AWS SSOでマルチアカウント環境へのログインを楽にする (ビルトインAWS SSO Directoryを使う場合)

昨今のベストプラクティスとして、1企業につき1AWSアカウントではなく、セキュリティ/リソース/コスト管理の分離のためにマルチアカウント戦略を取ることが推奨されるようになってきました。一般的な例としては、情シス管理の共有システム用アカウント + SOCのためのログ集約&監査アカウント + 各事業部/サービス用アカウントであったり、マイクロサービスを採用している場合はマイクロサービスごとのアカウント分離などが考えられます。そうすると、1人の利用者が複数のIAMユーザを持つことになりユーザを払い出す側も利用する側も運用が煩雑になってしまいますし、キーの流出などのリスクも大きくなります。こういった場合はActive Directory + ADFSを使ったフェデレーションによってユーザ管理の一元化とシングルサインオンを実現していましたが、ADFSの運用や難しいクレームルールの記述が必要でした。そこで大変便利に使えるのが、2017/12にデビューしたAWS SSOサービスです。ADFSを立てたりクレームルールを書くことなく、簡単にマルチアカウントでのユーザ管理とシングルサインオンの設定ができるようになります。ユーザーにとってもマルチアカウントへのログインが簡単になりますし、ポータル画面からAWS CLI/API実行のためのテンポラリクレデンシャル(Access Key/Secret Access Key/Token)が取得できるのもポイントが高いです。またSAML2.0を利用できるAWS以外のアプリケーションへのシングルサインオン(Salesforce、BOX、Office 365など)にも利用可能です。

ユーザのディレクトリとしては、ビルトインのAWS SSO DirectoryまたはActive Directoryを利用できます。今回はビルトインのディレクトリを使用してSSOを構成しています。

# 前提条件
* AWS SSOはAWS Organizationsと連携しているため、ログイン対象のAWSアカウントはAWS Organizationsの同じマスターアカウント配下に属している必要があります。もしOrganizationsの外で作成されたアカウントを含める場合は、自身のOrganizationに招待しておく必要があります。(その場合は旧Consolidated Billingと同じ考え方で請求もマスターアカウントに一本化されるため注意してください)

# SSOの対象となるアカウントの確認
ここからの設定は全てAWS Organizationsのマスターアカウントで実施します。
今回はテスト用に、AWS Organizationsから2つの子アカウントを作成済みです。
<img width="851" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/f7d9aa30-d801-f93e-5001-c9c6b4b1e4ea.png">



