AWS Parameters and Secrets Lambda ExtensionをServerless Frameworkで試す
AWS Parameters and Secrets Lambda Extensionに関して
今までLambdaからパラメータストアやSecretsManagerのパラメータを取得する際はAWS SDK等を使用する必要がありましたが、こちらのExtensionを使うとLambdaからHTTPリクエストでパラメータを取得することが出来ます。
公式ドキュメント
以下に書くことは大体このドキュメントに記載されています。
パラメータの取得の仕方がどのように変わるか
↓こんな風にsdkを使用して値を取得していたところを
ssm = boto3.client('ssm')
response = ssm.get_parameter(
Name='SAMPLE_PARAMETER',
WithDecryption=True
)
↓こんな風にも書けるようになりました
params = {
"name": "SAMPLE_PARAMETER",
"withDecryption": "true"
}
p = urllib.parse.urlencode(params)
url = 'http://localhost:2773/systemsmanager/parameters/get/?' + p
req = urllib.request.Request(url)
req.add_header('X-Aws-Parameters-Secrets-Token', os.environ['AWS_SESSION_TOKEN'])
with urllib.request.urlopen(req) as res:
body = res.read()
上記の通りパラメータを取得しやすくなったわけではないのですが、SDKを使用した場合とExtensionを使用した場合を比較するとAPIの呼び出し数の減少によるコスト削減やキャッシュを使用することによりレイテンシー改善が期待されるなどパフォーマンス的なメリットがあります。
サンプルコード
パラメータストアのSecureStringのパラメータを取得するサンプルコードです。
サンプルパラメータを作成してsls deploy
すれば試せます。
Usage
$ aws ssm put-parameter --name "SAMPLE_PARAMETER" --type "SecureString" --value "Sample parameters for secrets-lambda-extension-sample
$ sls deploy
作成したLambda関数を実行するとbodyとしてパラメータストアに登録したSAMPLE_PARAMETER
の値がレスポンスのbodyに入ります。
{
"statusCode": 200,
"body": "Sample parameters for secrets-lambda-extension-sample"
}
ログにはExtensionのログも出力されます。
ログレベルは環境変数PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL
で設定可能です。
[AWS Parameters and Secrets Lambda Extension] 2022/10/19 09:08:10 PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL is not present. Log level set to info.
[AWS Parameters and Secrets Lambda Extension] 2022/10/19 09:08:10 INFO Systems Manager Parameter Store and Secrets Manager Lambda Extension 1.0.94
[AWS Parameters and Secrets Lambda Extension] 2022/10/19 09:08:10 INFO Serving on port 2773
ポイント
Lambda Layer
Extensionの機能を使うためにAWSが用意してくれているLambda Layerを使用します。
Layerがプロキシとして機能するようです。
指定するLayerのarnは公式ドキュメントに記載されています。
20221019時点はArmアーキテクチャは未対応です。
layers:
- arn:aws:lambda:ap-northeast-1:133490724326:layer:AWS-Parameters-and-Secrets-Lambda-Extension:2
リクエスト先
ローカルのHTTPサーバのデフォルトポートは2773
なのでlocalhost:2773
とします(環境変数PARAMETERS_SECRETS_EXTENSION_HTTP_PORT
で変更出来ます)。
クエリ文字列として取得したいパラメータ名や複合の有無などのオプションを指定します。
params = {
"name": "SAMPLE_PARAMETER",
"withDecryption": "true"
}
p = urllib.parse.urlencode(params)
url = 'http://localhost:2773/systemsmanager/parameters/get/?' + p
# http://localhost:2773/systemsmanager/parameters/get/?name=SAMPLE_PARAMETER&withDecryption=true
リクエストヘッダー
リクエストヘッダーにAWS_SESSION_TOKEN
を指定しないとリクエストの検証に失敗して401エラーになります。
req.add_header('X-Aws-Parameters-Secrets-Token', os.environ['AWS_SESSION_TOKEN'])
その他
パラメータがキャッシュされる時間は以下の環境変数で指定出来ます。
両方ともデフォルト5分です。
SSM_PARAMETER_STORE_TTL
SECRETS_MANAGER_TTL
Discussion