はじめに
2022/10/18 に AWS Parameters and Secrets Lambda Extension が利用できるようになりました。
AWS から提供される Lambda Extensions を使用して AWS Systems Manager Parameter Store からパラメーターを取得したり、AWS Secrets Manager からシークレットを取得したりできるようになります。
何が嬉しいのか
これまでは Lambda 関数の処理内で AWS SDK 等を使用してパラメーターやシークレットを取得していました。今回の拡張機能を使用することでこれらの値をキャッシュし、Lambda 関数のライフサイクル内で再利用できるようになります。これによりパラメーターやシークレットを取得するためのレイテンシーとコストが削減されます。
基本的な使い方
以下のドキュメントに記載のとおりではあるのですが、基本的な点について補足します。
Lambda 関数に拡張機能の Layer を設定する
Lambda Extensions は Lambda Layers を設定することで使用できるようになります。マネージドコンソールでは AWS レイヤーで Parameters and Secrets Lambda Extension を選択できるようになっていました。
CLI 等から設定する場合は、公開されている Layer の ARN を指定します。リージョン毎の ARN のリストはドキュメントに記載されています。2022/10/19 現在で東京リージョンの ARN は arn:aws:lambda:ap-northeast-1:133490724326:layer:AWS-Parameters-and-Secrets-Lambda-Extension:2
です。
Lambda 関数内に HTTP GET のコードを書く
AWS Parameters and Secrets Lambda Extension を使用すると、AWS SDK での処理は不要になりますが、HTTP GET リクエストで値を取得するコードは必要です。サンプルコードは記事の後半を参照してください。
Lambda 関数の実行ロールの変更
拡張機能は Lambda 関数自体の実行に使用される IAM ロールの認証情報を使用します。そのためパラメーターやシークレットを取得するための適切な IAM ポリシーが設定されている必要があります。例えば Parameter Store の場合、ssm:GetParameter および kms:Decrypt (SecureString 使用時) が必要です。
(Optional) Lambda 関数に環境変数を設定する
パラメーターやシークレットのキャッシュに対する TTL、ログレベルなどを Lambda 関数の環境変数に設定することにより制御できます。
サンプルコード
Amazon Linux 2 の AMI パブリックパラメーターを参照する例です。
注意点は以下です。
- パラメーター名に含まれる
/
はパーセントエンコーディングで変換しておく必要があります - 拡張機能のローカル HTTP サーバーポートはデフォルト
2773
で起動します- 環境変数 PARAMETERS_SECRETS_EXTENSION_HTTP_PORT で変更することができます
- リクエストの検証のため、
X-Aws-Parameters-Secrets-Token
ヘッダーに環境変数AWS_SESSION_TOKEN
を設定する必要があります
const https = require('http');
exports.handler = function(event, context, callback) {
const options = {
hostname: 'localhost',
port: 2773,
path: '/systemsmanager/parameters/get/?name=%2Faws%2Fservice%2Fami-amazon-linux-latest%2Famzn-ami-hvm-x86_64-gp2',
headers: {
'X-Aws-Parameters-Secrets-Token': process.env.AWS_SESSION_TOKEN
},
method: 'GET'
};
const req = https.request(options, res => {
res.on('data', d => {
console.log("Response from cache: "+d);
return d;
});
});
req.on('error', error => {
console.error(error);
});
req.end();
};
実行結果のログは以下のようになります。パラメーター値が取得できてますね!
[AWS Parameters and Secrets Lambda Extension] 2022/10/19 06:51:08 PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL is not present. Log level set to info.
[AWS Parameters and Secrets Lambda Extension] 2022/10/19 06:51:08 INFO Systems Manager Parameter Store and Secrets Manager Lambda Extension 1.0.94
[AWS Parameters and Secrets Lambda Extension] 2022/10/19 06:51:08 INFO Serving on port 2773
EXTENSION Name: AWSParametersAndSecretsLambdaExtension State: Ready Events: [INVOKE,SHUTDOWN]
START RequestId: bb5bcc53-38cc-42d7-9dc5-xxxxxxxxxxxx Version: $LATEST
[AWS Parameters and Secrets Lambda Extension] 2022/10/19 06:51:08 INFO ready to serve traffic
2022-10-19T06:51:09.247Z bb5bcc53-38cc-42d7-9dc5-xxxxxxxxxxxx INFO Response from cache: {"Parameter":{"ARN":"arn:aws:ssm:ap-northeast-1::parameter/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2","DataType":"text","LastModifiedDate":"2022-10-04T17:56:51.889Z","Name":"/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2","Selector":null,"SourceResult":null,"Type":"String","Value":"ami-0fb16641312307fa9","Version":49},"ResultMetadata":{}}
END RequestId: bb5bcc53-38cc-42d7-9dc5-xxxxxxxxxxxx
REPORT RequestId: bb5bcc53-38cc-42d7-9dc5-xxxxxxxxxxxx Duration: 796.05 ms Billed Duration: 797 ms Memory Size: 128 MB Max Memory Used: 76 MB Init Duration: 324.74 ms
個人的つまずきポイント
ローカル HTTP サーバーの起動ポート
デフォルトで 2773
で起動します。当初 AppConfig の拡張機能を参考にして、2772 を指定してリクエスト失敗していました。起動ポートは関数のログにも出力されます。
HTTP ヘッダーの指定
リクエストの検証のため X-Aws-Parameters-Secrets-Token
ヘッダーの設定が必須です。指定していないと bad session token or header key
で 401 unauthorized
になります。
必須なのですが、2022/10/19 現在でドキュメントには記載されていませんでした。不備だと思うので今後修正されるかと思います。私は AWS 社員の方のツイートで設定が必要なことを知りました。
2. Make HTTP requests to localhost:2773/systemsmanager/parameters/get/?name=[parameter_name]
— Oren Nachman (@OrenNachman) October 19, 2022
a. Note: add a header 'X-Aws-Parameters-Secrets-Token' that is set to the AWS_SESSION_TOKEN environment variable
4/ pic.twitter.com/FXc7f9FA9q
以上です。
参考になれば幸いです。