AWS Systems Manager (SSM)のParameter Storeに認証情報を置き参照する

(2019-01-07)

DBのパスワードやAPIトークンといった認証情報をバージョン管理するコードや設定ファイル上に書くとOSS化など公開範囲を広げるときにやや困るし漏れるリスクが高まるのでなるべく避けたい。 そこでSSMのParameter Storeに値を置き、実行時やデプロイ時に参照する。

SSMのParameter StoreとSecrets Manager

Systems Manager (SSM)はAWSのリソースを可視化したり操作を自動化したりするサービス群で、 設定を持つParameter Storeはその一つ。値は暗号化して持つこともできる。 料金はかからない。

SSMのParameter Storeと似たような別のAWSのサービスに Secrets Managerというのがあって、 こちらはLambdaによって定期的に新しい値を生成しローテーションさせることができる。特にRDSなら自前の関数を用意する必要もない。 ただし料金がシークレットの件数($0.4/月)とAPIコール($0.05/10000回)でかかる。

今はParamter StoreとSecrets Managerが統合されていて、Parameter StoreのAPIでどちらも参照できるようだ。 今回はローテーションしないので単純に料金がかからないParameter Storeの方に書き込むことにする。 ただし、Parameter Storeは現状一度に大量のリクエストが飛ぶような使い方をするとRate exceededになってしまう問題がある。

実行時の値取得

実行時に値を取得するのはこんな感じ。

package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ssm"
)

type Parameter struct {
	ssm *ssm.SSM
}

func newParameter(sess *session.Session) *Parameter {
	return &Parameter{
		ssm: ssm.New(sess),
	}
}

func (s *Parameter) Get(name string, decrypt bool) (string, error) {
	param, err := s.ssm.GetParameter(&ssm.GetParameterInput{
		Name:           aws.String(name),
		WithDecryption: aws.Bool(decrypt),
	})
	if err != nil {
		return "", err
	}
	var secret string
	if param.Parameter.Value != nil {
		secret = *param.Parameter.Value
	}
	return secret, nil
}

func main() {
	secret := newParameter(session.New())
	param, err := secret.Get("test", true)
	if err != nil {
		panic(err)
	}
	fmt.Println(param) // => ok

	param, err = secret.Get("notfound", true)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok {
			fmt.Println(awsErr.Code()) // => ParameterNotFound
		}
	}
}
$ AWS_SDK_LOAD_CONFIG=1 AWS_PROFILE=**** go run main.go

Serverless Framework

Serverless Frameworkの設定ファイルserverless.ymlでもSSMを参照でき、デプロイ時に解決される。

Serverless FrameworkでLambdaをデプロイする - sambaiz-net

provider:
  name: aws
  ...
  environment:
    SECRET: ${ssm:test~true}

参考

AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか?比較 - Qiita