Skip to content

Lambdaからパラメータストアにアクセスする

素朴に実装するとSSMのレートリミットに到達してしまう。また、Environment に設定すると誰でも閲覧できるのでシークレットには使えない。

Lambdaはウォームスタートとコールドスタートがあり、コールドスタートの場合に一度だけアクセスするなら問題ないとは思うものの、当たったときに復旧する手段が無く、AWSアカウント全体でパラメータストアが止まってしまうので、サービスによってはリスクが高い。

無難な手段としてはLambda拡張を使う方法がある。公式が AWS-Parameters-and-Secrets-Lambda-Extension を提供しているので、これを使うといい。

Parameters-and-Secrets-Lambda-Extension拡張を使う

Section titled “Parameters-and-Secrets-Lambda-Extension拡張を使う”

まずはコンテナイメージを使ったLambda関数で拡張を実行するのように、拡張をコンテナイメージの /opt/extensions 以下に配置する。

次に、アプリケーションから拡張にアクセスしてパラメータを取得する。

type secretsResponse struct {
Parameter struct {
Value string
}
}
func fetchFromParameterStore(ctx context.Context, key string) (string, error) {
var params url.Values
params.Add("name", key)
params.Add("withDecryption", "true")
u, err := url.Parse("http://localhost:2773/systemsmanager/parameters/get")
if err != nil {
return "", err
}
u.RawQuery = params.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
if err != nil {
return "", err
}
token := os.Getenv("AWS_SESSION_TOKEN")
req.Header.Add("X-Aws-Parameters-Secrets-Token", token)
res, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer func() {
io.Copy(io.Discard, res.Body)
res.Body.Close()
}()
var v secretsResponse
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return "", err
}
return v.Parameter.Value, nil
}