AWS Parameters and Secrets Lambda Extensionとは?
AWS Parameters and Secrets Lambda Extensionを使用すると、Lambda 関数の AWS Secrets ManagerのシークレットとParameter Storeのパラメータを取得してキャッシュできます。
AWS Parameters and Secrets Lambda Extensionを使用するメリット:
- キャッシュされたシークレットまたはキャッシュされたパラメーターの取得は、それぞれ Secrets Manager またはParameter Storeアから取得するよりも高速です。そのため、関数の実行時間を短縮することができます。
- APIのコストを短縮することができます。
AWS Parameters and Secrets Lambda Extensionは、localhost ポート 2773 にリクエストを行います。PARAMETERS_SECRETS_EXTENSION_HTTP_PORT : 2773を環境変数として設定します。
この記事では、AWS Parameters and Secrets Lambda Extensionを使用して、Lambda 関数で AWS Secrets Manager シークレットを取得してキャッシュしてみました。
やってみた
Secrets Managerでシークレットの作成
- Secrets Manager のコンソールで[Store a new secret]を選択しておきます。
- [Other type of secret] をシークレットタイプとして選択します。
- シークレットをキー/値ペアとして入力しておきます。
- シークレットの名前を入力し、他の設定をデフォルト値のままにしてシークレットをStoreしておきます。
Lambda関数の作成
- Python ランタイムで Lambda 関数を作成しておきます。最新の Python バージョンでは「No module named requests」エラーが発生するため、今回は Python 3.7 を使用します。
- Lambda が Secrets Manager シークレットにアクセスできるようにする権限を持つ IAM ポリシーを作成し、このポリシーを Lambda 実行ロールにアタッチしておきます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": [
"arn:aws:secretsmanager:<region>:<account-id>:secret:*"
]
}
]
}
Extensionを使用せずにLambdaの実行時間の確認
- Python コードを以下のコードに置き換えます。これは、Lambda を実行するたびに Secret Manager からシークレットを取得します。
import json
import boto3
def lambda_handler(event, context):
client = boto3.client('secretsmanager')
secret = client.get_secret_value(SecretId='lambda-secret')
return secret['SecretString']
- 初めて Lambda 関数を実行するときに Secrets Manager からシークレットを取得するのにかかる時間は約 1640.58 秒です。
- その後の Lambda の実行では、シークレットを取得する時間は 1640.58 秒から 265.77 秒に短縮されました。
Extensionを使用しているLambdaの実行時間の確認
Lambda 関数にレイヤーを追加する
- Lambda コンソールで関数を選択し、Layersを選択して、Add a layerを選択しておきます。
- AWS layers で [AWS Parameters and Secrets Lambda Extension] を選択して、レイヤーを追加しておきます。
Lambda 関数に環境変数を追加する
- Lambda 関数を開き、Configurationで Environment variables を選択し、Edit をクリックしておきます。
- [Add environment variable]をクリックし、キーとして [PARAMETERS_SECRETS_EXTENSION_HTTP_PORT] を入力し、[2773] を値としてを入力し、保存しておきます。
拡張キャッシュからシークレットを取得する Python コード
- 拡張キャッシュからシークレットを取得するために、コードのリクエストヘッダーに [X-AWS-Parameters-Secrets-Token] を追加しておきます。
- トークンを[AWS_SESSION_TOKEN]に設定しておきます。
- 以下はシークレットを取得するコードです。
import json
import boto3
import os
import requests
def lambda_handler(event, context):
headers = {"X-Aws-Parameters-Secrets-Token": os.environ.get('AWS_SESSION_TOKEN')}
SECRETS_EXTENSION_PORT = os.environ.get('PARAMETERS_SECRETS_EXTENSION_HTTP_PORT')
secrets_extension_endpoint = f"http://localhost:{SECRETS_EXTENSION_PORT}/secretsmanager/get?secretId=lambda-secret"
req = requests.get(secrets_extension_endpoint, headers=headers)
secret = json.loads(req.text)["SecretString"]
return secret
- 初めて Lambda 関数を実行するときに Secrets Manager からシークレットを取得するのにかかる時間は約 697.25 秒です。
- その後の Lambda の実行では、シークレットを取得する時間は 697.25 秒から 29.81 秒に短縮されました。シークレットがキャッシュから取得されるため、時間が短縮されました。
まとめ
シークレットを取得する時間は、Secrets Manager から取得する場合に比べて大幅に短縮されました。キャッシュされたシークレットの取得は Secrets Manager からの取得よりも高速です。[AWS Parameters and Secrets Lambda Extension] を使用して、Parameter Store パラメータを取得してキャッシュすることもできます。
Reference : Use AWS Secrets Manager secrets in AWS Lambda functions