11

내 응용 프로그램의 최신 버전을 다운로드하기 위해 전용 S3 버킷에 액세스해야하는 스택을 구축 중입니다. EC2 인스턴스에 특정 역할을 할당 할 수있게 해주는 상대적으로 새로운 AWS 기능인 IAM roles을 사용하고 있으며이 기능을 IAM 정책과 결합합니다. 불행히도 이러한 역할에는 인스턴스 생성시 임시 API 자격 증명이 생성됩니다. 그것은 타격은 아니지만, (단지 관련 비트 간체)이 클라우드 init 스크립트와 같은 일을 나에게 강요 것 : 가장 중요한IAM 역할 임시 자격 증명을 구름 형성 템플릿에 사용할 수 있습니까?

#!/bin/sh 

# Grab our credentials from the meta-data and parse the response 
CREDENTIALS=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access) 
S3_ACCESS_KEY=$(echo $CREDENTIALS | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['AccessKeyId'];") 
S3_SECRET_KEY=$(echo $CREDENTIALS | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['SecretAccessKey'];") 
S3_TOKEN=$(echo $CREDENTIALS | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['Token'];") 

# Create an executable script to pull the file 
cat <<EOF> /tmp/pullS3.rb 
require 'rubygems' 
require 'aws-sdk' 
AWS.config(
    :access_key_id  => "$S3_ACCESS_KEY", 
    :secret_access_key => "$S3_SECRET_KEY", 
    :session_token  => "$S3_TOKEN") 
s3 = AWS::S3.new() 
myfile = s3.buckets['mybucket'].objects["path/to/my/file"] 
File.open("/path/to/save/myfile", "w") do |f| 
    f.write(myfile.read) 
end 
EOF 

# Downloading the file 
ruby /tmp/pullS3.rb 

처음이자 :이 작동하고 꽤 잘 작동합니다. 마찬가지로, CloudFormation의 기존 소스 액세스 지원을 사용하고 싶습니다. 특히 cfn-init은 S3 버킷을 포함하여 보호 된 데이터를 가져 오는 authentication resources의 사용을 지원합니다. 어쨌든 cfn-init에서이 키들을 가져 오거나 IAM 역할을 인증 리소스에 묶는가?

다른 대안으로 인증 된 서비스 뒤에 내 원본을 넣을 수있는 대안이 있다고 생각하지만, 현재로서는이 옵션을 사용할 수 없습니다.

또 다른 유망 리드는 AWS::IAM::AccessKey resource,이지만 문서에서는 역할과 함께 사용할 수 있다고 제안하지 않습니다. 어쨌든 그것을 시도 할 것입니다.

+0

[BOTO] (http://boto.readthedocs.org/en/과 테스트 최신 /), 인기있는 파이썬 AWS 라이브러리, 이것을 우아하게 처리합니다. 자세한 내용은 [이 대답] (http://stackoverflow.com/a/11130701/877115)을 참조하십시오. – Christopher

답변

11

지원이 추가 된 경우 확실하지 않지만 filessources 섹션의 AWS::CloudFormation::Init 섹션에 대한 S3 다운로드 인증에 IAM 역할을 사용할 수 있습니다.

그냥, (자세한 내용은 AWS::CloudFormation::Authentication 참조) 예를 들어 roleName 대신 & secretKeyaccessKeyId 사용

"Metadata": { 
    "AWS::CloudFormation::Init": { 
     "download": { 
      "files": { 
       "/tmp/test.txt": { 
        "source": "http://myBucket.s3.amazonaws.com/test.txt" 
       } 
      } 
     } 
    }, 
    "AWS::CloudFormation::Authentication": { 
     "default" : { 
      "type": "s3", 
      "buckets": [ "myBucket" ], 
      "roleName": { "Ref": "myRole" } 
     } 
    } 
} 

aws-cfn-bootstrap-1.3-11

+0

이것이 답 인 방법을 알지 못합니다. 또한 ec2 인스턴스 자체에 역할을 첨부해야합니다.이 역할을 통해 버킷에 영구 액세스 할 수 있습니다. –

1

나는이 작업을 할 수있었습니다. 내가 사용한 코드는 다음과 같습니다. https://forums.aws.amazon.com/message.jspa?messageID=319465

코드는 IAM 정책을 사용하지 않습니다. 대신 AWS :: S3 :: BucketPolicy를 사용합니다.

클라우드 형성 코드 : 당신의 가치와

"Resources" : {  

"CfnUser" : { 
    "Type" : "AWS::IAM::User", 
    "Properties" : { 
    "Path": "/", 
    "Policies": [{ 
     "PolicyName": "root", 
     "PolicyDocument": { "Statement":[{ 
     "Effect" : "Allow", 
     "Action" : [ 
      "cloudformation:DescribeStackResource", 
      "s3:GetObject" 
     ], 
     "Resource" :"*" 
     }]} 
    }] 
    } 
}, 

"CfnKeys" : { 
    "Type" : "AWS::IAM::AccessKey", 
    "Properties" : { 
    "UserName" : {"Ref": "CfnUser"} 
    } 
}, 

"BucketPolicy" : { 
    "Type" : "AWS::S3::BucketPolicy", 
    "Properties" : { 
    "PolicyDocument": { 
     "Version"  : "2008-10-17", 
     "Id"   : "CfAccessPolicy", 
     "Statement" : [{ 
     "Sid"  : "ReadAccess", 
     "Action"  : ["s3:GetObject"], 
     "Effect"  : "Allow", 
     "Resource" : { "Fn::Join" : ["", ["arn:aws:s3:::<MY_BUCKET>/*"]]}, 
     "Principal" : { "AWS": {"Fn::GetAtt" : ["CfnUser", "Arn"]} } 
     }] 
    }, 
    "Bucket" : "<MY_BUCKET>" 
    } 
}, 

"WebServer": { 
    "Type": "AWS::EC2::Instance", 
    "DependsOn" : "BucketPolicy", 
    "Metadata" : { 

    "AWS::CloudFormation::Init" : { 
     "config" : { 

     "sources" : { 
      "/etc/<MY_PATH>" : "https://s3.amazonaws.com/<MY_BUCKET>/<MY_FILE>" 
     } 

     } 
    }, 

    "AWS::CloudFormation::Authentication" : { 
     "S3AccessCreds" : { 
     "type" : "S3", 
     "accessKeyId" : { "Ref" : "CfnKeys" }, 
     "secretKey" : {"Fn::GetAtt": ["CfnKeys", "SecretAccessKey"]}, 
     "buckets" : [ "<MY_BUCKET>" ] 
     } 
    } 
    }, 

    "Properties": { 
    "ImageId" : "<MY_INSTANCE_ID>", 
    "InstanceType" : { "Ref" : "WebServerInstanceType" }, 
    "KeyName" : {"Ref": "KeyName"}, 
    "SecurityGroups" : [ "<MY_SECURITY_GROUP>" ], 

    "UserData"  : { "Fn::Base64" : { "Fn::Join" : ["", [ 
     "#!/bin/bash\n", 

     "# Helper function\n", 
     "function error_exit\n", 
     "{\n", 
     " cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WaitHandle" }, "'\n", 
     " exit 1\n", 
     "}\n", 

     "# Install Webserver Packages etc \n", 
     "cfn-init -v --region ", { "Ref" : "AWS::Region" }, 
     " -s ", { "Ref" : "AWS::StackName" }, " -r WebServer ", 
     "   --access-key ", { "Ref" : "CfnKeys" }, 
     "   --secret-key ", {"Fn::GetAtt": ["CfnKeys", "SecretAccessKey"]}, " || error_exit 'Failed to run cfn-init'\n", 

     "# All is well so signal success\n", 
     "cfn-signal -e 0 -r \"Setup complete\" '", { "Ref" : "WaitHandle" }, "'\n" 

    ]]}}   
    } 
} 

물론 교체 MY_BUCKET, MY_FILE, MY_INSTANCE_ID, MY_SECURITY_GROUP.