クロスアカウントで認証情報レポートを取得

# はじめに

AWSアカウントでマルチアカウントの導入が進んでいくと監査や管理を目的として、１つのAWSアカウント(管理アカウント)から複数のメンバーアカウントへクロスアカウントアクセスが必要になってきます。

当記事では自動化までは行わずに管理アカウントからIAMの認証情報レポートをクロスアカウントアクセスで生成、取得、結合をローカルからAWS CLIを利用しIAMユーザーの棚卸しを行います。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_getting-report.html

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-role.html

## 前提条件

- [当記事](https://qiita.com/daisukeArk/items/e6b4a48e7e6062ff1b64)のように利用するIAMユーザーのMFA保護が有効となっている
- クロスアカウントアクセスを行うためのIAMロールがメンバーアカウントに作成されている必要がある

## Require

- AWS CLI
- ローカル端末でクロスアカウントで実行するため、以下が必要
  - 管理アカウントのIAMユーザーの認証情報
  - メンバーアカウントのAWS CLIプロファイルの設定

## 流れ

- `~/.aws/config`の設定
- 環境変数へ一時認証情報を払い出す
- 認証情報レポートの生成
- 認証情報レポートの取得
- 認証情報レポートの結合

## `~/.aws/config`の設定

事前にクロスアカウントアクセスを行うためにプロファイルの設定を行います。
クロスアカウントアクセスを行うためのIAMロールがメンバーアカウントに作成されている必要があります。（当記事では手順を割愛しています）

```bash:~/.aws/config
[profile credential-report-account-a]
region = us-east-1
output = json
role_arn = arn:aws:iam::123456789012:role/credential-report-role
credential_source = Environment

[profile credential-report-account-b]
region = us-east-1
output = json
role_arn = arn:aws:iam::123456789012:role/credential-report-role
credential_source = Environment
```

## 環境変数へ一時認証情報を払い出す

以下の記事を参考に管理アカウントのMFA保護されたIAMユーザーの一時認証情報を環境変数へ設定してください。

https://qiita.com/daisukeArk/items/e6b4a48e7e6062ff1b64

## 認証情報レポートの生成

### コード

```bash
#!/bin/bash

# --------------------------------------------------------------------------------
# 認証情報レポート生成
# --------------------------------------------------------------------------------

PROFILE_NAMES=(\
    "credential-report-account-a"\
    "credential-report-account-b"\
)

for profile_name in ${PROFILE_NAMES[@]}
do
    TARGET_AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --profile ${profile_name} --output text)

    aws iam generate-credential-report \
        --region us-east-1 \
        --profile ${profile_name} \
        --output text \
        --query '[State, Description]' | sed "s/^/${TARGET_AWS_ACCOUNT_ID}\t/"
done
```

## 認証情報レポートの取得

### コード

```bash
#!/bin/bash

# --------------------------------------------------------------------------------
# 認証情報レポート取得
# --------------------------------------------------------------------------------

PROFILE_NAMES=(\
    "credential-report-account-a"\
    "credential-report-account-b"\
)

for profile_name in ${PROFILE_NAMES[@]}
do
    TARGET_AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --profile ${profile_name} --output text)

    aws iam get-credential-report \
        --region us-east-1 \
        --profile ${profile_name} \
        --output text \
        --query 'Content' | base64 -D > ./dest/credential_report-${TARGET_AWS_ACCOUNT_ID}.csv

    if [ $? -eq 0 ]; then
        echo -e "${TARGET_AWS_ACCOUNT_ID}\t認証情報レポート取得"
    else
        echo -e "${TARGET_AWS_ACCOUNT_ID}\t認証情報レポート取得[NG]"
    fi
done
```

## 認証情報レポートの結合

最後に取得したCSVファイルをすべて結合します。

### コード

```bash
#!/bin/bash

# --------------------------------------------------------------------------------
# 認証情報レポート結合
# --------------------------------------------------------------------------------

# ヘッダ行削除、ソート
cat ./dest/credential_report-*.csv \
| sed '/user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated/d' \
| sort -t , -k1 -u \
| sed '1s/^/user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated\n/' > ./dest/all.csv
```