SwitchRoleを使用してIAMユーザ管理を楽にする

Misoca開発チームの@kokuyouです。

最近新しいMac miniが届き、MacBook Proとの2台体制になったので、区別しやすいようマシン名をつけました。
MacBook Proのマシン名がKanon、Mac miniのマシン名がCLANNADとなっております。*1

f:id:kokuyouwind:20181122130446p:plain

f:id:kokuyouwind:20181122130454p:plain

これに対する某氏の反応がこちら。

f:id:kokuyouwind:20181122130508p:plain

はい。

🧑IAMユーザ増えすぎ問題

Misocaではサービスの開発・運用にAWSを活用しています。 この際に各環境の設定が混在しないよう、以下のようにAWSアカウントを分けています。

  • sandbox : 自由に各種設定を試せる砂場環境
  • development : 開発系のEC2やサービス設定を行う環境
  • production : 本番系のEC2やサービス設定を行う環境

これによって各リソースがどの環境のためのものかわかりやすくなり、「開発用の設定を弄ったら本番にも影響しちゃった!」という事態も防ぐことができます。
また「開発環境は自由に触れるが、本番環境は設定参照のみが可能」といった、環境基準でのIAMポリシーもシンプルに表現できます。

しかし、この運用では各環境ごとに全員分のIAMユーザを発行・管理する必要があります。
開発者が増えるごとに、IAMユーザの発行を3回行う必要があるわけです。

また開発者が利用する際も、AWSコンソールでIAMユーザを切り替えるたびにログインしなおす必要があります。
アカウント名が被っているとブラウザがパスワードを1環境分しか覚えてくれなかったりと、これもなかなか面倒です。*2

🎭 IAMユーザ集約とロール切り替え

そこで、ロールの切り替えを利用して他のアカウントのロールに切り替える方法を導入しました。

ログイン専用のAWSアカウントを新たに作成し、IAMユーザはこの環境にのみ作成します。 開発者はIAMユーザでログイン後、各環境のロールに切り替えることで、開発環境や本番環境での作業を行えるようになります。

ロールやポリシーの設定はClassMethodさんの記事を大いに参考にしています。

以下で導入手順を大まかに解説します。

既存環境へのロール追加

これまでは AdminDeveloper などのIAMグループを作成し、IAMユーザをグループに割り当てることで権限を管理していました。
これを置き換えるため、それぞれのグループに対応する切り替え用IAMロールを作成します。

「信頼されたエンティティ」には、ログイン環境のAWSアカウントIDを入力します。

f:id:kokuyouwind:20181122135242p:plain

ポリシーは、既存のグループについているものをそのまま選択します。 ただし「自分のMFAデバイスを設定する」などのIAM絡みのポリシーは必要なくなるので、そういったポリシーは省きます。

f:id:kokuyouwind:20181122135334p:plain

ロール名はグループとの対応がわかりやすいよう、同じ名前をつけました。
これについては、 SwitchRoleDeveloper などのように、SwitchRole用だとわかりやすい名前にしたほうが管理しやすいかもしれません。

f:id:kokuyouwind:20181128173212p:plain

ログイン環境の設定

続けて、ログイン用の環境からロール切り替えできるようにしていきます。

ロールの切り替えは sts::AssumeRole というアクションです。
先ほど開発環境に作ったIAMロールが arn:aws:iam::000000000000:role/Developer であれば、以下のようなポリシーを作ることでロール切り替えを許可できます。

f:id:kokuyouwind:20181128173829p:plain

ポリシー名は環境とロールのペアがわかりやすい名前にしておくと後々管理しやすいです。

以下の例だと開発環境(DevEnv)にある開発者ロール(DeveloperRole)で、用語が被ってしまい分かりづらいですね…

f:id:kokuyouwind:20181128174259p:plain

あとは、このポリシーを各IAMユーザに付与することで、そのユーザは該当ロールに切り替えられるようになります。

実際にロールを切り替える

ログイン環境に入り、アカウントメニューにある「ロールの切り替え」からアカウントを切り替えることができます。

f:id:kokuyouwind:20181128174838p:plain

