Slack Bot のイベントハンドラを Lambda で作成したい。
そのために、ローカルでテストしつつ、CloudFormation でデプロイを自動化したい。
CONTENTS
- この記事の内容
- できあがったもの
- aws cloudformation package でパッケージング
- aws cloudformation deploy でデプロイ
- デプロイスクリプト
- まとめ
- 参考資料
この記事の内容
ほぼ下記の記事と同じ内容。 これをトレースしてみたもの。
できあがったもの
以下のテンプレートを aws cloudformation
コマンドで処理する。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: STACK_DESCRIPTION Parameters: Role: Type: String Description: "lambda role arn" KMS: Type: String Description: "KMS key arn" SecretRegion: Type: String Description: "region of secret" SecretId: Type: String Description: "id of secret" Resources: lambdaResource: Type: AWS::Serverless::Function Properties: FunctionName: LAMBDA_FUNCTION_NAME Runtime: nodejs10.x Handler: index.handler MemorySize: 128 Timeout: 3 CodeUri: .. AutoPublishAlias: active KmsKeyArn: Ref: KMS Role: Ref: Role Environment: Variables: SECRET_REGION: Ref: SecretRegion SECRET_ID: Ref: SecretId
aws cloudformation package でパッケージング
以下の記事を参考にテンプレートを作成する。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: STACK_DESCRIPTION Parameters: Role: Type: String Description: "lambda role arn" KMS: Type: String Description: "KMS key arn" SecretRegion: Type: String Description: "region of secret" SecretId: Type: String Description: "id of secret" Resources: lambdaResource: Type: AWS::Serverless::Function Properties: FunctionName: LAMBDA_FUNCTION_NAME Runtime: nodejs10.x Handler: index.handler MemorySize: 128 Timeout: 3 CodeUri: .. AutoPublishAlias: active KmsKeyArn: Ref: KMS Role: Ref: Role Environment: Variables: SECRET_REGION: Ref: SecretRegion SECRET_ID: Ref: SecretId
- Parameters : コマンドラインから指定するパラメータ。テンプレートからは
Ref: KEY
で参照 - AutoPublishAlias : デプロイ時にエイリアスを付け替える
エイリアスについては AWS Lambda で Slack Bot イベントハンドラを作る にまとめた。
STACK_DESCRIPTION
、LAMBDA_FUNCTION_NAME
は適宜指定する。
ディレクトリ構成は以下のような形にした。
- package.json - node_modules/ - index.js - lib/ - config/ - template.yaml
このテンプレートを aws cloudformation package
コマンドで処理するとデプロイ可能な形式に変換できる。
aws cloudformation package \ --template-file config/template.yaml \ --output-template-file config/packaged-template.yaml \ --s3-bucket $S3_BUCKET_NAME
$S3_BUCKET_NAME
は適宜指定する。
ここには CodeUri
で指定したソースがアップロードされる。
このコマンドを実行するユーザーは $S3_BUCKET_NAME
で指定するバケットにアップロードする権限を持っている必要がある。
aws cloudformation deploy でデプロイ
先に package コマンドで生成した packaged-template.yaml
を deploy すると、テンプレートで定義した Lambda がデプロイされる。
--parameter-overrides
に Parameters
の内容を指定する。
aws cloudformation deploy \ --template-file config/packaged-template.yaml \ --region $STACK_REGION \ --stack-name $STACK_NAME \ --parameter-overrides \ Role=$ROLE_ARN \ KMS=$KMS_ARN \ SecretRegion=$SECRET_REGION \ SecretId=$SECRET_ID
変数はそれぞれ、以下のものを設定する。
$STACK_REGION
: このスタックのリージョン$STACK_NAME
: スタック名$ROLE_ARN
: Lambda のロール(詳細は AWS Lambda で Slack Bot イベントハンドラを作る)$KMS_ARN
: KMS キー$SECRET_REGION
: シークレットのリージョン$SECRET_ID
: シークレット名(詳細は AWS Secrets Manager で機密情報を保存する)
deploy
する際に必要なポリシーは以下の通り。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "cloudformation", "Effect": "Allow", "Action": [ "cloudformation:GetTemplateSummary", "cloudformation:DescribeStacks", "cloudformation:DescribeChangeSet", "cloudformation:CreateChangeSet", "cloudformation:ExecuteChangeSet" ], "Resource": [ "arn:aws:cloudformation:REGION:ACCOUNT:stack/STACK_NAME/*" ] }, { "Sid": "transform", "Effect": "Allow", "Action": "cloudformation:CreateChangeSet", "Resource": "arn:aws:cloudformation:REGION:aws:transform/*" }, { "Sid": "lambda", "Effect": "Allow", "Action": [ "lambda:ListVersionsByFunction", "lambda:TagResource", "lambda:UntagResource", "lambda:ListTags", "lambda:GetFunction", "lambda:CreateFunction", "lambda:DeleteFunction", "lambda:UpdateFunctionConfiguration", "lambda:UpdateFunctionCode", "lambda:PublishVersion", "lambda:CreateAlias", "lambda:UpdateAlias" ], "Resource": [ "arn:aws:lambda:REGION:ACCOUNT:function:FUNCTION_NAME" ] }, { "Sid": "iam", "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": [ "arn:aws:iam::ACCOUNT:role/ROLE_NAME" ] } ] }
REGION
、ACCOUNT
、STACK_NAME
、FUNCTION_NAME
、ROLE_NAME
は適宜指定する。
複数のユーザーでデプロイするのが面倒だったので、stack, function に関してはデプロイする分だけ複数指定するようにした。
デプロイスクリプト
パラメータは1度指定すれば良いので、--parameter-overrides
はデプロイスクリプトでは指定する必要はない。
aws cloudformation package \ --template-file config/template.yaml \ --output-template-file config/packaged-template.yaml \ --s3-bucket $S3_BUCKET_NAME \ && \ aws cloudformation deploy \ --template-file config/packaged-template.yaml \ --region $STACK_REGION \ --stack-name $STACK_NAME
まとめ
CloufFormation で Lambda をデプロイしてみた。 これでデプロイを自動化できるので、ローカルでテストしつつ、マージされたらデプロイというフローで開発できる。