AWS CLI が ~/.aws/config よりも ~/.aws/credentials を優先してリソースへのアクセス失敗する対策

この記事は [LIFULL Advent Calendar 2024](https://qiita.com/advent-calendar/2024/lifull) 17日目の記事です。
織物工場生産技術職→コワーキングスペース接客業を経てエンジニアになった謎キャリアのマントルです。🌏
IAM Identity Center 導入により AWS CLI でのお困り対策例の記事を備忘録的に書きました。

# 概要
AWS CLI を使用する際に ~/.aws/config で設定した内容よりも ~/.aws/credentials の内容が優先されてしまうことによって、予期しない動作になることがあります。

この記事では、この問題の背景と対策について解説します。

# 背景
実際にあったシチュエーションです。

IIC（IAM Identity Center）を弊社で特定のアカウントで導入され、
シングルサインオンで AWS CLI にログインできるようになりました。

ブラウザを通じての認証で簡易的にログインできたり、アクセスキーやシークレットキーを直接保存しないのでセキュリティ面で向上したりとメリットはたくさんあります。

それと別に、IICがまだ導入されていない従来のログイン方法（aws configure）を取る複数のAWSアカウントを使用しておりました。



そこでとある問題が発生しました。

IICを導入しているアカウントで動作確認しようとすると...

```
# AWS SSO を設定
❯ aws configure sso

# AWS SSO にログイン
❯ aws sso login --profile <作成したプロファイル名>

# 自分のIDを呼び出せるか動作確認
❯ aws sts get-caller-identity --profile <作成したプロファイル名>
↓
# このようなエラー発生
Unable to locate credentials. You can configure credentials by running "aws configure".

```



AWSの認証情報が見つからないというエラーが発生しました。
`aws configure sso` にて登録できてログインもできているはずなのに認証情報が見つからないとは...どういうことだ？

( ‘ω’)ｴｯ…
AWS CLIよ！いま教えたばかりじゃないか！もう俺のこと忘れた？という状態になりました。
  
※ aws configure sso セットアップはこちらの記事が参考になると思います：https://qiita.com/oizumi-yuta/items/d01a193be93789b3ab43

## ~/.aws/config と ~/.aws/credentials に同名のプロファイルを保存していた

```~/.aws/config
[my-profile]
region = ap-northeast-1
sso_session = session-name
sso_account_id = <アカウントID>
sso_role_name = <ロールネーム>

[sso-session session-name]
sso_start_url = <SSOスタートURL>
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access
```

```~/.aws/credentials
[my-profile]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットキー>
```

上記は例ですが、`~/.aws/config` と `~/.aws/credentials` に同名のプロファイルを保存していました。
どうしてこれが問題なのか？

## ~/.aws/config よりも ~/.aws/credentials の内容を優先される

### configとcredentials について

| ファイル | 用途 |
| ---- | ---- |
| ~/.aws/config | 主に非認証系の設定（リージョンや出力形式、SSO設定など）を扱いますが、プロファイルに関する情報も含めることができます。 |
| ~/.aws/credentials | アクセスキーやシークレットキーなどの認証情報が保存されます。このファイルのプロファイル設定が最優先されます。 |

ref: https://docs.aws.amazon.com/ja_jp/cli/v1/userguide/cli-configure-files.html

同名のプロファイルを config と credentials に保存しているとコマンド実行時にプロファイルを指定してても、credentials を優先して使ってしまうので意図した挙動にならないことがあります。

## なぜ~/.aws/credentialsが優先されるのか
~/.aws/credentialsファイルは主に認証情報（アクセスキーとシークレットキー）を保存するために作られています。
通常、~/.aws/config は非認証系の設定を行うために使用されますが、同じプロファイル名が両方に存在する場合、credentials が優先されます。ですが、認証系の情報も保存できるため、対策としてconfigだけを使うという方法があります。（個人的にはこうしてます）

AWS CLIはこのように credentials にある名前から思い出すのでいくら最新に config に新しい情報を教えたばかりでも「え、そんなの知らないですよ？」って言わんばかりの反応をします。

# 対策

## 方法1. プロファイル名を分ける

```~/.aws/config
[first-profile]
region = ap-northeast-1
sso_session = session-name
sso_account_id = <アカウントID>
sso_role_name = <ロールネーム>

[sso-session session-name]
sso_start_url = <SSOスタートURL>
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access
```

```~/.aws/credentials
[second-profile]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットキー>
```

このように例として、「first-profile」、「second-profile」という名前で分けてますが、 `~/.aws/config` と `~/.aws/credentials` で管理する名前を区別することでAWS CLIに誤認識されることはなくなります。

## 方法2. ~/.aws/credentials を削除してしまう

```
rm ~/.aws/credentials
```

~/.aws/credentials を削除すれば競合が解消されます。そして、アクセスキーとシークレットキーをconfigに移動させてしまって、configで一括管理すると管理しやすくなります。（自分はこうしてます。）

```~/.aws/config
[my-profile]
region = ap-northeast-1
output = json
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットキー>
```

## 方法3. defaultを使用しない。プロファイルを指定して使う
default プロファイルを避け、特定の名前のプロファイルを使用することで、設定内容の競合を完全に回避することができます。

```~/.aws/config
[default]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットキー>
上記を削除
↓
[my-profile]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットキー>

```

そして実際に使用する際にはプロファイルを指定して実行します。

```
aws s3 ls --profile iic-profile
```

# おわり
以上になります。
良い AWS CLI ライフを！