見出し画像

AWS Parameter Storeに保存したパラメータをLambdaから使用してみた

Webhook URL を使って、Teams にメッセージを通知する Lambda を使用すると、その URL の取り扱いには注意が必要です。
ソースコードにベタ書きするのも、あれですし環境変数に埋め込むのも嫌なので、SSM のパラメータストアを使ってみました。
また同時に、Lambda の Memory Size など設定で変更するパラメータもパラメータストアに入れて使ってみました。

環境

- Windows10 Pro: 20H2
- WSL2: Ubuntu-18.04
- AWS CLI: aws-cli/2.0.37 Python/3.7.3 Linux/4.19.84-microsoft-standard exe/x86_64.ubuntu.18
- AWS SAM CLI: SAM CLI, version 1.0.0
- Python: 3.7

パラメータストアを利用する

SecureString で格納する


aws ssm put-parameter \
   --name webhookURL \
   --value "test" \
   --type SecureString

- name: パラメータストアに格納するパラメータ名
- value: 実際の Webhook URL
- type: SecureString

今回のパラメータの暗号化に使用した鍵は AWS マネージド型のキーで作成しました。カスタマー管理型のキーで作成する場合はオプションで`--key-id`パラメータを追加してやるだけで大丈夫です。
CloudFormation では SecureString のパラメータを作成することができないので、シェルスクリプトで書きました。
このスクリプトを実行するだけで、Webhook URL を格納することができました。

Lambda のパラメータをパラメータストアに格納する。

同時に Lambda のパラメータも格納してみました。
この背景としては、運用で異なるパラメータを Cloudformation のテンプレートから分離して安全に Stack をアップデートする目的がありました。

parameter.yamlでパラメータを定義しています。


AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Using Parameter Store in Lambda function
Resources:
 LambdaMemorySize:
   Type: AWS::SSM::Parameter
   Properties:
     AllowedPattern: ^\d+$
     Description: Lambda Memory Size
     Name: /Cloud/dev/test/LambdaMemorySize
     Type: String
     Value: "128"
     Tags:
       Environment: dev
 LambdaTimeout:
   Type: AWS::SSM::Parameter
   Properties:
     AllowedPattern: ^\d+$
     Description: Lambda Timeout
     Name: /Cloud/dev/test/LambdaTimeout
     Type: String
     Value: "120"
     Tags:
       Environment: dev
​

- AllowedPattern: パラメータに正規表現で制限を加えています
- ただし、今回は簡単のため数字のみとしています
- Name: 実際のパラメータ名
- Value: 値
- Tags: ここで Enviroment を入れていますが、このタグを元にアクセス制限を与えることも可能です

パラメータのデプロイもやはり、シェルスクリプトで実行しています。


ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`
sam package \
 --template-file parameter.yaml \
 --s3-bucket test-dev-${ACCOUNT_ID} \
 --output-template-file packaged_parameter.yaml
sam deploy \
 --template-file ./packaged_parameter.yaml \
 --stack-name test-parameter \
 --capabilities CAPABILITY_IAM \
 --no-fail-on-empty-changeset
​

sam package コマンドで、デプロイするコードを圧縮し、S3 にアップロードして、デプロイの準備が整った、パッケージ化された SAM テンプレートファイルを生成します。
sam deploy コマンドにより、実際のリソースをデプロイします。

デプロイ後に SSM パラメータストアを確認すると以下の画像のようになっております。

画像1

Lambda 関数のデプロイ

SAM テンプレートファイルの作成

今回は単純な Lambda 関数のみを作成します。
実際に Lambda 関数の Timeout 時間や Memory Size はパラメータストアの値を使用するようにしています。
ここで重要なのが、Lambda に与える IAM Policy として、`AmazonSSMReadOnlyAccess`を明示的に定義することです。

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Using Parameter Store in Lambda function
Parameters:
 LambdaMemorySize:
   Type: AWS::SSM::Parameter::Value<String>
 LambdaTimeout:
   Type: AWS::SSM::Parameter::Value<String>
Resources:
 SampleFunction:
   Type: AWS::Serverless::Function
   Properties:
     Name: test-function
     CodeUri: src/
     Handler: test.lambda_handler
     Runtime: python3.7
     Policies:
       - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
       - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess
     Timeout: !Ref LambdaTimeout
     MemorySize: !Ref LambdaMemorySize

Lambda のコード

今回のコードは非常に単純で、テスト実行されたらパラメータストアに格納された Webhook URL を Print するだけです。

import boto3
import os
ssm = boto3.client("ssm")
def get_secure_string():
   response = ssm.get_parameter(
       Name="webhookURL",
       WithDecryption=True
   )
   return response["Parameter"]["Value"]
def lambda_handler(evnt, context):
   webhookURL = get_secure_string()
   print(f"WebHookURL is {webhookURL}")

Lambda 関数のデプロイ


ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`
sam package \
 --template-file template.yaml \
 --s3-bucket test-dev-${ACCOUNT_ID} \
 --output-template-file packaged.yaml
sam deploy \
 --template-file ./packaged.yaml \
 --stack-name test-function \
 --capabilities CAPABILITY_IAM\
 --no-fail-on-empty-changeset \
 --parameter-overrides \
   LambdaMemorySize=/Cloud/dev/test/LambdaMemorySize \
   LambdaTimeout=/Cloud/dev/test/LambdaTimeout

Lambda のデプロイもシェルスクリプトを使用しています。
概ねはパラメータストアのときと同様ですが、`parameter-overrides`にてパラメータストアを使用するパラメータを渡しています。
デプロイ成功後にコンソールを確認してみます。そのなかでパラメータの項目があり、以下の画像のように、値にパラメータストアにあるパラメータ名、解決済みの値として実際に定義した値が入力されています。

画像2

もし、運用で Lambda のメモリサイズを上げるというときには、パラメータストアのテンプレートのみを変更するだけでよくなります。

結果確認

適当なイベントで実際にデプロイした関数を実行してみます。ログ出力を確認してみると、以下のように、`WebHookURL is test`と出力されていることが分かります。

画像3

まとめ

パラメータストアに値を保存して、Lambda でそれを使用してみました。
template のファイルから簡単に、パラメータの分離ができ、さらに Webhook URL についても、ベタ書きにする必要もなくなりました!
パラメータストアについては履歴が残るので、その点も便利なのではないでしょうか。

この記事が気に入ったらサポートをしてみませんか?