🤝

2023年時点で個人的に最強だと思うAWS接続設定の共有方法(AWS IC(SSO)前提)

2023/10/08に公開

前提

  • 認証方式がAWS IC(SSO)
  • Terraformやserverless frameworkなど、AWS権限を必要とする開発をしている
  • (必須ではないが) 複数人で開発している

やり方

事前準備

  1. Gitリポジトリのルートに次のファイルを作成[1]
.envrc
export AWS_CONFIG_FILE=$(expand_path .awsconfig)
export AWS_SHARED_CREDENTIALS_FILE=$(expand_path .awscreds)
.awsconfig
[default]
# https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/sso-configure-profile-token.html などを参考に各々の値を設定
sso_start_url = https://your-org-name.awsapps.com/start
sso_region = ap-northeast-1
sso_account_id = 123456789012
sso_role_name = AdministratorAccess
region = ap-northeast-1
  1. direnvをインストール
  2. Gitリポジトリのルートで direnv allow を実行
  3. aws sso login を実行
  4. aws sts get-caller-identity を実行
実行例
$ aws sts get-caller-identity
{
    "UserId": "ABBAVTZIBTYRT2ULO4A3U:kazufumi-nishida",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_AdministratorAccess_deadbeef695dcef4/kazufumi-nishida"
}
  1. 出力結果が.awsconfigに書いたアカウントIDおよびIAMロールになっていることを確認

各開発者

AWSへアクセスする直前、次を行う:

  1. (やっていなければ) direnvをインストール
  2. Gitリポジトリのルートで direnv allow を実行
  3. aws sso login を実行

aws sso login はAWS ICのセッションが切れるごとにやる必要があります(この手法というよりAWS ICの制約)

この方法のメリット

  1. 各開発者がそれぞれでAWSへの接続設定[2]を管理する必要がない
  2. そのリポジトリで必要な権限を sso_role_name の形で統一できる

仕組みの原理解説

AWS ICを使っている場合、接続設定にcredentialsが含まれません。
ですので、その接続設定はGitにコミットすることができます。
しかし、通常であればawsコマンドやSDKは ~/.aws/config を見に行ってしまいます
これではGitリポジトリに追加することはできません。

そこで AWS_CONFIG_FILE 環境変数を使って見に行くCONFIGファイルのパスを変更します。
これをコマンド実行ごとに指定するのはとても手間がかかかるので、 direnv ツールを使って作業ディレクトリ以下にいるときは常に AWS_CONFIG_FILE 環境変数が設定されているようにします。

一時的に別のAWSプロファイルで実行したい場合

以下のように環境変数を上書きすることで切り替えられます。

実行例
$ AWS_CONFIG_FILE=~/.aws/config AWS_PROFILE=account1-env2 terraform plan

注意点

認証方法の種類と優先順位

AWSへの認証情報の設定方法はたくさんあります。
それらには優先順位があり、環境変数の優先順位は2番目と高いですが、コマンドラインなどで直接指定した場合、および AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY 環境変数は AWS_CONFIG_FILE より優先順位が高いです。
上手く動かない場合は、SHELLで printenv | grep "AWS" などを実行してそれらの環境変数を設定していないか確認してください。

terraformが ~/.aws/credentials を見に行ってしまう問題

使用するツールによっては、 ~/.aws/credentials[defalut] に書かれた認証情報を見に行ってしまうようです。

https://twitter.com/raki/status/1710726485290766521

現状、awscliは問題なし、terraformは問題があることを確認しています[3]

対策として、AWS_SHARED_CREDENTIALS_FILE 環境変数へあえて存在しないパスを指定しています。

.envrc
export AWS_CONFIG_FILE=$(expand_path .awsconfig)
export AWS_SHARED_CREDENTIALS_FILE=$(expand_path .awscreds)

メモ

元tweet: https://twitter.com/k_bigwheel/status/1710701766134882583

脚注
  1. AWS_SHARED_CREDENTIALS_FILE の設定理由については後述します ↩︎

  2. ~/.aws/config~/.aws/credentials ↩︎

  3. terraformもaws公式のgolang SDK使っているんですけど、なぜ振る舞いに違いがあるんでしょう ↩︎

Discussion