
Systems Managerのパラメータストアを更新したあと、Lambdaを再デプロイしないと内容が反映されなかった話
この記事は公開されてから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に設定しています。
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としています。
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の環境変数を使わずにコードで毎回取得すると良さそうですね。










