GoogleアカウントでSSOして複数AWSアカウントへスイッチング

エンタメ系企業の社内もろもろを担当しているakibinです。

最近は[Chai](https://open.spotify.com/track/7pOkuWv1jnfvKgl6oVstg9?si=291e77312d96441c)にハマってます。めにめにめに赤ちゃんチェケラ。

# やりたいこと
これをやりたいと思います。（最近は[IAMロールをお面に例えること](https://dev.classmethod.jp/articles/iam-role-passrole-assumerole/)がスタンダードなようです）
![スクリーンショット 2021-07-02 8.35.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/1de1244a-7c67-cd03-8846-00e0366a032e.png)


これを実現したかった理由。

* セキュリティを担保（MFA）した状態でログインを簡素化したい
* 複数AWSアカウントを切り替えるのがめんどくさい
* 複数AWSアカウントに作成したIAMユーザの管理がめんどくさい
* **極力アクセスキーを使用したくない**

AWSのセキュリティインシデントはアクセスキー漏洩が圧倒的に多いようで、AWSの[IAMユーザのアクセスキーの管理](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html)にも、アクセスキーではなくIAMロールで代用すると明記されています。
なので、当初はAWSアカウントのセキュリティ強化で色々考えていたのですが、結果セキュリティ強化と利便性の兼ね備えた、IAM王構成が実現できました。
この構成だとIAMユーザとIAMグループは使用せず、IAMロールとIAMポリシーのみで複数AWSアカウントへ簡単にアクセス、またアクセスキーを使用せず複数AWSアカウントへCLIでのアクセスが実現が可能です。

# 項目
## 管理コンソール
* Googleアカウント（MFA）で踏み台となるAWSアカウントへSSO
* 踏み台AWSアカウントから他のAWSアカウントへスイッチング

## CLI
* CLIからGoogleアカウント（MFA）で踏み台AWSアカウントへログイン
* CLIで踏み台AWSアカウントから他のAWSアカウントへスイッチング

# 管理コンソール：Googleアカウント（MFA）で踏み台となるAWSアカウントへSSO
こちらの設定方法はAWSの公式ブログ [G Suite アカウントを用いた AWS へのシングルサインオン](https://aws.amazon.com/jp/blogs/startup/techblog-saml-gsuite/) を参照させてもらいました。そのまんま手順通り設定すればGoogleアカウントでSSOが可能になります。

![スクリーンショット 2021-06-30 15.38.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/7848b5d1-2350-92ac-f044-5cf8997cae99.png)

作業中の注意点として、踏み台AWSアカウントに設定するIAMロールの最大セッション時間と、Googleアカウント側のユーザーのカスタム属性（Seesion Duration）の値は合わせてください。

**IAMロールの最大セッション時間**
![スクリーンショット 2021-07-01 16.39.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/01386051-b66c-b5ad-e87e-2db9613a77e8.png)

**Googleアカウント側のユーザーのカスタム属性（Seesion Duration）の値**
![スクリーンショット 2021-07-01 16.42.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/a1b7be0c-f05c-eb61-27aa-57e5bbc9288d.png)

Googleアカウントで踏み台AWSアカウントへSSOが可能となったら、次に他のAWSアカウントへスイッチングする設定を行います。

# 管理コンソール：踏み台AWSアカウントから他のAWSアカウントへスイッチング
スイッチ先のAWSアカウントへ、踏み台AWSアカウントからスイッチを許可するIAMロールを作成します。
#### 1. スイッチ先のAWSアカウントのIAMページ→[ロール]から[ロールの作成]をクリック
![スクリーンショット 2021-06-30 15.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/dde8a54f-405b-b6ae-70bb-80a49a0a5375.png)

#### 2. [別のAWSアカウント]を選択、踏み台AWSアカウントの[アカウントID]を入力して次のステップへ
MFAはGoogleアカウントで行われているのでチェック不要です。
![スクリーンショット 2021-06-30 16.00.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/d843161e-21f9-d64f-0621-e26016995558.png)

#### 3. 踏み台アカウントに許可するアクセス権限（IAMポリシー）を選択
今回は読み込みのみ（ReadAccessOnly）の権限を付与しました。
![スクリーンショット 2021-06-30 16.03.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/52b66d15-7456-4fda-3aa7-7036cca36fd9.png)

#### 4. 任意でタグを付ける
今回はつけてませんが、Nameとかでわかりやすくタグ付けするのもありと思います。
![スクリーンショット 2021-06-30 16.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/72ccaffa-8772-a6b7-9874-c2879caf675a.png)

#### 5. ロール名とロール説明（任意）を入れてロールを作成
![スクリーンショット 2021-06-30 16.10.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/99ef486a-48a6-b2ff-1f58-515430e28e12.png)

#### 6. 作成したIAMロールを開く
![スクリーンショット 2021-06-30 16.18.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/5b9eeaa1-96da-b139-9f17-ca79f793a7cf.png)

#### 7. [信頼関係]タブを開き、［信頼関係の編集］を開く
![スクリーンショット 2021-06-30 16.22.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/784d7b14-85d7-88eb-7bfe-c200880a4aec.png)

#### 8. "Principal"に踏み台AWSアカウントへのSSO設定時に作成したIAMロールのarnを入れる
GoogleアカウントからSSO設定時に作成した踏み台AWSアカウントのIAMロールのarn（Amazon リソースネーム）をコピーして...
※踏み台AWSアカウントのIAMロール
![スクリーンショット 2021-06-30 16.28.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/17cc153f-6687-1c6c-0800-722e837ceb33.png)

..."Principal"の"AWS"箇所にペーストする。[信頼ポリシーの更新]をクリック
![スクリーンショット 2021-06-30 16.32.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/d27bae27-3732-688d-51c8-c1100d0f47c9.png)

踏み台AWSアカウントの特定のIAMロールからのスイッチがこれで許可されます。

IAMユーザでのスイッチングであればこれで設定完了なのですが、今回はGoogleアカウントからSSOする踏み台AWSアカウントのIAMロールからスイッチするのでもう1作業あります。

それが、
**踏み台AWSアカウントにスイッチ先AWSアカウントのIAMロールへのスイッチを許可するIAMポリシーを作成して、踏み台AWSアカウントのSSO用IAMロールにアタッチする**
です。

#### 9. 先程スイッチ先AWSアカウントに作成したIAMロール（from_fumidai）のarnをコピーしておく
![スクリーンショット 2021-06-30 16.47.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/b9fe6cf6-04ae-18b0-a443-bde73ee9bc1a.png)


#### 10. 踏み台AWSアカウントのIAMページから[ポリシー]を開き［ポリシーの作成］
![スクリーンショット 2021-06-30 16.43.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/6e15e6bb-519b-4b14-8f80-ac3eb218a27a.png)

#### 11. [JSON]タブを開き、以下をコピペ。"Resource"には先程コピーしたスイッチ先AWSアカウントのIAMロールのarnを入れる

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::＊＊＊＊＊＊＊＊＊＊＊＊:role/from_fumidai"
        }
    ]
}
```

![スクリーンショット 2021-06-30 16.52.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/9ac6b8eb-1a1f-21df-4f40-ef518cc5caa4.png)

#### 12. 任意でタグを入れる
今回はなし
![スクリーンショット 2021-06-30 18.02.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/a9623ffb-9f36-a266-0839-3f9bf8876b3f.png)

#### 13. [ポリシー名]と［説明］（任意）を入れて[ポリシーの作成]
![スクリーンショット 2021-06-30 18.04.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/c72fcffa-a443-6ecc-8da1-afb68aef717b.png)

#### 14. 踏み台AWSアカウントへSSOするためのIAMロールを開き、作成したIAMポリシーをアタッチするため、［ポリシーをアタッチします］をクリック
![スクリーンショット 2021-06-30 18.24.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/347fa88a-f0ae-879f-d367-4c34070a0a1d.png)

#### 15. 作成したIAMポリシーを選択して［ポリシーをアタッチ］
![スクリーンショット 2021-06-30 18.26.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/b562d464-b195-fd14-1e14-bb6c591ea566.png)

IAMポリシーがIAMロールにアタッチされます。
![スクリーンショット 2021-06-30 18.28.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/6b4c40dc-f702-849f-faba-c5ea06cc4591.png)

では、実際に踏み台AWSアカウントにSSOして、スイッチ先AWSアカウントにスイッチングしてみます。

#### 16. スイッチ先AWSアカウントのスイッチ用IAMロールのスイッチング用URLをコピーしておく
![スクリーンショット 2021-06-30 18.34.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/f730428a-e9ec-c88a-0703-6c84177e102e.png)

#### 17. Googleアカウントから踏み台AWSアカウントへSSO
![スクリーンショット 2021-06-30 15.38.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/636aabb3-1380-c9e4-047f-1ab82965dcb3.png)
↓↓↓↓↓
![スクリーンショット 2021-06-30 18.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/9c8124a6-1f5a-25bb-096c-4e99b4dd5c7d.png)

#### 18. 先程コピーしたスイッチング用URLへアクセス。色を決めて[ロールの切り替え]
![スクリーンショット 2021-06-30 18.30.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/caf08f7d-f669-b466-9d98-041853e47454.png)

これでSSOからの他のAWSアカウントへスイッチングができました！
![スクリーンショット 2021-06-30 18.43.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/7d54c659-dafa-deb0-2e5d-7b42b40e3cd3.png)

ちなみにスイッチングの履歴はブラウザに保存され、以下で履歴を確認してスイッチングが可能です。
![スクリーンショット 2021-07-02 8.50.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/aa923bd5-d89c-1523-14e2-c9a1b254c9c4.png)
キャッシュクリアすると履歴が消えるので、その場合はスイッチ先AWSアカウントのスイッチ用IAMロールのスイッチング用URLから再度スイッチングしてください。

次はCLIでのGoogleアカウントでのログインと、他のAWSアカウントへのスイッチング方法です。

# CLIからGoogleアカウント（MFA）で踏み台AWSアカウントへログイン
aws-google-auth (CLIによるSAML認証ツール)を使用してログインしていきます。

【今回の条件】
* macOS 10.15.6
* AWS CLIインストール済み

#### 1. Macでpipを使えるようにする
以下の記事を参照させていただきました！
[【Python】macOSでpipを使えるようにする](https://qiita.com/ohbashunsuke/items/e7c673db606a6dced8a6)

#### 2. pipコマンドでaws-google-authをインストール
```bash
$ pip install aws-google-auth
```
#### 3. ~/.aws/configに設定値を入力
```
[profile sts]
region = xx-xxxxxx-x
google_config.ask_role = False
google_config.keyring = False
google_config.duration = 43200
google_config.google_idp_id = xxxxx(Googleアカウントのidp_id)
google_config.role_arn = xxxxx
google_config.google_sp_id = xxxxx(Googleアカウントのsp_id)
google_config.u2f_disabled = False
google_config.google_username = xxxxx
```

* region<br>アクセスするリージョンを入力
* google_config.duration<br>**管理コンソール：Googleアカウント（MFA）で踏み台となるAWSアカウントへSSO**で設定した、踏み台AWSアカウントに設定したIAMロールの最大セッション時間と、Googleアカウント側のユーザーのカスタム属性（Seesion Duration）の値と合わせてください。
* idp_idとsp_id<br>AWSマネジメントコンソールへのリンクURLから取得可能です
![スクリーンショット 2021-07-01 16.25.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/c32e48fb-fddc-d19c-ba6a-ed360f6e56d2.png)
* google_config.role_arn<br>踏み台AWSに作成したSSO用のIAMロールのarn
* google_config.google_username<br>GoogleアカウントのID

#### aws-google-authコマンドを実行
```bash
$ aws-google-auth
Google Password: # Googleアカウントのパスワードを入力
# MFA認証。今回の場合は私のスマホでログインを許可しました。SMSやAuthenticaterを使用している場合はTokenを求められるので、それを入れてEnter
Check your phone - after you have confirmed response press ENTER to continue. 
```
以下のようなメッセージが出れば認証完了です。

```
Assuming arn:aws:iam::************:role/ima-role_name
Credentials Expiration: 2021-07-02 04:53:35+09:00
```

#### 5. プロファイルの切り替え
```
$ export AWS_DEFAULT_PROFILE=sts
```

これでOK！IAMユーザの一覧でも見てみましょう。

```
$ aws iam list-users
```
当然お見せできませんが、一覧表示されました！

で、AWS管理コンソールでアクセスキーは発行していませんが、実際には`~/.aws/credentials`を見るとアクセスキーが発行されていました。
ただ、これはGoogleアカウントのID/PWとMFAをパスしないと使用できないので、セキュアですね。

# CLIで踏み台AWSアカウントから他のAWSアカウントへスイッチ
では次に、CLIでログインした踏み台AWSアカウンtのから他のAWSアカウントへスイッチする方法です。

#### 1． スイッチ先のAWSアカウントに作成したIAMロールのarnをコピー
![スクリーンショット 2021-07-01 18.34.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/39310a99-5501-2238-f8c8-aa223f5d9e8f.png)


#### 2. `~/.aws/config`にスイッチ先のAWSアカウントのIAMロールのプロファイルを作成
```
[profile from_fumidai]
role_arn = arn:aws:iam::************:role/from_fumidai
source_profile = sts
```
* role_arn<br>先程コピーしたarn
* source_profile<br>Googleアカウントでログイン用のプロファイルの名前

Googleアカウントでログイン用のプロファイルを元（source）にして、from_fumidaiにアクセスする感じです。

#### 3. プロファイルの切り替え
```
$ export AWS_DEFAULT_PROFILE=from_fumidai
```

これでOK！もう一度IAMユーザの一覧でも見てみましょう。

```
$ aws iam list-users
```
なんと！IAM王が表示されました！！
![スクリーンショット 2021-07-01 18.44.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504009/7031f83f-63e9-2d60-2723-df15fbe71355.png)

IAMロールになるというか、IAMロールを使ってアクセスしてる感じなんですが、この子マチガエテルヨ…

# おまけ：どうしてもプログラム用にアクセスキーを使いたい場合…
というわけで、ユーザに関してはGoogleアカウントでのSSOとスイッチングで複数AWSアカウントにアクセス可能になりました。
CLIも上記のような感じでアクセスキー発行なしでアクセス可能です。

また、SDKなどプログラム用のアクセス制御について、AWSのベストプラクティスでもIAMロールを使用することが基本となります。
が、どうしてもアクセスキーを使用したいシーンもあると思います。
その場合は、以下を考慮してもらえるといいと思います。

* 専用のIAMユーザを作成してアクセスキーを発行<br>ユーザ用のIAMユーザにアクセスキーを発行しない
* プログラムごとに発行<br>複数プログラムで共有しない
* 担当者をタグ付けする<br>用途や担当者を明確にするためタグ付けする
* **IAMポリシーでアクセスできるリソースを制限、またIP制限でアクセスキー自体を外部環境から使用できなくする**

たとえば、特定のIPアドレス以外からの使用を制限する場合は以下のような感じです。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "***.***.***.***/32"
                    ]
                }
            },
            "Resource": "*"
        }
    ]
}
```
これにより、万が一漏洩したとしても、そのアクセスキーでは何も出来ないです。
これぐらい、アクセスキーの取り扱いは注意したほうが良いと思います。

おまけ以上です！

# こちらもチェックお願いします！
[Twitterアカウント](https://twitter.com/akibinmusic)
[Youtubeチャンネル](https://www.youtube.com/channel/UC-JOpwEnJn3gCrUA4NdCYgg)