Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can IAM role temporary credentials be used in cloudformation templates?

I'm building a stack that needs access to a private S3 bucket to download the most current version of my application. I'm using IAM roles, a relatively new AWS feature that allows EC2 instances to be assigned specific roles, which are then coupled with IAM policies. Unfortunately, these roles come with temporary API credentials generated at instantiation. It's not crippling, but it's forced me to do things like this cloud-init script (simplified to just the relevant bit):

#!/bin/sh

# Grab our credentials from the meta-data and parse the response
CREDENTIALS=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access)
S3_ACCESS_KEY=$(echo $CREDENTIALS | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['AccessKeyId'];")
S3_SECRET_KEY=$(echo $CREDENTIALS | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['SecretAccessKey'];")
S3_TOKEN=$(echo $CREDENTIALS | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['Token'];")

# Create an executable script to pull the file
cat << EOF > /tmp/pullS3.rb
require 'rubygems'
require 'aws-sdk'
AWS.config(
    :access_key_id     => "$S3_ACCESS_KEY",
    :secret_access_key => "$S3_SECRET_KEY",
    :session_token     => "$S3_TOKEN")
s3 = AWS::S3.new()
myfile = s3.buckets['mybucket'].objects["path/to/my/file"]
File.open("/path/to/save/myfile", "w") do |f|
    f.write(myfile.read)
end
EOF

# Downloading the file
ruby /tmp/pullS3.rb

First and foremost: This works, and works pretty well. All the same, I'd love to use CloudFormation's existing support for source access. Specifically, cfn-init supports the use of authentication resources to get at protected data, including S3 buckets. Is there anyway to get at these keys from within cfn-init, or perhaps tie the IAM role to an authentication resource?

I suppose one alternative would be putting my source behind some other authenticated service, but that's not a viable option at this time.

Another promising lead is the AWS::IAM::AccessKey resource, but the docs don't suggest it can be used with roles. I'm going to try it anyway.

like image 432
Christopher Avatar asked Jul 19 '12 18:07

Christopher


1 Answers

I'm not sure when support was added, but you can meanwhile use an IAM role for authenticating S3 downloads for files and sources sections in AWS::CloudFormation::Init.

Just use roleName instead of accessKeyId & secretKey (see AWS::CloudFormation::Authentication for details), e.g.:

"Metadata": {
    "AWS::CloudFormation::Init": {
        "download": {
            "files": {
                "/tmp/test.txt": {
                    "source": "http://myBucket.s3.amazonaws.com/test.txt"
                }
             }
        }
    },
    "AWS::CloudFormation::Authentication": {
        "default" : {
            "type": "s3",
            "buckets": [ "myBucket" ],
            "roleName": { "Ref": "myRole" }
        }
    }
}

Tested with aws-cfn-bootstrap-1.3-11

like image 102
Paul Egan Avatar answered Nov 15 '22 14:11

Paul Egan