この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS SAMやCloudFormationでsAWS Systems Managerのパラメータストアを使っている方は多いと思います。 何らかの値をLambdaの環境変数として渡せば、templateファイル自体に内容が記載されないため、GitHub等でPublicなリポジトリにできたりします。
そんなパラメータストアですが、内容を変更したあと、Lambdaを再デプロイしないと値が反映されませんでした。という話です。
パラメータストアに値を追加
下記コマンドでSSM(AWS Systems Manager)のパラメータストアに適当な値を追加します。
$ aws ssm put-parameter \
--type 'String' \
--name '/Hoge/Message' \
--value 'This is a pen.'
{
"Version": 1,
"Tier": "Standard"
}
AWS SAMで適当なLambdaを作成する
テンプレートファイルを修正
SSMパラメータストアから/Hoge/Message
の値を取得し、Lambdaの環境変数MESSAGE
に設定しています。
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: ssm-parameter-sample
Parameters:
Message:
Type: AWS::SSM::Parameter::Value<String>
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.7
Environment:
Variables:
MESSAGE: !Ref Message
Timeout: 5
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
Outputs:
HelloWorldApi:
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
Lambdaコードを作成
Lambdaの環境変数MESSAGE
の内容をAPIのResponseBodyとしています。
app.py
import json
import os
MESSAGE = os.environ['MESSAGE']
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': json.dumps({
'message': MESSAGE,
}),
}
デプロイする
下記コマンドでビルド&デプロイします。parameter-overrides
には、SSMパラメータストアのKey名を与えています。
$ sam build
$ sam package \
--output-template-file packaged.yaml \
--s3-bucket hoge-sam-bucket
$ sam deploy \
--template-file packaged.yaml \
--stack-name Ssm-Parameter-Sample-Stack \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset \
--parameter-overrides \
Message=/Hoge/Message
動作確認する(初回)
APIエンドポイントを取得する
下記コマンドでAPIエンドポイントを取得します。
$ aws cloudformation describe-stacks \
--stack-name Ssm-Parameter-Sample-Stack \
--query 'Stacks[].Outputs'
[
[
{
"OutputKey": "HelloWorldApi",
"OutputValue": "https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/"
}
]
]
APIにアクセスする
最初にSSMパラメータストアに登録した内容が返ってきました。
$ curl https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "This is a pen."}
動作確認する(パラメータストアを更新した)
パラメータストアの内容を更新する
下記コマンドでSSMパラメータストアの内容を更新します。overwrite
オプションを付与しています。
$ aws ssm put-parameter \
--overwrite \
--type 'String' \
--name '/Hoge/Message' \
--value 'This is a banana.'
{
"Version": 2,
"Tier": "Standard"
}
APIにアクセスする
SSMパラメータストアを更新しましたが、APIの応答には反映されていません。
$ curl https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "This is a pen."}
Lambdaの様子
マネジメントコンソールでLambdaを確認すると、環境変数は更新されていません。
動作確認する(再デプロイした)
再デプロイする
同じコマンドで再デプロイします。
$ sam build
$ sam package \
--output-template-file packaged.yaml \
--s3-bucket hoge-sam-bucket
$ sam deploy \
--template-file packaged.yaml \
--stack-name Ssm-Parameter-Sample-Stack \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset \
--parameter-overrides \
Message=/Hoge/Message
APIにアクセスする
APIの応答には反映されました!
$ curl https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "This is a banana."}
Lambdaの様子
マネジメントコンソールでLambdaを確認すると、環境変数は更新されました!
さいごに
改めて考えてみると「そうですよね」としか言えないですが、知らなければ地味にハマりそうです。 SSMパラメータストアの内容を即時反映したい場合は、Lambdaの環境変数を使わずにコードで毎回取得すると良さそうですね。