AWSアクセスキーの管理方法のベストプラクティスの勉強とGo SDK実装のコードリーディング

結論

アプリ実行用サーバにアクセスキーを持たせて、各AWSリソースにアクセスするやり方はできるだけ避ける。

代わりにIAM RoleやSTSを使って一時的な認証を行うことができるのでそちらでできるだけ代替する。

具体的には、以下の順に推奨されていた。

  1. EC2かECSならそれぞれ専用のIAM Roleを使用する
  2. 1が無理なら.aws/credencialsか.aws/configに設定する
  3. 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.LoadDefaultConfigGetting StartedのWrite Codeを参考にする)**

  • 第1引数: context.TODO()
    • context.Context型を引数にとるメソッドに渡したいcontextの実装がない or 決まっていない場合に暫定的にcontext.Contextを渡すためだけに使用している。(参照
  • 第2引数: config.WithRegion("us-west-2")
    • LoadOptionsFunc型(…func(*LoadOptions) error)を引数に取る
      • config.LoadDefaultConfigは実行されると、LoadOptions構造体のfieldに関数の実装を差し込むLoadOptionsFunc型の関数を返す。(この時点で実行はまだされない)
      • その後、LoadOptionsFunc型の関数はloopによって空のLoadOptions構造体を引数に受け、「LoadOptions構造体のfieldに関数の実装を差し込む」が実行される。
      • 上記流れでLoadOptions構造体に関数がセットされる。
      • LoadOptions構造体はConfigs型に埋め込まれる
      • 外部の設定値をConfigにロードする
      • ConfigsはAWSResolverによってaws.Configに変換され、これが返り値となる。
  • あとは****imds**** packageaws.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を読み込む順番

どうやら以下順番で認証情報の読み込みを行うらしい(参照

  1. 環境変数

    1, AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN

    2, AWS_WEB_IDENTITY_TOKEN_FILE

    • これは、以下記事のように外部IDプロバイダを使用した認証を行う際に設定される値。
    • GithubのID Providerで認証を行う例(記事
    • おそらくTokenが含まれたfileのパスか、Token文字列そのものが設定されると思われる。
  2. 設定ファイル

    1, .aws/credencialsを確認

    2, .aws/configを確認

  3. ECSの場合、タスク用のIAM Roleを確認

  4. EC2の場合、インスタンス用IAM Roleを確認