Chr*_*her 16 amazon-s3 amazon-web-services cloud-init aws-cloudformation
我正在使用CloudFormation来管理Tomcat Web服务器堆栈,但我厌倦了为新的应用程序版本进行原始AMI管理.我想向厨师方向走,但现在没有时间.相反,我试图在网络服务器实例化中克服一个简单的问题:当新机器启动时,如何下载"当前"WAR?
我的想法是利用私有的S3存储桶和cloudinit,但我对IAM凭据的处理方式感到有点困惑.我可以将它们放在模板的用户数据中,但我不愿意这样做,特别是因为我是控制该文件的版本.我能想到的唯一选择是在AMI本身中使用环境变量.它们必须是纯文本,但是......呃,如果你可以打破我的实例,你可以压缩并下载我的整个网络服务器.只要IAM用户不被重复用于任何其他用户并且定期轮换,这似乎是解决问题的合理方法.我错过了什么吗?如何使用cloudinit安全地下载私有S3资产?
Eri*_*ond 16
亚马逊最近宣布了一项新功能,您可以在其中为您的EC2实例提供"IAM角色".这使得允许特定实例具有读取特定S3资源的权限变得相当容易.
这是他们的博客文章宣布新功能:
以下是EC2文档中的部分:
以下是IAM文档中的部分:
http://docs.amazonwebservices.com/IAM/latest/UserGuide/WorkingWithRoles.html
IAM角色通过HTTP使实例可以使用凭据,因此在实例上运行的任何用户或进程都可以看到它们.
Jam*_*yke 15
要稍微更新这个问题的答案:
与IAM角色一起,新的AWS命令行客户端使得获取这些资产变得微不足道.它将自动从环境中提取通过IAM提供的AWS凭据,并处理这些凭据的刷新.
以下是从用户数据脚本中的安全S3存储桶中获取单个资产的示例:
# Install the AWS command-line tools
pip install awscli
# Fetch the asset
aws s3 cp --region us-east-1 s3://my-private-bucket/a-folder/an-asset.zip /some/destination
Run Code Online (Sandbox Code Playgroud)
就那么简单.您还可以从S3复制整个目录内容并上传等.有关更多详细信息和选项,请参阅参考资料.
具有IAM角色的实例具有自动轮换的临时安全凭证.它们可以通过http at获得http://169.254.169.254/latest/meta-data/iam/security-credentials/RoleName,其中RoleName就是你所谓的角色.因此,它们很容易从您的实例中获取,但它们会定期到期.
使用它们有点困难.CloudFormation无法直接使用临时凭证.Amazon Linux AMI安装了Python boto,现在它足够聪明,可以自动为您查找和使用这些凭据.这里有一个单行程,你可以放入一个脚本来从S3桶b获取文件,键k到本地文件f:
python -c "import boto;boto.connect_s3().get_bucket('b').get_key('k').get_contents_to_filename('f')"
Run Code Online (Sandbox Code Playgroud)
boto为您查找并使用角色的临时凭证,这使其非常易于使用.
要将私有 S3 资产安全地下载到新的 EC2 实例上,您应该使用适用于 EC2 的 IAM 角色向您的 EC2 实例授予必要的 S3 权限,然后调用aws s3 cp您实例的UserData cloudinit 脚本来下载资产。
要从 CloudFormation 模板为 EC2 设置 IAM 角色,请使用AWS::IAM::InstanceProfile资源,引用AWS::IAM::Role具有AssumeRolePolicyDocument委派访问权限的资源ec2.amazonaws.com,以及旨在授予最低权限的策略(在这种情况下,'s3:GetObject'仅允许下载特定的 S3 资产)。
这是一个完整的示例模板,它使用 cloudinit 将 S3 资产下载到新的 EC2 实例,并将其内容作为Stack Output返回:
Description: (securely) download a private S3 asset onto a new EC2 instance with cloudinit
Parameters:
S3Bucket:
Description: S3 bucket name
Type: String
S3Key:
Description: S3 object key
Type: String
Mappings:
# amzn-ami-hvm-2016.09.1.20161221-x86_64-gp2
RegionMap:
us-east-1:
"64": "ami-9be6f38c"
Resources:
EC2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal: {Service: [ ec2.amazonaws.com ]}
Action: ["sts:AssumeRole"]
Path: /
Policies:
- PolicyName: EC2Policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ['s3:GetObject']
Resource: !Sub 'arn:aws:s3:::${S3Bucket}/${S3Key}'
RootInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles: [ !Ref EC2Role ]
WebServer:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [ RegionMap, !Ref "AWS::Region", 64 ]
InstanceType: m3.medium
IamInstanceProfile: !Ref RootInstanceProfile
UserData:
"Fn::Base64":
!Sub |
#!/bin/bash
DATA=$(aws s3 cp s3://${S3Bucket}/${S3Key} -)
/opt/aws/bin/cfn-signal \
-e $? \
-d "$DATA" \
'${Handle}'
Handle:
Type: AWS::CloudFormation::WaitConditionHandle
Wait:
Type: AWS::CloudFormation::WaitCondition
Properties:
Handle: !Ref Handle
Timeout: 300
Outputs:
Result:
Value: !GetAtt Wait.Data
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18351 次 |
| 最近记录: |