AWS CLIに認証情報を渡す方法アレコレとその優先順位とか確認方法とか

AWS CLIでは、認証情報を渡すことでリソースを扱うIAMユーザーを特定します。
また、大抵のリソースはリージョンの指定も必要です。
うまく設定できてなかったら、違うアカウントやリージョンのリソースが更新されたりしてしまいます。

認証情報とリージョンを渡す方法はいくつかあるので、その方法や優先順位、確認方法をまとめてみます。

## 認証情報の渡し方と優先順位
今回は、以下の3つの情報の渡し方に絞って書いていこうと思います。
STSを使用したときのセッショントークンや、CLIの出力形式なんかもありますが、ここでは触れません。

- アクセスキーID
- シークレットアクセスキー
- リージョン

で、その認証情報の渡し方と優先順位ですが、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html#config-settings-and-precedence)に書いてあります。

1. コマンドラインオプション
2. 環境変数
3. CLI認証ファイル
4. CLI設定ファイル
5. コンテナ認証情報
6. インスタンスプロファイル認証情報

### コマンドラインオプション
コマンドラインのオプション`--profile`で指定します。
`--profile`で指定するプロファイル名は、あらかじめ以下のコマンドで設定しておきます。

```
$ aws configure --profile [プロファイル名]
```

実行すると各情報の入力を求められます。
アクセスキーID,シークレットアクセスキー,リージョン名(,出力形式)を一つの塊として扱います。

```
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]:
Default output format [None]:
```

また、プロファイルを指定してもリージョンは`--region`で上書きできます。
しかし、アクセスキーIDとシークレットアクセスキーを上書きするオプションはありません。

### 環境変数
以下の項目を設定できます。

- `AWS_ACCESS_KEY_ID` : アクセスキーID
- `AWS_SECRET_ACCESS_KEY` : シークレットアクセスキー
- `AWS_DEFAULT_PROFILE` : デフォルトプロファイル名
- `AWS_DEFAULT_REGION` : デフォルトリージョン

ちなみに、`AWS_ACCESS_KEY_ID`,`AWS_SECRET_ACCESS_KEY`は、`AWS_DEFAULT_PROFILE`よりも優先順位が高いです。

### CLI認証ファイル / CLI設定ファイル
公式ドキュメントでは項目が分かれていますが、実質セットと考えていいと思います。

`aws configure`コマンドでAWS CLIの設定を行なったときに設定内容が保存されるファイルたちですが、
CLI認証ファイルにはアクセスキーIDとシークレットアクセスキーが、
CLI設定ファイルにはデフォルトリージョン(と出力形式)が保存されます。

コマンドラインオプションのところで書いたように、`--profile`オプションを指定すれば任意のプロファイル名で設定を保存できます。その場合は、コマンド実行時にも`--profile`オプションが必要です。

一方で、`--profile`オプションを設定しなければ、デフォルトのプロファイルとして保存されます。その場合は、コマンド実行時にも`--profile`オプションは不要です。
ただし、デフォルトのプロファイルは`AWS_DEFAULT_PROFILE`で上書き可能です。

### コンテナ認証情報
ECSタスクに紐づけたIAMロールが持つ認証情報です。
IAMロールにはリージョンの情報が無いので、コマンドラインオプション`--region`か環境変数`AWS_DEFAULT_REGION`,もしくはCLI設定ファイルでの指定が必要です。

### インスタンスプロファイル認証情報
EC2インスタンスに紐づけたIAMロールが持つ認証情報です。
コンテナ認証情報と同様、リージョンの指定が別途必要です。

## 認証情報の確認方法
どの認証情報を使っているのか分からなくなったら、確認してみましょう。
以下のコマンドで確認できます。

```
$ aws configure list
```

### コマンドラインオプション
```
$ aws configure list --profile example
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                  example           manual    --profile
access_key     ****************ABCD shared-credentials-file
secret_key     ****************ABCD shared-credentials-file
    region                us-west-2      config-file    ~/.aws/config
```

### 環境変数
```
$ AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXABCD AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXABCD AWS_DEFAULT_REGION=us-west-2 aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************ABCD              env
secret_key     ****************ABCD              env
    region                us-west-2              env    AWS_DEFAULT_REGION
```

### CLI認証ファイル / CLI設定ファイル
```
% aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************ABCD shared-credentials-file
secret_key     ****************ABCD shared-credentials-file
    region           ap-northeast-1      config-file    ~/.aws/config
```

### コンテナ認証情報 / インスタンスプロファイル認証情報
```
$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************6A3Q         iam-role    
secret_key     ****************YFRw         iam-role    
    region                <not set>             None    None
```

## 優先順位を利用する例
めちゃくちゃピンポイントですが、実際に出くわした例を参考までに。

### 他アカウントに対してAWS SAMでアプリケーションをデプロイする
AWS STSでAssumeRoleを行い、他のアカウントに対してAWS SAMでアプリケーションをデプロイする場合です。

基本的にはAWS CLIは自身のアカウントの操作をしたいので、CLI認証/設定ファイルやインスタンスプロファイルの認証情報を利用しますが、この場合は一時的に認証情報を上書きする必要があります。
このような場合は、環境変数に認証情報を設定して実行します。

```
$ AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXABCD AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXABCD AWS_SESSION_TOKEN=XXXXXXXXXXXXXXXXABCD aws cloudformation package ...(略)
```

### CircleCIでDynamoDB localを操作する
CircleCIのコンソールでAWSの認証情報を設定できますが、DynamoDB localを操作するときだけダミーの認証情報を使いたい、という場合。

```.circleci/config.yml
version: 2
jobs:
  example:
    docker:
      (略)
      - image: amazon/dynamodb-local
        ports:
          - 8000:8000
          
    steps:
      (略)
      - run:
          name: Create DynamoDB Table
          command: AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXABCD AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXABCD  AWS_DEFAULT_REGION=ap-northeast-1 aws --endpoint-url http://127.0.0.1:8000 dynamodb create-table --table-name example-table ...(略)
```