結論
アプリ実行用サーバにアクセスキーを持たせて、各AWSリソースにアクセスするやり方はできるだけ避ける。
代わりにIAM RoleやSTSを使って一時的な認証を行うことができるのでそちらでできるだけ代替する。
具体的には、以下の順に推奨されていた。
- EC2かECSならそれぞれ専用のIAM Roleを使用する
- 1が無理なら.aws/credencialsか.aws/configに設定する
- EC2以外のマシンなどで実行する場合などは、環境変数で持たせるといい
AWS アクセスキーを管理するためのベストプラクティス - AWS アカウント管理
どうやるか
EC2のインスタンスプロファイルによってEC2内のアプリケーションに一時的な認証情報を付与する。
つまりインスタンスプロファイルに必要なアクセス権限を持たせたIAM Roleを紐づければいい。
AWS CDKとAWS CLIはこの認証情報をインスタンスプロファイルから自動的に取得してくれる。
メリット
- アクセスキーの管理がIAM Roleで一元化できる。
- Credencialsのローテートが不要になる。
AWS CDKとAWS CLIはどうやって認証情報を取得するのか(Golang)
認証情報を取得するのは以下のコード実行時らしい。
https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#loading-aws-shared-configuration
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
log.Fatalf("failed to load configuration, %v", err)
}
**config.LoadDefaultConfig(Getting StartedのWrite Codeを参考にする)**
- 第1引数:
context.TODO()
- context.Context型を引数にとるメソッドに渡したいcontextの実装がない or 決まっていない場合に暫定的にcontext.Contextを渡すためだけに使用している。(参照)
- 第2引数:
config.WithRegion("us-west-2")
- LoadOptionsFunc型(…func(*LoadOptions) error)を引数に取る
- 1
config.LoadDefaultConfig
は実行されると、LoadOptions構造体のfieldに関数の実装を差し込むLoadOptionsFunc型の関数を返す。(この時点で実行はまだされない)- その後、LoadOptionsFunc型の関数はloopによって空のLoadOptions構造体を引数に受け、「LoadOptions構造体のfieldに関数の実装を差し込む」が実行される。
- 上記流れでLoadOptions構造体に関数がセットされる。
- 2
- LoadOptions構造体はConfigs型に埋め込まれる
- 外部の設定値をConfigにロードする
- 3
- ConfigsはAWSResolverによってaws.Configに変換され、これが返り値となる。
- LoadOptionsFunc型(…func(*LoadOptions) error)を引数に取る
- あとは****imds**** packageにaws.Configを渡せばそのfield通りにEC2内のデータを取得できる。
- imds package内のIAMInfo構造体でinstance profileの値は受け取ってそう
- 時間があればこの先もそのうち調べてみる
参照記事・コード
https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#LoadDefaultConfig
https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds
https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/ec2/imds#IAMInfo
https://github.com/aws/aws-sdk-go-v2/blob/feature/ec2/imds/v1.13.3/feature/ec2/imds/api_client.go
AWS CDKとAWS CLIがcredencialsを読み込む順番
どうやら以下順番で認証情報の読み込みを行うらしい(参照)