🐕‍🦺

AWS Parameters and Secrets Lambda ExtensionをServerless Frameworkで試す

2022/10/19に公開

AWS Parameters and Secrets Lambda Extensionに関して

今までLambdaからパラメータストアやSecretsManagerのパラメータを取得する際はAWS SDK等を使用する必要がありましたが、こちらのExtensionを使うとLambdaからHTTPリクエストでパラメータを取得することが出来ます。

https://aws.amazon.com/jp/about-aws/whats-new/2022/10/aws-parameters-secrets-lambda-extension/

公式ドキュメント

以下に書くことは大体このドキュメントに記載されています。
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/ps-integration-lambda-extensions.html

パラメータの取得の仕方がどのように変わるか

↓こんな風にsdkを使用して値を取得していたところを

sdk_sample.py
ssm = boto3.client('ssm')
response = ssm.get_parameter(
    Name='SAMPLE_PARAMETER',
    WithDecryption=True
)

↓こんな風にも書けるようになりました

lambda_extension_sample.py
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すれば試せます。
https://github.com/kishii4726/secrets-lambda-extension-sample

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アーキテクチャは未対応です。

serverless.yml
    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で変更出来ます)。
クエリ文字列として取得したいパラメータ名や複合の有無などのオプションを指定します。

lambda_function.py
     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エラーになります。

lambda_function.py
req.add_header('X-Aws-Parameters-Secrets-Token', os.environ['AWS_SESSION_TOKEN'])

その他

パラメータがキャッシュされる時間は以下の環境変数で指定出来ます。
両方ともデフォルト5分です。

SSM_PARAMETER_STORE_TTL
SECRETS_MANAGER_TTL

Discussion