#mynavi(AWSメモ)
#setlinebreak(on);

* 概要 [#dd0e7442]
#html(<div style="padding-left: 10px;">)
AWS CloudFormation を利用するとインフラ全体をテキストファイルでモデル(ソース)化できる。
AWS上に作成する必要があるリソースを全てCloudFormationテンプレートとして定義しておく事で、環境の複製やデプロイの自動化などが安全容易に行える。

awslabsのサンプル
SAMの仕様
https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md

テンプレートのサンプル
https://github.com/awslabs/serverless-application-model/tree/master/examples

#html(</div>)

* 目次 [#o9960c76]
#contents
- 関連
-- [[AWS API Gateway&LambdaをFlaskに移行しやすいように作る]]
-- [[AWS IotにPublishされたデータをDynamoDBに登録する]]
-- [[PythonでAWS DynamoDBのCRUDを書いてみる]]
-- [[AWS Lambdaで環境変数を使用する]]
-- [[AWSのサービスをJenkinsでデプロイする#template.yml>AWSのサービスをJenkinsでデプロイする#w4800203]]
-- [[CloudFormationでカスタムドメイン対応の API Gateway を作成する]]
-- [[Lambda&API GatewayをCloudFormationで作成する]]
-- [[オンプレミスのサーバログをS3に収集する]]
- 参考
-- https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html
-- https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md
-- https://github.com/awslabs/serverless-application-model/tree/master/examples

* テンプレート形式 [#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>)

* 擬似パラメーター参照 [#g3c440b6]
#html(<div style="padding-left: 10px;">)

リージョン名やアカウントID、スタック名などをパラメータ参照する事ができる。

参考
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html

利用例)
#mycode2(){{
    .
    .
    # Sub関数で利用
    !Sub "${AWS::AccountId}"

    # Ref関数で利用
    !Ref AWS::StackName
}}

#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'
aws cloudformation list-exports --output text | awk '{print $3" "$4}'

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

** S3バケット [#icbb4091]
#html(<div style="padding-left: 10px;">)

参考)
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html

例)
#mycode2(){{
AWSTemplateFormatVersion: "2010-09-09"
Description: sample s3 bucket template
Resources:
  ServerlogBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Sub '${AWS::AccountId}-serverlogs'
}}

#html(</div>)


** Lambda、API Gateway [#p037c91c]
#html(<div style="padding-left: 10px;">)

[[Lambda&API GatewayをCloudFormationで作成する]] を参照。

参考
- Lambda単体 (AWS::Serverless 変換を利用する場合)
-- 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
- Lambda単体 (AWS::Serverless 変換を利用する場合)
-- 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
- API Gateway & Lambda (AWS::Serverless 変換を利用しない場合)
-- https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-reference-apigateway.html
- API Gateway & Lambda (AWS::Serverless 変換を利用する場合)
-- 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>)

** SQS [#x7f810e4]
#html(<div style="padding-left: 10px;">)

参考
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html

#mycode2(){{
AWSTemplateFormatVersion: "2010-09-09"
Description: sample sqs 
Resources:
  SampleQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: "SampleQueue"              # キュー名(FIFOキューにする場合は末尾は .fifo にする必要がある)
      #FifoQueue: true                        # FIFOキューにする場合はtrue
      #ReceiveMessageWaitTimeSeconds: 0       # 待機期間 ※ デフォルト: 0(1 〜 20) ※1以上を指定するとデフォルトでロングポーリングとなる
      #VisibilityTimeout: Integer             # 可視性タイムアウト ※ デフォルト: 30
      #ContentBasedDeduplication: Boolean     # 同一内容のメッセージを重複を除去するかどうか(FIFOキューの時のみ)
      #DelaySeconds: Integer                  # 遅延秒数(デフォルト: 0)
      #KmsMasterKeyId: String                 # KMSのマスターキーID
      #KmsDataKeyReusePeriodSeconds: Integer  # KMSのキーを再利用できる期間
      #MaximumMessageSize: Integer            # メッセージの最大サイズ ※ デフォルト: 256KiB(1 &#12316; 256)
      #MessageRetentionPeriod: Integer        # メッセージの保持期間 ※ デフォルト: 345600 秒(4日) (60&#12316;1209600秒(14日))
      #RedrivePolicy:
      #  deadLetterTargetArn: String          # デッドレターキュー
      #  maxReceiveCount: Integer             # 失敗時の配信回数
      #Tags:
      #  Resource Tag                         # タグ
Outputs:
  SampleQueue:
    Export:
      Name: SampleQueueName
    Value: !GetAtt SampleQueue.QueueName
}}
#html(</div>)


#html(</div>)

* 実行方法 [#t51adc84]
#html(<div style="padding-left: 10px;">)

関連: [[Lambda&API GatewayをCloudFormationで作成する#デプロイ用シェル>Lambda&API GatewayをCloudFormationで作成する#x58d7da5]]

** 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>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS