11

我正在構建一個需要訪問私有S3存儲桶的堆棧以下載我的應用程序的最新版本。我使用的是IAM roles,這是一種相對較新的AWS功能,允許爲EC2實例分配特定角色,然後再與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支持使用authentication resources來獲取受保護的數據,包括S3存儲桶。無論如何,從cfn-init內部獲取這些密鑰,或者將IAM角色綁定到身份驗證資源?

我想一個替代方案是將我的源頭放在其他一些經過驗證的服務之後,但目前這不是一個可行的選擇。

另一個有希望的領導是AWS::IAM::AccessKey resource,,但文檔不建議它可以與角色一起使用。無論如何,我會嘗試。

+0

[伯特](http://boto.readthedocs.org/en/最新/),一個流行的Python AWS庫,可以很好地處理這個問題。有關更多詳細信息,請參閱[此答案](http://stackoverflow.com/a/11130701/877115)。 – Christopher 2013-02-12 15:08:35

回答

11

我不知道加入支持的時候,但你可以同時使用在AWS::CloudFormation::Init認證S3的下載filessources段的IAM角色。

只需使用roleName代替accessKeyId & secretKey(見AWS::CloudFormation::Authentication瞭解詳細信息),如:

"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實例本身,從而授予它對存儲區的永久訪問權限。 – 2014-09-18 02:22:19

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與你的價值觀。

相關問題