こんにちは、生産性向上チームの五十嵐(@ganta0087)です。
今回はAWSアカウントの管理についてのお話です。
AWSアカウントをみなさんの組織ではどのように管理されているでしょうか?
シングルアカウントで運用していると、人やチームが増えて規模が大きくなってきたときに権限管理が中央集権的になり、管理者への負担が増大してしまいます。また、新規ユーザーの登録だけでなく、退職時の削除漏れにも注意が必要です。利用者側としても管理するパスワードが増えるのは避けたいです。
そこで、生産性向上チームではマルチアカウント構成によるシングルサインオン(以下SSO)とチームに委譲できる権限管理のしくみを作ることでこれらの問題を解決し、社内でAWSを活用しやすくなるようにしました。
サイボウズには社員のアカウント情報を管理しているActive Directory(Azure AD)があります。今回はそのAzure ADをIdentity Provider(以下IdP)として設定し、権限管理まわりのしくみを作った内容を紹介します。
SSOを使ったAWSアカウントの構成の概要
AWSアカウントの整理方法
AWSアカウントは目的ごとに作成しています。
具体的にはAWS Organizationsの組織単位(OU)を使って次のように整理しています。
- root
- admin
管理用アカウントを配置 - service
この下にプロダクトごとのOUを作成し、さらにその下へ環境ごと(Production、Stagingなど)のアカウントを配置 - professional
組織横断型チーム用のアカウントを配置 - business
その他業務用のアカウントを配置 - sandbox
実験用のアカウントを配置
- admin
また、AWS Organizationsを使うことで請求の一括化や、APIを使ったアカウントの作成も行っています。 AWS Organizationsの利用方法については、AWSの公式ドキュメントをご参照ください。
AWSアカウントへのログインの流れ
AWSアカウントへのログインの流れは次のようになっています。
まず、認証用AWSアカウントにAzure ADを経由してSSOでログインします。 この認証用アカウントには、Azure AD上のすべてのユーザーがログインできるようにしています。
これはAWS上の権限管理のためにAzure AD側のメンテナンスが不要となるよう、一律ログインさせてしまう方式をとっています。そのため、AWSにSSOでログインした直後の状態では何もできないようにしています。
目的のAWSアカウントにはAssumeRoleを利用して切り替えます。 認証用AWSアカウントに誰がどのアカウントに切り替えてよいかを定義しておき、それに基づいて切り替え可否を制御しています。この定義のマスターデータはkintoneに置き、CircleCI ServerのScheduled Buildsを使って自動同期することで簡単にメンテナンスができるようにしています。
認証用アカウントへのSSOの設定
ここでは手順のおおまかな流れを説明します。詳細な手順はMicrosoftの公式ドキュメントをご参照ください。
Azure AD側にAWSをアプリケーション登録
- Azure ADのエンタープライズアプリケーションにAWSを追加します。
- 追加したAWSアプリケーションにSAMLの設定を行います。
- フェデレーションメタデータXMLをダウンロードします。
AWS側にSAMLの設定を追加
- Azure AD連携用のIAM Userを作成します。(Azure ADからAWS上のIAM Roleを参照するため)
- IAMでProvider TypeがSAMLのIdentity Providerを追加し、Azure ADからダウンロードしたフェデレーションメタデータXMLをアップロードします。
- SAMLフェデレーション用のIAM Roleを作成します。(SSOの認証を通過したユーザーに割り当てられるロール)
先述したとおり、Azure ADにユーザーがあれば、誰でもAWSへ入れるようにしています。そのため、このロールに設定するポリシーは何もできないものを定義しておきます。内部的にはこのロールへAssumeRoleしており、ロールが参照できるように、
iam:ListRoles
だけは許可しています。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AssumeRoleWithSAMLBasePolicy", "Effect": "Allow", "Action": "iam:ListRoles", "Resource": "*" } ] }
Azure AD側にIAM Roleのマッピングを設定
- Azure AD連携用IAM Userのアクセスキーとシークレット使ってプロビジョニングの設定を行います。
- Azure AD上の全ユーザーが所属しているグループにSAMLフェデレーション用IAM Roleを割り当てます。
AWSアカウントの切り替え
先述したとおり、SSOで入った直後は何もできないため、別のAWSアカウントのロールへ切り替えられるようにします。
まず、切り替え先のAWSアカウントに対象となるロールを作成します。ロールの作成時に「別のAWSアカウント」を選択して、「アカウントID」に認証用AWSアカウントのIDを指定します。
そして、どのAWSアカウントのどのロールに切り替えてよいかのポリシーを、認証用AWSアカウントのSAMLフェデレーション用IAM Roleに付与していきます。
Azure AD上のuser-a
とuser-b
に対し、AWSアカウントIDが333333333333
のSampleRole
ロールに切り替えることを許可するには、次のように記述します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sts:AssumeRole" ], "Resource": "arn:aws:iam::333333333333:role/SampleRole", "Condition": { "StringLike": { "aws:userid": [ "*:user-a@*", "*:user-b@*" ] } } }, ... ] }
このポリシーを手動で編集していくのは大変なので、自動化します。
サイボウズではkintoneアプリで切り替え先のAWSアカウント+ロールとユーザーのマッピングを管理して、ポリシー反映のツールを定期実行することによって実現しています。
kintoneのレコードに自動生成したロール切り替えのURLへのリンクやARNも表示しており、利便性も高めています。
切り替え先のAWSアカウントが増えてくると、マネジメントコンソール上では5つまでしか履歴が保持されないため不便です。そういうときはAWS Extend Switch RolesというChrome拡張が便利です。後述する~/.aws/config
と同じ書式で切り替え設定を書くことができます。Chrome Syncにも対応しており、Chromeに設定したGoogleアカウントへ設定が保存されるのも便利です。
CLIの場合
マネジメントコンソールはWebブラウザで完結するため問題ありません。しかし、CLIからAWS CLIやAWS SDKを使って実装されたツールを利用したい場合は、Azure ADからAWSにSSOするためのしくみが必要となります。
AWSのナレッジセンターにその手順が掲載されています。
流れとしては次のようになります。
- WebブラウザでAzure ADからAWSにSSOする際のSAMLレスポンスを、Webブラウザの開発者ツールで取り出します。
- AWSのSTSのAPIにAssumeRoleWithSAMLがあるので、これにSAMLレスポンスを渡すことで、認証情報を得ます。
- 取得した認証情報を
~/.aws/credentials
に保存しておきます。
これを毎回手動で行うことは現実的ではないので、自動化するツールをOSSで実装しました。
assamではchromedpというChrome DevTools ProtocolでGoogle Chromeを操作するライブラリを利用し、Google Chromeの立ち上げからSAMLレスポンスの取得までを行っています。
assamの使い方
インストール
macOSの場合はHomebrewでインストールできます。
$ brew install cybozu/assam/assam
Linux/Windowsの場合は、最新のReleaseページから対応するアーカイブをダウンロードし、展開して得られるassam
コマンドをパスの通ったディレクトリに配置してください。
設定
次に、初期設定を行います。
$ assam --configure
- Azure Tenant ID
- Microsoft Azureポータルから確認できます。Azure Active Directoryからプロパティにある「ディレクトリID」がAzure Tenant IDです。
- App ID URI
- AWSのSAMLエンドポイントを指定します。Azure AD側に設定したものと同じものを設定します。通常は
https://signin.aws.amazon.com/saml
です。
- AWSのSAMLエンドポイントを指定します。Azure AD側に設定したものと同じものを設定します。通常は
- Default Session Duration Hours
- セッションの有効期限を設定します。1〜12時間の任意の時間を指定してください。
- Chrome User Data Dir
- Google Chromeのユーザーデータディレクトリの配置場所を指定します。デフォルトでは
~/.config/assam/chrome-user-data
に保存されます。
- Google Chromeのユーザーデータディレクトリの配置場所を指定します。デフォルトでは
設定された内容は~/.aws/config
のdefault
プロファイルのセクションに保存されます。任意のプロファイルに保存する場合は--profile
(-p
)オプションが使用できます。
ログイン
assam
コマンドを実行すると、Google Chromeが起動してAzure ADへのログインを求められます。このログイン操作によって、AWSにシングルサインオンを行い、CLIからAWSにアクセスするための認証情報をローカルに取得します。
$ assam
Azure ADにログインするとGoogle Chromeが終了してプロンプトが戻ります。
assamはデフォルトで.aws/credentials
のdefault
プロファイルに認証情報を上書きするのでご注意ください。default
プロファイルを使いたくない場合は、--profile
オプションをご利用ください。
AWSアカウントとロールの切り替え
AWS CLIとSDKでは、切り替え先のロールを~/.aws/config
に設定しておくと、AWS_PROFILE
環境変数などによるプロファイル名の指定のみで簡単に切り替えることができます。
AWSアカウントIDが333333333333
のSampleRole
に切り替える設定の場合は、次のようになります。
[profile sample-role] region = ap-northeast-1 role_arn = arn:aws:iam::333333333333:role/SampleRole source_profile = default
~/.aws/config
で設定したプロファイル名をAWS_PROFILE
に指定します。
$ export AWS_PROFILE=sample-role
このように設定することで、SSOで認証情報を得たdefault
のプロファイルでsts:AssumeRole
オペレーションをバックグラウンドで実行します。そして、目的のロールの一時的な認証情報を得て、指定されたAWSへのオペレーションを実行できます。
assamの--profile
オプションを使ってプロファイル名をdefault
から変更している場合は、source_profile
に変更したプロファイル名を指定してください。
また、AWS SDKを使用したツールでは、AWS_SDK_LOAD_CONFIG
にtrue
または1
を設定しておくことで、このしくみを利用するようになります。
$ export AWS_SDK_LOAD_CONFIG=true
direnvを利用すると、ディレクトリを移動しただけでプロファイルが切り替えられて便利です。
おわりに
Azure ADをお使いの場合はぜひassamをご活用ください。
他のIdPでもSAMLの設定が可能なので、同様の構成を作る際のご参考になれば幸いです。