Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon s3 如何(安全地)使用cloudinit将私有S3资产下载到新的EC2实例上?_Amazon S3_Amazon Web Services_Amazon Cloudformation_Cloud Init - Fatal编程技术网

Amazon s3 如何(安全地)使用cloudinit将私有S3资产下载到新的EC2实例上?

Amazon s3 如何(安全地)使用cloudinit将私有S3资产下载到新的EC2实例上?,amazon-s3,amazon-web-services,amazon-cloudformation,cloud-init,Amazon S3,Amazon Web Services,Amazon Cloudformation,Cloud Init,我正在使用CloudFormation来管理Tomcat Web服务器堆栈,但我厌倦了为新的应用程序版本进行原始AMI管理。我想换成厨师,但现在没有时间。相反,我试图解决Web服务器实例化中的一个简单问题:当新机器启动时,如何下载“当前”战争 我的想法是利用一个私有的S3 bucket和cloudinit,但我有点被IAM凭据的处理方式难倒了。我可以将它们放在模板的用户数据中,但我不愿意这样做,特别是因为我正在控制该文件的版本。我能想到的唯一选择是在AMI本身中使用环境变量。它们必须是明文,但是

我正在使用CloudFormation来管理Tomcat Web服务器堆栈,但我厌倦了为新的应用程序版本进行原始AMI管理。我想换成厨师,但现在没有时间。相反,我试图解决Web服务器实例化中的一个简单问题:当新机器启动时,如何下载“当前”战争


我的想法是利用一个私有的S3 bucket和cloudinit,但我有点被IAM凭据的处理方式难倒了。我可以将它们放在模板的用户数据中,但我不愿意这样做,特别是因为我正在控制该文件的版本。我能想到的唯一选择是在AMI本身中使用环境变量。它们必须是明文,但是。。。呃,如果你能闯入我的实例,你可以压缩并下载我的整个Web服务器。只要IAM用户不被重复使用,并且定期轮换,这似乎是解决问题的合理方法。我遗漏了什么吗?如何使用cloudinit安全地下载私有S3资产?

亚马逊最近宣布了一项新功能,您可以在其中为EC2实例提供“IAM角色”。这使得允许特定实例具有读取特定S3资源的权限变得相当容易

以下是他们的博客文章,宣布了新功能:

以下是EC2文档中的部分:

以下是IAM文档中的部分:


IAM角色通过HTTP将凭据提供给实例,因此实例上运行的任何用户或进程都可以看到它们。

具有IAM角色的实例具有自动循环的临时安全凭据。可通过http
http://169.254.169.254/latest/meta-data/iam/security-credentials/RoleName
,其中RoleName是您所称的角色。因此,它们很容易从您的实例中获取,但它们会定期过期

使用它们有点困难。CloudFormation无法直接使用临时凭据。AmazonLinuxAMI安装了PythonBoto,现在它足够智能,可以自动为您查找和使用这些凭据。这里有一行代码,您可以将它放入脚本中,从S3 bucketb中提取文件,将k键插入本地文件f

python -c "import boto;boto.connect_s3().get_bucket('b').get_key('k').get_contents_to_filename('f')"

boto为您查找并使用角色的临时凭据,这使其非常易于使用。

要稍微更新此问题的答案,请执行以下操作:

与IAM角色一起,新角色使得获取这些资产变得微不足道。它将自动从环境中提取通过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

就这么简单。您还可以从S3复制并上载整个目录内容等。有关更多详细信息和选项,请参阅。

要将专用S3资源安全下载到新的EC2实例上,您应该使用授予EC2实例必要的S3权限,然后调用实例的来下载该资源

要从CloudFormation模板为EC2设置IAM角色,请使用该资源,引用具有
AssumePolicyDocument
的资源,授权访问
EC2.amazonaws.com
,策略设计为(在本例中,仅允许下载特定s3资产的
's3:GetObject'

下面是一个完整的示例模板,它使用cloudinit将S3资产下载到一个新的EC2实例上,并以以下格式返回其内容:


什么是“k键”?它是一个具有临时凭据的文件吗?对于未来的用户,密钥k是您希望从S3获得的文件名。如果您有文件夹结构,那么密钥将是foldername/file.sh耶新的cli工具基于
botocore
,这似乎是
boto
v3的基础。如果您了解AWSAPI的结构,那么总体来说,这是一个很棒的界面。非常好、简洁的回答@jamesvanDyke。但我仍然怀疑这是否安全,如我在这里的类似问题所示:是否有任何完整的从头到尾的AWS CLI示例或教程显示如何设置和使用IAM机制?这些参考资料看起来非常复杂,如能提供一个完整的示例,请逐一说明。
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