要安全地将私有 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 实例上,并将其内容作为堆栈输出返回:
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