AWS Organizationsの有効化と子アカウントの作成は以下の参考リンクなどを参考に実施しておきます。(めちゃ簡単です。)
[AWS Organizationsの新規設定と確認](https://qiita.com/tamo_breaker/items/854c94379e4e8c8711e4)

# AWS SSOの設定

## AWS SSOの有効化
マネジメントコンソールから、AWS Single Sign Onのコンソールへ移動します。
(AWS SSOは2019/2/11時点でバージニア北部リージョンにのみエンドポイントがあるため設定はバージニア北部リージョンで実施します。)

"AWS SSOを有効にする"をクリックします。
<img width="837" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/15440b2d-53f9-e405-6ebd-b4a8cf267ab6.png">

## ユーザの追加
ダッシュボードが表示されるので、"ディレクトリの管理"をクリックします。
<img width="834" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/8a390344-3e73-572c-fedf-5e20f65ab02f.png">

"ユーザの追加"をクリックします。
<img width="846" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/c0d717b3-a2c9-9fd8-421c-f7994bbba1e7.png">

Eメールアドレスと名、性、表示名を入力して"次のステップ：グループ"をクリックします。
"パスワード"の設定において"パスワードの設定手順が記載されたEメールをユーザに送信します"を選択するとユーザ作成完了と同時にユーザにInvitationメール(パスワード設定用リンク)が送られます。
"ユーザーと共有することのできる一時的なパスワードを生成します"を選択した場合にはメールは自動送信されずにポータルURLと仮パスワードが設定コンソールに表示されるため、権限設定の完了後などに手動でユーザに連絡できます。
<img width="772" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/59798ae1-3682-7b54-dac9-bbfaca2d5899.png">

## グループの作成とユーザの追加

"グループの作成"をクリックします。
<img width="830" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/b4b4a434-7500-972f-940e-a4e15460bbd5.png">

グループ名と説明(オプション)を入力して"作成"をクリックします。
<img width="528" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/c2db5b01-223d-868d-cf25-d7f9d1ea8bc7.png">

作成されたグループにチェックを入れ、 "ユーザの追加"をクリックします。
<img width="640" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/f8846115-1afb-591e-7487-24276c4a1b9e.png">

## ユーザのパスワード変更
[ユーザの追加](#ユーザの追加)において、"パスワードの設定手順が記載されたEメールをユーザに送信します"を選択した場合、ユーザのメールアドレス宛に画像左のようなメールが届きます。(送信元:"no-reply@login.awsapps.com"、タイトル:"Invitation to join AWS Single Sign-On")。Accept Invitation"をクリックすると画像右のようにブラウザでパスワード設定画面が表示されるためパスワードを設定するとユーザの作成は完了し、ユーザーポータルに自動的にログインします。(この時点ではログインできるAWSアカウントはありません。)
<img width="782" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/dcad6dc8-22ea-d00e-8ae6-b7014d660f94.png">

[ユーザの追加](#ユーザの追加)において、"ユーザーと共有することのできる一時的なパスワードを生成します"を選択している場合は以下の画面が表示され、権限設定などの完了後に手動でログインポータルURLと仮パスワードを連絡することができます。
<img width="844" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/ee1c6970-bab1-c8da-a035-b4a18ee9df76.png">

## ユーザ/グループのAWSアカウントへのアクセス設定
AWS SSOのダッシュボードから"AWS アカウントへのSSOアクセスの管理"をクリックします。
<img width="841" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/8cb0458a-be56-7e08-b522-cf39561847e4.png">

先ほど作成したユーザ/グループに対してログインを許可したいアカウントにチェックを入れ、"ユーザの割り当て"をクリックします。
<img width="1005" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/ad414c21-90e4-8786-a0aa-80ac98d34a29.png">

"グループ"タブに切り替え、作成したグループを選択して"次のステップ:アクセス権限セット"をクリックします。
<img width="605" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/845a58f5-745a-3fec-9cac-703a54ba474d.png">

"アクセス権限セットを作成"をクリックします。"アクセス権限セット"はIAMポリシーのセットであり、アクセスを許可されたアカウントにおいてSSOユーザが行使できる権限のセットになります。実体としては、アクセス権限セットと同じ権限を持つIAM Roleがログインを許可したアカウントに自動的に作成され、SSOのユーザはマネコン利用時にこのRoleを自動的にAssumeRoleします。このRoleはService-Linked RoleというAWSサービスが作成するRoleで、ユーザによって編集することができません。つまり、ログイン先で勝手に自分のRoleを書き換えて権限を拡張することを防ぐことができます。
<img width="641" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/6a196e5b-6a2e-a281-a8b3-23c573090e59.png">

アクセス権限セットに含めるポリシーには既存のAWS管理ポリシーを使うことも、自分でカスタムのポリシーを作成することもできます。今回はテストのため"AdninistratorAccess"管理ポリシーを選択し、"作成"をクリックします。

<img width="739" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/e97d0f46-fc28-1a7c-c08d-cbda93602735.png">

作成されたアクセス権限セットを選択して"完了"をクリックします。
<img width="764" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/92aa9c6d-ed33-d620-ee29-374b1113b514.png">

数十秒で設定が完了します。
<img width="834" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/2e86975d-e2d6-2caf-6e61-0c0d05cff023.png">

各アカウントの詳細ページを表示すると、どのユーザ/グループに対してどのアクセス権限セットが割り当てられているかが確認できます。
<img width="877" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/61d3d152-ec13-c797-4fed-f410521a3518.png">


# AWS SSOユーザポータルヘログインとAWSコンソール/CLIの利用

## ユーザポータルへのログイン
"AWS SSOコンソール" > "ディレクトリ"にユーザーポータルURLが表示されていますのでこれをユーザーに案内します。https://[x-xxxxxxxxxx].awsapps.com/start というURLになっており[]の部分はカスタマイズできます。
<img width="877" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/88c23f40-9b9b-79d6-71ee-f2663663be5e.png">

ユーザーポータルURLにアクセスするとユーザ名とパスワードが求められます。ユーザ名にはユーザのメールアドレスを入力します。
<img width="532" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/4bfc52e7-f5d4-c347-46b3-794aa533e215.png">

サインインすると、ユーザーポータルが表示されます。SSO対象のアプリケーションとしてAWSアカウントが表示されています。これをクリックして展開します。
<img width="877" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/f3b04bbf-8193-7d17-8c1e-07e0c3e9764d.png">

ログイン可能なアカウント一覧が表示されます。下の画像では3つのアカウントがリストされており、さらに一番上のアカウントのみクリックして展開した状態です。
<img width="789" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/4deccb7f-8db5-0f3a-87ad-0afa456ea734.png">


上記で"Management console"をクリックするとそのアカウントのマネジメントコンソールにログインすることができます。"AWSReservedSSO_AdministratorAccess_xxxxxxx..."というAWS SSOによって作成されたService-Linked Roleの権限でログインしています。
<img width="1409" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/7a2d5fd0-92db-9231-638c-fe8e6432f850.png">

また、"Command line or programatic access"の方をクリックするとCLI/API利用に使えるテンポラリーのクレデンシャル(デフォルト期限1時間)が発行されます。例えば環境変数をターミナルに貼り付ければそのままAWS CLIを利用して環境を操作することができます。従来SAMLを使ったSSOの場合、CLIの利用が手間でしたがこれはとても便利です。一時的なクレデンシャルなので万が一漏洩しても期限が切れていれば使用できません。
<img width="534" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/d7a46855-aa5b-16f4-3a1c-deb0a73e292b.png">

# まとめ
AWS SSOとビルトインのDirectoryを使用してマルチアカウント環境のSSOを構築しました。フルマネージドで構築もこれだけなので、マルチアカウントで運用している場合はIAMユーザ払い出しから切り替えれば運用者/利用者双方にメリットが大きいと思います。また以下のようなケースでは、ビルトインのDirectoryではなくActive Directoryに接続した方が良い場合もありそうです。その場合の設定方法は後日記載予定です。

* 既存のAWS上またはオンプレミスのActive Directoryユーザ、グループでログインしたい場合
* パスワードポリシーを自由に設定したい場合
(AWS SSOディレクトリのパスワードポリシーは以下に設定されており、現在は変更できない模様)
    * 8 ～ 64 文字
    * 次の 4 つのうち 4 つを含む
      * 英小文字
      * 英大文字
      * 数字
      * 特殊文字
* 大量のユーザをホストする場合(デフォルトリミットは500ユーザ、100グループ)
AWS SSOの制限 :https://docs.aws.amazon.com/singlesignon/latest/userguide/limits.html

# おまけ

## セッション期間を変更する
ログインセッションの期限を変更するには、アクセス権限セットの詳細ページで"編集"をクリックします。
<img width="1016" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/79d9411f-01a5-b036-44d2-1848c011470b.png">

"セッション期間"設定を変更すればOKです。最小1時間、最大12時間まで設定可能です。
https://docs.aws.amazon.com/singlesignon/latest/userguide/howtosessionduration.html
<img width="1036" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/345960/c466a85c-d4b7-da1c-a7b0-c67158651305.png">

## 多要素認証の設定
現在メールによる多要素認証を設定できます。設定方法は[こちら](https://qiita.com/f-daiki/items/156e36a1a4bef15e8cff)。