我正在使用CloudFormation模板来启动一个自定义的Windows AMI,它需要从S3存储桶中检索一些代码,并在启动后执行它。
在使用AWS CLI( s3 sync )快速手动完成之后,我一直努力通过CloudFormation将其工作8个小时以上,但都无济于事。 实质上,这个命令总是失败:
“NoCredentialsError:找不到凭据”
最初我尝试以许多不同的方式设置/.aws/credentials和/.aws/config文件,直到我终于意识到运行cfn-init.exe的用户身份及其subprocess无法访问这些文件所有这一切都行不通。 所以相反,我select使用setx设置环境variables,但这似乎并不工作,我仍然得到相同的错误。
我对此感到非常沮丧,因为每个testing都需要对CF模板进行更改,上传到S3,创build一个堆栈,等待5-10分钟,完成只引导到RDP, 然后再次find失败。
这是我的模板的init > config部分:
"commands" : { "0-Tester" : { "command" : "echo \"I am OK.\" > \"d:\\test.txt\"" }, "1-SetAK" : { "command" : { "Fn::Join" : ["", [ "setx AWS_ACCESS_KEY_ID ", { "Ref": "AutomationUserAK" } ]] } }, "2-SetSK" : { "command" : { "Fn::Join" : ["", [ "setx AWS_SECRET_ACCESS_KEY ", { "Ref": "AutomationUserSK" } ]] } }, "3-Pullcode" : { "command" : "aws s3 sync s3://some-s3-bucket d:/dev/ --debug" } }
前3个命令(testing仪,SetAK,SetSK)工作得很好。 最后一个(Pullcode)每次都失败。
所以在这一点上,我假设我错了。 也许我需要为CF堆栈configuration一个特定的IAM,也许我应该使用setx ... /M ,也许有一百万个其他选项,但是由于这个试验和错误一直在我工作的整个一天,然后一些我想这不会伤害要问。
您的每个命令都在单独的PowerShell中运行,因此setx AWS_ACCESS_KEY_ID将variables设置在一个 shell实例中并退出。 然后, setx AWS_SECRET_ACCESS_KEY在另一个shell中设置另一个variables并退出。 然后,在另一个 shell中运行aws s3 sync ,其中以前的variables都不存在,并且因为凭证variables不存在于该 shell中而失败。
而不是从元数据中调用它,你可以这样做:
"UserData": { "Fn::Base64": { "Fn::Join": ["", [ "<script>\n", "cfn-init.exe -v -s [...]\n", "setx AWS_ACCESS_KEY_ID ", { "Ref": "AutomationUserAK" }, "\n", "setx AWS_SECRET_ACCESS_KEY ", { "Ref": "AutomationUserSK" }, "\n", "aws s3 sync s3://some-s3-bucket d:/dev/\n", "</script>" ] ] } }
在这种情况下,它将全部运行在同一个shell实例中,并且当您调用aws s3 sync时,这些键仍然会被设置。
不过,我不得不说,将访问和密钥传递给CloudFormation模板是一个糟糕的做法。 相反,CloudFormation模板应使用适当的权限创buildIAMangular色来访问S3存储桶并将其分配给EC2实例。 实例上的aws工具可以透明地访问S3,而不需要提供访问和密钥。 像这样的事情应该为你的CloudFormation模板做:
首先使用S3访问策略创buildIAMangular色 (根据需要调整策略):
"InstanceRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/", "Policies": [ { "PolicyName": "S3_Access", "PolicyDocument": { "Statement": [ { "Effect": "Allow", "Action": [ "s3:List*", "s3:Get*" ], "Resource": "*" } ] } } ] } },
然后创build一个引用上述IAMangular色的IAM实例configuration文件 …
"InstanceProfile": { "Type": "AWS::IAM::InstanceProfile", "Properties": { "Path": "/", "Roles": [ { "Ref": "InstanceRole" } ] } },
最后,创build获取该IAMconfiguration文件的EC2实例(并依次使用S3访问策略的IAMangular色 )。
"Instance": { "Type": "AWS::EC2::Instance", "Properties": { "IamInstanceProfile": { "Ref": "InstanceProfile" }, [...], "UserData": { "Fn::Base64": { "Fn::Join": ["", [ "<script>\n", "cfn-init.exe -v -s ", { "Ref" : "AWS::StackId" }, " -r Instance --region ", { "Ref" : "AWS::Region" }, "\n", "</script>" ] ] } } }, "Metadata": { "AWS::CloudFormation::Init": { "config": { "commands" : { "Pullcode" : { "command" : "aws s3 sync s3://some-s3-bucket d:/dev/ --debug" } } } } } },
使用IAMangular色时 , AWS凭据是dynamic生成的,并且通过aws命令可以透明地获取。 这更安全,并且是让EC2实例访问AWS资源的更好方法。
了解有关EC2实例angular色的更多信息,例如: https : //aws.nz/best-practice/ec2-instance-roles/
希望帮助:)