Google Workspace（旧称G Suite） アカウントのSAML認証を使ってAWS CLIの認証を行う

# はじめに

この記事は2020年のRevCommアドベントカレンダー9日目の記事です。8日目は[@marienplatz](https://qiita.com/marienplatz)さんの [【超入門】android(kotlin)アプリにユニットテストを導入する](https://qiita.com/marienplatz/items/29865b0520efc992dcdb) でした。

こんにちは、RevCommでインフラエンジニアをしている工藤です。

AWSでのアカウント管理、皆さんどのようにされていますか？
エンジニアを始めとした社内のAWS利用者の加入、離脱に合わせて、IAM Userの発行/失効作業をするのは、頻度が高くなってくると中々大変な作業になります。
また、MFA設定についてもIAM User側で設定してもらう必要があるかと思いますが、Google Workspaceアカウントを使うと、Google Workspace側のMFAを使用することができます。
そこで、今回はGoogle WorkspaceアカウントのSAML認証を使ってAWS CLIの認証を行う方法について、触れていきたいと思います。

Google Workspaceアカウントを使ったAWS マネジメントコンソールの認証については、AWSさんがTechBlogで丁寧に解説して下さっていますので、こちらが参考にされるのが良いかと思います。
https://aws.amazon.com/jp/blogs/startup/techblog-saml-gsuite/


# 前提
- 既にAWS マネジメントコンソールの認証ができている
- AWS CLI v1最新版のインストールが完了している

# 実施した環境
OS: macOS Catalina 10.15.7
AWS CLI: aws-cli/1.18.190 Python/3.7.4 Darwin/19.6.0 botocore/1.19.30

# 認証方法

今回は２つの方法を試してみます

1. aws-google-authというオープンソースツールを使用する方法
2. AWS CLIのAssumeRoleWithSAMLを使用する方法

## aws-google-authというオープンソースツールを使用する方法

https://github.com/cevoaustralia/aws-google-auth

###aws-google-authをインストールして、認証する

流れとしては、こんな感じになります。
1. aws-google-authをインストール
2. aws-google-authを実行
3. 対話式で初期入力 or aws config設定
4. AWS_PROFILE設定 or awscli profile指定実行

aws-google-authをインストール

```console
pip install aws-google-auth
```


aws-google-authを実行する

```console
aws-google-auth
```

初回アクセス時は、下記のように入力を求められます

```
Google username: sample@example.com
Google IDP ID: 123456789 ※1
Google SP ID: ABCDEFGH ※1
Google Password: 
```
※1 IDP IP、SP IDは、AWS マネジメントコンソールへのリンクURLから取得可能できます
![qiita_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194729/7815564c-d675-fe19-f252-ab0acfa11e5a.jpeg)


```
# 認証が通り、複数のIAM Roleを保持しているアカウントの場合、下記のように選択を求められます
# IAM Roleが１つの場合は聞かれない

Open the Google App, and tap 'Yes' on the prompt to sign in ...
[  1] arn:aws:iam::012345:role/dev-readonly
[  2] arn:aws:iam::012345:role/dev-administrator
[  3] arn:aws:iam::123456:role/prod-readonly
[  4] arn:aws:iam::123456:role/prod-administrator
Type the number (1 - 4) of the role to assume: 4
```

認証が通ると

```console
Assuming arn:aws:iam::012345:role/dev-readonly
Credentials Expiration: 2020-12-07 06:41:56+09:00
```

認証が通ると設定情報は、aws configに記載されます

profileを切り替えて認証したい場合は、下記のように `予め設定する` or `aws-google-auth -p [profile] ` で対話形式設定するのいずれかの方法があります

予め設定する場合は、google_config.durationの値は、該当するIAM Roleの最大セッション時間 & Google Workspace側のユーザーのカスタム属性（Seesion Duration）の値と合わせます

```config:~/.aws/config
[profile dev-readonly]
region = ap-northeast-1
google_config.ask_role = False
google_config.keyring = False
google_config.duration = 43200
google_config.google_idp_id = ABCDEFGH
google_config.google_sp_id = 123456789
google_config.u2f_disabled = False
google_config.google_username = sample@example.com
google_config.bg_response = None
google_config.role_arn = arn:aws:iam::012345:role/dev-readonly

[profile prod-readonly]
region = ap-northeast-1
google_config.ask_role = False
google_config.keyring = False
google_config.duration = 7200
google_config.google_idp_id = ABCDEFGH
google_config.google_sp_id = 123456789
google_config.u2f_disabled = False
google_config.google_username = sample@example.com
google_config.bg_response = None
google_config.role_arn = arn:aws:iam::0123456:role/prod-readonly
```

あとは、 export AWS_PROFILE or profileを指定して awscliのコマンドが実行できます

```console
export AWS_PROFILE=dev-readonly
aws s3 ls
```

```
aws s3 ls --profile dev-readonly
```

# AWS CLIのAssumeRoleWithSAMLを使用する方法

aws-cliの場合は、ブラウザも使う必要はありますが、SAML認証が可能です

流れとしては、こんな感じになります。
1. ブラウザでSSOのURLへアクセス
2. SAMLレスポンスをファイルに保存
3. assume-role-with-samlを実行
4. AWS_PROFILE設定 or awscli profile指定実行


ブラウザでSSOのURLへアクセスし、SAMLレスポンスを表示する

```
アクセス先のURLは、※1の画像にあるURLとなります。

SAMLレスポンスの取得方法は、下記のマニュアルを参照ください
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/troubleshoot_saml_view-saml-response.html#chrome
```

SAMLレスポンスをファイルに保存

```
任意の場所にSAMLレスポンスの内容を書き込んだファイルを保存します。
※SAMLレスポンスには有効期限がありますので、ご注意ください
```

assume-role-with-samlを実行する

実際にご自身の環境で実行する場合は、下記の項目を変更してください

-  `--role-arn`: SAML認証に使用しているRoleのarn
-  `principal-arn`: IAMで作成したIDプロバイダーのarn
-  `--duration-seconds`: SAML認証に使用しているRoleに指定している最大セッション時間
-  `"[dev-readonly]"`: 任意のプロファイル名に変更ください

コマンド見ていただくとわかりますが、認証情報を~/.aws/credentialsへ追記している為、2回目以降は該当のプロファイルを削除する必要があります

```console
aws sts assume-role-with-saml --role-arn arn:aws:iam::012345:role/dev-readonly --principal-arn arn:aws:iam::012345:saml-provider/GSuite --duration-seconds 43200 --saml-assertion file://samlresponse.log |
jq -r '.Credentials' | awk -F':' '
BEGIN {RS="," ; print "[dev-readonly]"}
/:/{ gsub(/"/, "", $2) }
/AccessKeyId/{print "aws_access_key_id =" $2}
/SecretAccessKey/{print "aws_secret_access_key =" $2}
/SessionToken/{ print "aws_session_token =" $2 }
/Expiration/{ printf "aws_session_expiration =%s:%s:%s",$2,$3,$4}
' | sed 's/"//g' | sed '/}/d' >> ~/.aws/credentials
```

あとは、 export AWS_PROFILE or profileを指定して awscliのコマンドが実行できます

```console
export AWS_PROFILE=dev-readonly
aws s3 ls
```

```
aws s3 ls --profile dev-readonly
```

# まとめ

今回は、２種類の方法を使用して、awscliのSAML認証をしてみました。
awscli v2では、AWS SSOでのを使用しての認証がサポートされているので、こちらも試してみたいと思います。

明日は [@series7](https://qiita.com/series7) さんの[GitHub Actionsを使ってServerless Frameworkチーム開発効率化](https://qiita.com/series7/items/1b77ff6e7f6f5304fea7)です。