How can I (securely) download a private S3 asset onto a new EC2 instance with cloudinit?

前端 未结 4 871
清歌不尽
清歌不尽 2020-12-08 11:26

I\'m using CloudFormation to manage a Tomcat webserver stack but am tired of doing raw AMI management for new application versions. I\'d like to move in the direction of Che

相关标签:
4条回答
  • 2020-12-08 11:54

    Amazon recently announced a new feature where you can give "IAM roles" to your EC2 instances. This makes it fairly easy to allow specific instances to have permission to read specific S3 resources.

    Here's their blog post announcing the new feature:

    http://aws.typepad.com/aws/2012/06/iam-roles-for-ec2-instances-simplified-secure-access-to-aws-service-apis-from-ec2.html

    Here's the section in the EC2 documentation:

    http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/UsingIAM.html#UsingIAMrolesWithAmazonEC2Instances

    Here's the section in the IAM documentation:

    http://docs.amazonwebservices.com/IAM/latest/UserGuide/WorkingWithRoles.html

    IAM roles make the credentials available to the instance through HTTP, so any users or processes running on the instance can see them.

    0 讨论(0)
  • 2020-12-08 12:05

    To update the answers to this question a bit:

    Along with IAM roles, the new AWS command-line client makes fetching these assets trivial. It will automatically pull AWS credentials bestowed via IAM from the environment and handle the refreshing of those credentials.

    Here's an example of fetching a single asset from a secure S3 bucket in a user-data script:

    # 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
    

    Simple as that. You can also copy entire directory contents from S3 and uploaded, etc. See the reference material for more details and options.

    0 讨论(0)
  • 2020-12-08 12:12

    An instance with an IAM Role has temporary security credentials that are automatically rotated. They're available via http at http://169.254.169.254/latest/meta-data/iam/security-credentials/RoleName, where RoleName is whatever you called your role. So they're easy to get from your instance, but they expire regularly.

    Using them is a bit tough. CloudFormation can't use temporary credentials directly. The Amazon Linux AMI has Python boto installed, and it's now smart enough to find and use those credentials for you automatically. Here's a one-liner you can put in a script to fetch a file from S3 bucket b, key k to local file f:

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

    boto finds and uses the role's temporary credentials for you, which makes it really easy to use.

    0 讨论(0)
  • 2020-12-08 12:12

    To securely download a private S3 asset onto a new EC2 instance, you should use IAM Roles for EC2 to grant the necessary S3 permission to your EC2 instance, then call aws s3 cp in your instance's UserData cloudinit script to download the asset.

    To setup an IAM Role for EC2 from a CloudFormation template, use the AWS::IAM::InstanceProfile resource, referencing an AWS::IAM::Role resource with an AssumeRolePolicyDocument delegating access to ec2.amazonaws.com, with a Policy designed to grant least privilege (in this case, allowing 's3:GetObject' only for the specific S3 asset being downloaded).

    Here's a full example template that downloads an S3 asset onto a new EC2 instance using cloudinit, returning its contents as a 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
    
    0 讨论(0)
提交回复
热议问题