IAM 角色临时凭证可以在 cloudformation 模板中使用吗?
Posted
技术标签:
【中文标题】IAM 角色临时凭证可以在 cloudformation 模板中使用吗?【英文标题】:Can IAM role temporary credentials be used in cloudformation templates? 【发布时间】:2012-07-19 00:42:36 【问题描述】:我正在构建一个堆栈,它需要访问私有 S3 存储桶才能下载我的应用程序的最新版本。我正在使用IAM roles,这是一个相对较新的 AWS 功能,它允许为 EC2 实例分配特定角色,然后与 IAM 策略相结合。不幸的是,这些角色带有在实例化时生成的临时 API 凭证。这并不严重,但它迫使我做这个 cloud-init 脚本之类的事情(简化为相关部分):
#!/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,,但文档不建议它可以与角色一起使用。反正我要试试。
【问题讨论】:
boto,一个流行的 python AWS 库,可以优雅地处理这个问题。有关详细信息,请参阅this answer。 【参考方案1】:我设法让这个工作。我使用的是这个交易所的代码: https://forums.aws.amazon.com/message.jspa?messageID=319465
代码不使用 IAM 策略 - 它使用 AWS::S3::BucketPolicy。
成云代码sn-p:
"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 替换为您的值。
【讨论】:
【参考方案2】:我不确定何时添加了支持,但您可以同时使用 IAM 角色来验证 AWS::CloudFormation::Init 中 files
和 sources
部分的 S3 下载。
只需使用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
测试
【讨论】:
我看不出这是怎么回答的。此外,您还需要将该角色附加到 ec2 实例本身,从而授予其对存储桶的永久访问权限。以上是关于IAM 角色临时凭证可以在 cloudformation 模板中使用吗?的主要内容,如果未能解决你的问题,请参考以下文章
Aws::Errors::MissingCredentialsError(无法在没有设置凭证的情况下签署请求)- Beanstalk,通过 IAM 角色实现安全