今まではboto3を使ってParameter Storeから値を取得していました。
import boto3
ssm = boto3.client('ssm')
response = ssm.get_parameters(
Names=[Parameter Store Key],
WithDecryption=True
)
が、以下のアップデートにより、直接Parameter Storeなどから値を取得できるようになったので、実際に試してみた際のメモです。
必要な権限
SDKを使って実装していたときと同様に、Lambdaの実行ロールに以下の権限を渡す必要がある。
ssm:GetParameter
-
kms:DecryptSecureString
(SecureStringを取得する場合に必要)
必要なレイヤーの追加
AWSレイヤー
Paramter StoreやSecrets Managerから値を取得するためのレイヤーがAWSから提供されているので追加する。
レイヤーの追加
→ AWS レイヤー
→ AWS-Parameters-and-Secrets-Lambda-Extension
の順に操作し、レイヤーを選択・追加する。
カスタムレイヤー
後述するが、今回の手法でParameter Storeから値を取得する場合、ローカルホストに対して以下のようなHTTPリクエストを投げる。
parameter_url = ('http://localhost:' + port + '/systemsmanager/parameters/get/?name=' + ssm_parameter_path)
本記事ではRequests
モジュールを利用するため、必要であれば以下のように事前にRequests
モジュールをレイヤー化して登録しておく。
$ mkdir python/
$ cd python
$ pip install -t ./ requests
$ cd ..
$ zip -r Layer.zip python/
補足: 標準ライブラリのrequestの利用
LambdaでHTTPリクエストを行う場合 urllib.request
であれば標準で用意されているので、多少コードが長くなっても問題ない場合はレイヤーを作成しなくても良いかも。
import urllib.request
Lambdaから値を取得するサンプルコード
必要な権限・レイヤーを追加したあとは、Lambda関数内で特定のエンドポイントへHTTPリクエストを行うような処理を実装すれば良い。
import os
import requests
# デフォルトのポートは2773 (変更可能)
endpoint = 'http://localhost:2773/systemsmanager/parameters/get/?name={}'.format('Parameter Storeに登録してあるKey名')
# GETリクエストを行うために必要なトークンの情報
headers = {
'X-Aws-Parameters-Secrets-Token': os.environ['AWS_SESSION_TOKEN']
}
res = requests.get(endpoint, headers=headers)
上記を実行することでParameter Storeに対するリクエストが可能。
ちなみにレスポンスの中から値のみを取得したい場合は以下のようにすればOK。
value = res.json()['Parameter']['Value']
利用できる環境変数
環境変数を設定することでポートやTTLの変更などの細かい設定を行うことができる。
まとめ
本機能を使うことで、Lambdaで直接値を取得できるだけでなく、AWS側でキャッシュしてくれます。自前でのキャッシュ実装が不要になるだけでなく、レイテンシー改善およびコスト削減を行うこともできるため、積極的に利用してくと良いかもしれないです。