#author("2019-03-15T13:14:49+00:00","","") [[AWSメモ]] > * AWS CloudFormationメモ [#q8714c67] #setlinebreak(on); #contents -- 関連 --- [[AWS API Gateway&LambdaをFlaskに移行しやすいように作る]] --- [[AWS IotにPublishされたデータをDynamoDBに登録する]] --- [[PythonでAWS DynamoDBのCRUDを書いてみる]] --- [[AWS Lambdaで環境変数を使用する]] --- [[AWSのサービスをJenkinsでデプロイする#template.yml>AWSのサービスをJenkinsでデプロイする#w4800203]] -- 参考 --- https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html ** 概要 [#dd0e7442] #html(<div style="padding-left: 10px;">) AWS CloudFormation を利用するとインフラ全体をテキストファイルでモデル(ソース)化できる。 AWS上に作成する必要があるリソースを全てCloudFormationテンプレートとして定義しておく事で、環境の複製やデプロイの自動化などが安全容易に行える為、非常に有用。 #html(</div>) ** テンプレート形式 [#a83d7460] #html(<div style="padding-left: 10px;">) https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-formats.html CloudFormation テンプレートは JSON または YAML で以下の形式で記述する。 #mycode2(){{ AWSTemplateFormatVersion: "2010-09-09" Description: Sample template Resources: SampleResource1: # リソースの論理名 Type: AWS::Xxxx::Xxxx # リソースタイプ Properties: # リソースのプロパティ . . SampleResource2: # リソースの論理名 Type: AWS::Xxxx::Xxxx # リソースタイプ Properties: # リソースのプロパティ . . }} 各項目の内容は以下の通り。 | 項目名 | 説明 | 参考URL |h | AWSTemplateFormatVersion | 形式バージョン | https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/format-version-structure.html | | Description | 説明 | https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-description-structure.html | #html(</div>) ** 組み込み関数の利用 [#d4cfd34e] #html(<div style="padding-left: 10px;">) スタックの管理に役立ついくつかの組み込み関数が用意されている。 ここでは使用頻度の高い GetAtt と Ref について記載する。 ※GetAtt、Ref ともに ARN や ID を参照する際に多用する。 参考 https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html *** GetAtt [#q6e79d07] #html(<div style="padding-left: 10px;">) GetAtt はテンプレートのリソースから属性の値を返す事ができる。 https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html YAMLの場合 #mycode2(){{ Fn::GetAtt: [ logicalNameOfResource, attributeName ] # 完全名関数 !GetAtt logicalNameOfResource.attributeName # 短縮形 }} #html(</div>) *** Ref [#l9fec0fa] #html(<div style="padding-left: 10px;">) Ref は指定したパラメータまたはリソースの値を返す事ができる。 https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html YAMLの場合 #mycode2(){{ Ref: logicalName # 完全名関数 !Ref logicalName # 短縮形 }} 尚、返される内容はリソースの種類によって異なるので注意が必要。( ARN、ID、名前 の何れかが返されるものが殆どだが ) ※参考: [[Ref: リソースの戻り値の例>https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html#ref-resource-return-examples]] #html(</div>) #html(</div>) ** マクロの利用 [#u18013e5] #html(<div style="padding-left: 10px;">) *** AWS::Serverless 変換 [#y2dbc281] #html(<div style="padding-left: 10px;">) #TODO https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/transform-aws-serverless.html https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template.html#serverless-sam-template-api #html(</div>) *** 定型コンテンツの挿入 [#ac8ec692] #html(<div style="padding-left: 10px;">) #TODO https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/create-reusable-transform-function-snippets-and-add-to-your-template-with-aws-include-transform.html #html(</div>) #html(</div>) ** パラメータを使用する [#y20d2825] #html(<div style="padding-left: 10px;">) Parameters セクションを利用すると、スタックを作成または更新する際にテンプレートにカスタム値を入力できる。 https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html *** テンプレートの記述例 [#m2f826f0] #html(<div style="padding-left: 10px;">) 以下に Lambda関数名の接頭文字をパラメータ化する例を記載する。 #mycode2(){{ AWSTemplateFormatVersion : '2010-09-09' Transform: "AWS::Serverless-2016-10-31" Description: "Sample Lambda Environments." Parameters: FuncNamePrefix: Type: String Default: "My" Resources: SampleLambdaEnv: Type: "AWS::Serverless::Function" Properties: FunctionName: !Sub '${FuncNamePrefix}-SampleLambda' . . }} #html(</div>) *** パラメータの設定方法 [#o8903d12] #html(<div style="padding-left: 10px;">) create-stack でパラメータをセット場合は --parameters オプションを指定する https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html #myterm2(){{ aws cloudformation create-stack --stack-name SampleStack --template-body file://template.yml --parameters FuncNamePrefix="Test" --capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND }} deploy でパラメータをセットする場合は --parameter-overrides オプションを使用する https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/index.html #myterm2(){{ aws cloudformation deploy --stack-name SampleStack --template-file packaged-template.yml --parameter-overrides FuncNamePrefix="Test" --capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND }} #html(</div>) *** 関連 [#ib381835] #html(<div style="padding-left: 10px;">) - [[AWS Lambdaで環境変数を使用する]] #html(</div>) #html(</div>) ** 条件を指定する [#f111df71] #html(<div style="padding-left: 10px;">) #TODO https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html #html(</div>) ** 他スタックの定義を再利用する [#kd44b137] #html(<div style="padding-left: 10px;">) *** 定義のエクスポート [#qc8613f9] #html(<div style="padding-left: 10px;">) スタックの出力値をエクスポートして、他のテンプレートで使用する事ができる。 https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html テーブル名 及び テーブルのARN をエクスポートする例) #mycode2(){{ . . Resources: SampleTable01: Type: AWS::DynamoDB::Table Properties: TableName: SampleTable01 Outputs: SampleTable01Name: Value: !Ref SampleTable01 Export: Name: MyTable01Name SampleTable01Arn: Value: !GetAtt SampleTable01.Arn Export: Name: MyTable01Arn }} また、エクスポートされている値の一覧は aws cloudformation list-exports で確認する事ができる。 #myterm2(){{ aws cloudformation list-exports { "Exports": [ { "ExportingStackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/SampleCreateTables/dbd...5d08", "Value": "arn:aws:dynamodb:ap-northeast-1:XXXXXXXXXXXX:table/SampleTable01", "Name": "MyTable01Arn" }, { "ExportingStackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/SampleCreateTables/dbd...5d08", "Value": "SampleTable01", "Name": "MyTable01Name" } ] } }} 整形して出力 #myterm2(){{ aws cloudformation list-exports | awk 'BEGIN {value=""}{ if ($1 == "\"Value\":") value=$2; if ($1 == "\"Name\":") print $2"\t"value}' | sed 's/[",]//g' MyTable01Arn arn:aws:dynamodb:ap-northeast-1:XXXXXXXXXXXX:table/SampleTable01 MyTable01Name SampleTable01 }} #html(</div>) *** エクスポート済みの値の参照 [#gf2375f6] #html(<div style="padding-left: 10px;">) エクスポートした値は Fn::ImportValue を使用して別のテンプレートから参照する事ができる。 https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html #mycode2(){{ SampleIotDataTablePutItemRole: Type: AWS::IAM::Role Properties: . . Policies: - PolicyName: "SampleIotDataTablePutItemPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "dynamoDB:PutItem" Resource: !ImportValue MyTable01Arn }} #html(</div>) 参考 - チュートリアル: 別の AWS CloudFormation スタックのリソース出力を参照する&br;https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/walkthrough-crossstackref.html #html(</div>) ** サンプル [#vad9a975] #html(<div style="padding-left: 10px;">) 参考: [[AWS リソースおよびプロパティタイプのリファレンス>https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html]] *** Lambda単体 [#gd05e635] #html(<div style="padding-left: 10px;">) #TODO https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-reference-lambda.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html #html(</div>) *** Lambda単体 (AWS::Serverless 変換を利用する場合) [#x629e4d5] #html(<div style="padding-left: 10px;">) #TODO https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/transform-aws-serverless.html https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template.html#serverless-sam-template-api #html(</div>) *** API Gateway & Lambda [#bcad9846] #html(<div style="padding-left: 10px;">) #TODO https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-reference-apigateway.html #html(</div>) *** API Gateway & Lambda (AWS::Serverless 変換を利用する場合) [#laf9d052] #html(<div style="padding-left: 10px;">) #TODO https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/transform-aws-serverless.html https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md #html(</div>) *** DynamoDB [#p42a469c] #html(<div style="padding-left: 10px;">) 例) #mycode2(){{ AWSTemplateFormatVersion: "2010-09-09" Description: sample dynamodb template Resources: SampleTable01: Type: AWS::DynamoDB::Table Properties: # テーブル名(必須) TableName: SampleTable01 # 請求モード BillingMode: PROVISIONED # プロビジョニング(デフォルト): PROVISIONED、オンデマンド:PAY_PER_REQUEST # テーブルキー 及び インデックスのキー項目(必須) AttributeDefinitions: - AttributeName: pkeyCol # 項目名 AttributeType: S # 文字列:S、数値:N、バイナリ:B - AttributeName: skeyCol AttributeType: S - AttributeName: gsiCol AttributeType: S - AttributeName: lsiCol AttributeType: S # キャパシティユニット( BillingMode が PROVISIONED の場合は必須 ) ProvisionedThroughput: ReadCapacityUnits: 5 # 読み込みキャパシティユニット WriteCapacityUnits: 5 # 書き込みキャパシティユニット # テーブルのキー項目(必須) KeySchema: - AttributeName: pkeyCol # 項目名 KeyType: HASH # HASH or RANGE - AttributeName: skeyCol KeyType: RANGE # GSI GlobalSecondaryIndexes: - # インデックス名 IndexName: SampleTable01_GSI1 # キー項目 KeySchema: - AttributeName: gsiCol KeyType: HASH # 射影 Projection: ProjectionType: KEYS_ONLY # KEYS_ONLY or INCLUDE or ALL # キャパシティユニット ProvisionedThroughput: ReadCapacityUnits: 5 # 読み込みキャパシティユニット WriteCapacityUnits: 5 # 書き込みキャパシティユニット # LSI LocalSecondaryIndexes: - # インデックス名 IndexName: SampleTable01_LSI1 # キー項目 KeySchema: - AttributeName: pkeyCol KeyType: HASH - AttributeName: lsiCol KeyType: RANGE # 射影 Projection: ProjectionType: KEYS_ONLY # KEYS_ONLY or INCLUDE or ALL }} 参考URL | AWS::DynamoDB::Table | https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html | | Amazon DynamoDB Table AttributeDefinition | https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-attributedef.html | | Amazon DynamoDB Table KeySchema | https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-keyschema.html | | Amazon DynamoDB Table ProvisionedThroughput | https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-provisionedthroughput.html | | Amazon DynamoDB テーブル GlobalSecondaryIndex | https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-gsi.html | | Amazon DynamoDB テーブル LocalSecondaryIndex | https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-lsi.html | 尚、AutoScaling の設定は AWS::ApplicationAutoScaling::ScalableTarget 及び AWS::ApplicationAutoScaling::ScalingPolicy で設定する必要がある。 ※ Auto Scaling アクションを実行するサービスにリンクされたロールとして AWSServiceRoleForApplicationAutoScaling_DynamoDBTable を使用できる。 ※ https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/AutoScaling.Console.html#AutoScaling.Console.NewTable ※ https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html#cfn-dynamodb-table-examples-application-autoscaling ※ https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/AutoScaling.Console.html 関連 [[DynamoDBのキャパシティユニットについて]] #html(</div>) #html(</div>) ** 実行方法 [#t51adc84] #html(<div style="padding-left: 10px;">) *** create-stack で作成する場合 [#ud4cda5a] #html(<div style="padding-left: 10px;">) #myterm2(){{ # スタック名 STACK_NAME=SampleStack # 検証&作成&作成完了まで待つ aws cloudformation validate-template --template-body file://template.yml \ && aws cloudformation create-stack --stack-name $STACK_NAME --template-body file://template.yml --capabilities CAPABILITY_IAM \ && aws cloudformation wait stack-create-complete --stack-name $STACK_NAME }} #html(</div>) *** package & deploy で作成する場合 [#aac44185] #html(<div style="padding-left: 10px;">) #myterm2(){{ # スタック名 STACK_NAME=SampleStack # アカウントIDの取得 ACCOUNT_ID=`aws sts get-caller-identity | grep Account | awk '{print $2}' | sed -e "s/[^0-9]//g"` # S3バケットの作成(バケット名は世界で唯一である必要がある為、末尾にアカウントID等を付与しておく) aws s3api create-bucket --create-bucket-configuration '{"LocationConstraint": "ap-northeast-1"}' --bucket my-cloudformation-templates-${ACCOUNT_ID} # 検証&パッケージング&デプロイ aws cloudformation validate-template --template-body file://template.yml \ && aws cloudformation package --template-file template.yml --s3-bucket my-cloudformation-templates-${ACCOUNT_ID} --output-template-file packaged-template.yml \ && aws cloudformation deploy --template-file packaged-template.yml --stack-name $STACK_NAME --capabilities CAPABILITY_IAM }} 尚、エラーがあった場合は describe-stack-events で内容を確認できる。 #myterm2(){{ aws cloudformation describe-stack-events --stack-name $STACK_NAME }} #html(</div>)