成功すると、右上のアカウント表示が指定した名前と色に変わります。
今入っている環境がわかりやすいよう、一定のルールで名前と色を設定するのがおすすめです。

f:id:kokuyouwind:20181128175110p:plain

設定Tips

  • 1つのロールごとに対応する切替ポリシーをログイン環境に作り、それを束ねるグループを作ると扱いやすい
    • DeveloperグループにDevEnvDeveloprポリシーとProdEnvReadOnlyポリシーをアタッチする、といった管理ができる
  • ロール切替の情報入力はけっこう面倒なので、切替リンクをまとめておくと布教しやすい
  • IAMポリシー割当を弄るだけで好きな環境・好きなロールに切り替えられるので、ログイン環境のIAM権限は限られたユーザにのみ付与する

👍 SwitchRoleでよいところ

  • 当初の想定通り、環境の切り替えが非常に楽になった
    • 管理するログイン情報が1つだけで済む
    • 新しい人が入ったときも、IAMユーザを1つ作るだけ
  • ログイン環境のIAMだけ見れば「誰が何をできるか」が概ね分かるようになった
  • より弱い権限での動作確認がしやすくなった
    • 「管理者以外はこのバケットを見れなくしたい」といった設定をAdministratorアカウントで動作確認するのはなかなか難しかったけど、Roleを切り替えるだけでできるようになった

🤔 SwitchRoleの気になること

いま入っている環境が分かりづらい

右上のロール表示を見ればわかるんですが、あまり目立たないのでうっかり間違えそうになります…

特に大きいディスプレイで作業していると表示が小さくなるので見落とし率が上がります。

f:id:kokuyouwind:20181128182032p:plain

画面中央を注視して作業してると、ここはまず見ないですよね…

どうせならヘッダーの背景色も同じ色にしてくれるとわかりやすいんですが、そういった機能はないようです。

同じことを考える人はいるようで、AWS Extend Switch RolescolorAWSFrameといったChrome拡張を使えば多少はわかりやすくなります。

Roleの信頼するエンティティにIAMグループを指定できない

SwitchRoleに使うロールには信頼関係を設定できます。
ログイン環境のアカウントIDを設定した部分ですね。

f:id:kokuyouwind:20181128182813p:plain

GUIからはアカウント単位までしか設定できませんが、JSONを直接編集することでIAMユーザ単位でも信頼するエンティティを設定することができます。
「ログイン環境のkokuyouのみを信頼する」といった設定をしておけば、ログイン環境側のポリシーをどう弄ってもそれ以外のユーザは切り替えられなくなるわけですね。
この設定は複数のIAM Userがあるアカウントをスイッチ元として、クロスアカウント用IAM Roleを作るにも書いてあります。

とはいえ、ユーザ単位で信頼関係を管理するのは管理が大変そうです。 できれば「ログイン環境のAdminグループを信頼する」といった設定をしたくなってきます。

残念ながら、信頼関係に設定できるのはIAMユーザ、IAMロールのみで、IAMグループは設定できないようです。
アカウント単位で信頼してもさほど問題はないのですが、できれば最小限にしたいところですね。

🌈 今後やりたいこと

現状は手作業でIAMユーザを作ってSwitchRole用グループを割り当てていますが、この辺をterraformで管理してPull RequestベースでのIAMユーザ追加・IAMグループ割当ができると、手作業を減らせるうえ履歴も追いやすい形で残って良さそうです。

また、本番環境では「一部S3バケットのみアクセスできる」などのポリシーが設定されています。
しかし、他のポリシーと一緒に設定した状態で意図通り動くかは結構分かりづらく、都度手作業で確認しています。

こうした部分も、ロールごとにawspec でテストを書いてCIできるようにしていけると良いなと思います。

📢 宣伝

MisocaではAWSを使いこなしたいエンジニアを募集しています!

www.wantedly.com

*1:どっちもAIRじゃない、というのがポイントです

*2:Chromeでユーザを複数作り、それぞれのChromeユーザごとに別のIAMユーザでログインするという運用をしている人が多いようです