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}