11

Buduję stos, który potrzebuje dostępu do prywatnego zasobnika S3, aby pobrać najnowszą wersję mojej aplikacji. Używam IAM roles, względnie nowej funkcji AWS, która pozwala na przypisanie określonych instancji EC2 do określonych ról, które następnie są powiązane z zasadami IAM. Niestety te role mają tymczasowe referencje API wygenerowane podczas tworzenia instancji. To nie paraliżuje, ale to zmusiło mnie do robienia rzeczy, jak ten skrypt cloud-init (uproszczonej do zaledwie odpowiedniej bit):Czy tymczasowe dane logowania do roli IAM mogą być używane w szablonach Cloudformation?

#!/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 

Przede wszystkim: To działa, i działa całkiem dobrze. Mimo to, chciałbym skorzystać z istniejącej obsługi CloudFormation dla dostępu do źródła. W szczególności, cfn-init obsługuje użycie authentication resources, aby uzyskać chronione dane, w tym wiadra S3. Czy mimo to można uzyskać te klucze z poziomu cfn-init, a może powiązać rolę IAM z zasobem uwierzytelniania?

Przypuszczam, że jedną alternatywą byłoby umieszczenie mojego źródła za inną uwierzytelnioną usługą, ale obecnie nie jest to realną opcją.

Kolejną obiecującą przewagą jest AWS::IAM::AccessKey resource,, ale dokumenty nie sugerują, że można z niej korzystać. I tak spróbuję.

+0

[Boto] (http://boto.readthedocs.org/en/ latest /), popularna biblioteka zapytań AWS, radzi sobie z tym elegancko. Aby uzyskać więcej informacji, zobacz [tę odpowiedź] (http://stackoverflow.com/a/11130701/877115). – Christopher

Odpowiedz

11

Nie jestem pewien, kiedy dodano wsparcie, ale w międzyczasie można użyć IAM rolę uwierzytelniania S3 pobieranie za files i sources sekcjach w AWS::CloudFormation::Init.

Wystarczy użyć roleName zamiast accessKeyId & secretKey (patrz AWS::CloudFormation::Authentication szczegółów), np

"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" } 
     } 
    } 
} 

Testowane aws-cfn-bootstrap-1.3-11

+0

Nie widzę, jak to jest odpowiedź. Musisz dodatkowo dołączyć tę rolę do samej instancji EC2, która zapewnia jej stały dostęp do zasobnika. –

1

Udało mi się to zadziałać. Użyłem kodu z tej wymiany: https://forums.aws.amazon.com/message.jspa?messageID=319465

Kod nie korzysta z zasad IAM - zamiast tego używa AWS :: S3 :: BucketPolicy.

Chmura formacja fragment kodu:

"Resources" : {  

"CfnUser" : { 
    "Type" : "AWS::IAM::User", 
    "Properties" : { 
    "Path": "/", 
    "Policies": [{ 
     "PolicyName": "root", 
     "PolicyDocument": { "Statement":[{ 
     "Effect" : "Allow", 
     "Action" : [ 
      "cloudformation:DescribeStackResource", 
      "s3:GetObject" 
     ], 
     "Resource" :"*" 
     }]} 
    }] 
    } 
}, 

"CfnKeys" : { 
    "Type" : "AWS::IAM::AccessKey", 
    "Properties" : { 
    "UserName" : {"Ref": "CfnUser"} 
    } 
}, 

"BucketPolicy" : { 
    "Type" : "AWS::S3::BucketPolicy", 
    "Properties" : { 
    "PolicyDocument": { 
     "Version"  : "2008-10-17", 
     "Id"   : "CfAccessPolicy", 
     "Statement" : [{ 
     "Sid"  : "ReadAccess", 
     "Action"  : ["s3:GetObject"], 
     "Effect"  : "Allow", 
     "Resource" : { "Fn::Join" : ["", ["arn:aws:s3:::<MY_BUCKET>/*"]]}, 
     "Principal" : { "AWS": {"Fn::GetAtt" : ["CfnUser", "Arn"]} } 
     }] 
    }, 
    "Bucket" : "<MY_BUCKET>" 
    } 
}, 

"WebServer": { 
    "Type": "AWS::EC2::Instance", 
    "DependsOn" : "BucketPolicy", 
    "Metadata" : { 

    "AWS::CloudFormation::Init" : { 
     "config" : { 

     "sources" : { 
      "/etc/<MY_PATH>" : "https://s3.amazonaws.com/<MY_BUCKET>/<MY_FILE>" 
     } 

     } 
    }, 

    "AWS::CloudFormation::Authentication" : { 
     "S3AccessCreds" : { 
     "type" : "S3", 
     "accessKeyId" : { "Ref" : "CfnKeys" }, 
     "secretKey" : {"Fn::GetAtt": ["CfnKeys", "SecretAccessKey"]}, 
     "buckets" : [ "<MY_BUCKET>" ] 
     } 
    } 
    }, 

    "Properties": { 
    "ImageId" : "<MY_INSTANCE_ID>", 
    "InstanceType" : { "Ref" : "WebServerInstanceType" }, 
    "KeyName" : {"Ref": "KeyName"}, 
    "SecurityGroups" : [ "<MY_SECURITY_GROUP>" ], 

    "UserData"  : { "Fn::Base64" : { "Fn::Join" : ["", [ 
     "#!/bin/bash\n", 

     "# Helper function\n", 
     "function error_exit\n", 
     "{\n", 
     " cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WaitHandle" }, "'\n", 
     " exit 1\n", 
     "}\n", 

     "# Install Webserver Packages etc \n", 
     "cfn-init -v --region ", { "Ref" : "AWS::Region" }, 
     " -s ", { "Ref" : "AWS::StackName" }, " -r WebServer ", 
     "   --access-key ", { "Ref" : "CfnKeys" }, 
     "   --secret-key ", {"Fn::GetAtt": ["CfnKeys", "SecretAccessKey"]}, " || error_exit 'Failed to run cfn-init'\n", 

     "# All is well so signal success\n", 
     "cfn-signal -e 0 -r \"Setup complete\" '", { "Ref" : "WaitHandle" }, "'\n" 

    ]]}}   
    } 
} 

Oczywiście zastępując MY_BUCKET, my_file, MY_INSTANCE_ID, MY_SECURITY_GROUP ze swoimi wartościami.

Powiązane problemy