11

アプリケーションの最新バージョンをダウンロードするためにプライベート S3 バケットにアクセスする必要があるスタックを構築しています。私はIAM ロールを使用しています。これは、EC2 インスタンスに特定のロールを割り当てることができる比較的新しい AWS 機能であり、その後、IAM ポリシーと結合されます。残念ながら、これらのロールには、インスタンス化時に生成された一時的な API 資格情報が付属しています。それは不自由ではありませんが、この cloud-init スクリプトのようなことをすることを余儀なくされました (関連するビットだけに簡略化されています):

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

何よりもまず、これは機能し、かなりうまく機能します。それでも、CloudFormation のソース アクセスに対する既存のサポートを使用したいと思います。具体的には、 S3 バケットなどの保護されたデータを取得するための認証リソースcfn-initの使用をサポートします。内からこれらのキーを取得したり、IAM ロールを認証リソースに関連付けたりする方法はありますか?cfn-init

別の方法として、ソースを他の認証済みサービスの背後に配置することも考えられますが、現時点では実行可能なオプションではありません。

別の有望なリードはAWS::IAM::AccessKey リソースですが、ドキュメントではロールで使用できることは示唆されていません。とにかくやってみます。

4

2 に答える 2

11

サポートがいつ追加されたのかはわかりませんが、その間は IAM ロールを使用してAWS::CloudFormation::InitfilesのおよびsourcesセクションのS3 ダウンロードを認証できます。

&roleNameの代わりに使用してください (詳細については、 AWS::CloudFormation::Authenticationを参照してください)。例:accessKeyIdsecretKey

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

でテスト済みaws-cfn-bootstrap-1.3-11

于 2013-03-26T11:59:56.647 に答える
1

私はこれを機能させることができました。私が使用したのは、この交換からのコードでした: https://forums.aws.amazon.com/message.jspa?messageID=319465

コードは IAM ポリシーを使用しません。代わりに AWS::S3::BucketPolicy を使用します。

雲形成のコード スニペット:

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

    ]]}}        
  }
}

明らかに、MY_BUCKET、MY_FILE、MY_INSTANCE_ID、MY_SECURITY_GROUP を値に置き換えます。

于 2013-01-13T11:11:40.640 に答える