AWS CLI の認証周りについて

## はじめに
`aws configure`コマンドを実行するとなぜ`credentials`と`config`に設定が分かれているのか疑問に思い、認証周りを整理しました。

### 使用環境とバージョン
- macOS Big Sur
- git version 2.24.3 (Apple Git-128)
- aws-cli/2.1.16


## 記事の対象
- ある程度AWSの知識がある方
- AWSの認証周りに興味のある方

## 事前準備
- AWS CLIのインストール
- IAMユーザのアクセスキーとシークレットキーの発行

## configおよびcredentialsについて
`aws configure`コマンドを使用して、AWS CLIに設定を追加します。

```
$ aws configure
AWS Access Key ID [None]: [アクセスキー]
AWS Secret Access Key [None]: [シークレットキー]
Default region name [None]: ap-northeast-1
Default output format [None]: json
```
上記コマンドを実行すると以下の2ファイルに設定が追加されます。

```text:~/.aws/credentials
[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

```text:~/.aws/config
[default]
region=ap-northeast-1
output=json
```


`config`と`credentials`の違いは以下の通り、機密性の違いで分かれているようです。
>
AWS CLI は aws configure で指定された機密性の高い認証情報を、ホームディレクトリの .aws という名前のフォルダにある credentials という名前のローカルファイルに保存します。aws configure で指定された機密性の低い設定オプションは、config という名前のローカルファイルに保存されるだけでなく、ホームディレクトリの .aws フォルダにも保存されます。

[設定ファイルと認証情報ファイルの設定](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html)

## 名前付きプロファイルについて
`credentials`と`config`には同じファイル内で複数のプロファイルを設定することができます。
以下に`user1`のIAMユーザ認証情報を追加しています。

```text:~/.aws/credentials
[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

[user1]
aws_access_key_id=AKIAI44QH8DHBEXAMPLE
aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
```

```text:~/.aws/config
[default]
region=ap-northeast-1
output=json

[profile user1]
region=us-east-1
output=text
```

追加したプロファイルはawsコマンドを使用する際のオプションに指定することができます。

```text:s3コマンドの例
$ aws s3 ls --profile user1
```

また、デフォルトで特定のプロファイル指定したい場合は環境変数に設定できます。
環境変数に設定する場合はawsコマンド時の`--profile`オプションは不要です。

```text
$ export AWS_DEFAULT_PROFILE=user1
$ aws sts get-caller-identity  // 確認コマンド
```

[名前付きプロファイル - AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-role.html)

## スイッチロール権限で認証する
configに新たにプロファイルと追加し、以下のキーを設定します。

|キー|設定内容|
|:--|:--|
|role_arn|スイッチ先のロールARN|
|source_profile|`role_arn`で設定したロールにアクセス権限があるIAMユーザー認証情報のプロファイル名を設定|

```text:~/.aws/config
[default]
region=ap-northeast-1
output=json

+ [profile switchrole]
+ role_arn = arn:aws:iam::{スイッチ先のAWSアカウントID}:role/{ロール名}
+ source_profile = default
+ region=ap-northeast-1
+ output=json
```

`source_profile`には`role_arn`で設定したロールを使用するアクセス権限があるIAMユーザー認証情報を設定する必要があります。上記例では`credentials`の`default`に設定しているIAMユーザの認証情報が参照されます。

`role_arn`で設定したロールには`credentials`の`default`に設定しているIAMユーザに`sts:assume-role`を呼び出すアクセス権限が付与されている必要があります。

```json:role-arnに設定したロールの信頼関係
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::{credentialsにdefaultで設定されているIAMユーザのAWSアカウントID}:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
>
CLI は、sts:AssumeRole オペレーションをバックグラウンドで使用してこれを達成します。これらの一時的な認証情報は、次にリクエストされた CLI コマンドを実行するために使用されます。指定されたロールには、リクエストされた CLI コマンドを実行できる IAM アクセス許可ポリシーがアタッチされている必要があります。

以下のコマンドが発行されているイメージになります。

```
$ aws sts assume-role \
    --role-arn arn:aws:iam::{スイッチ先のAWSアカウントID}:role/{ロール名} \
    --role-session-name {botocoreが発行するセッション名}
```


[assume-role — AWS CLI 1.18.211 Command Reference](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/assume-role.html)


## 参考記事
- [AWS CLI 認証情報ヘルパーを使用して AWS CodeCommit リポジトリへの HTTPS 接続をセットアップする手順](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-https-unixes.html)