AWSマルチアカウントにおけるIAMユーザー設計戦略を考えてみる

はじめに

2020年3月以来の投稿になりますが、「AWS案件に携わる中で、いろいろと貯まった知見を世のエンジニアの皆さんと共有したいな..」という思いに突然駆られ、本稿ではAWSマルチアカウントにおけるIAMユーザ設計の戦略をご紹介します。

ビジネスの要件・制約等により、取り得る設計は様々ですが、一つのベストプラクティス例としてご参考になればと思います。

IAMポリシーに関する基本方針

カスタマー管理ポリシーの利用

AWS利用において、避けては通れないIAM設計。 AWSでは、AWSアカウント(ルートユーザー)の通常利用は推奨しておらず、 AWSアカウント作成後は速やかにIAMユーザーを作成される方も多いのではないでしょうか。

AWS アカウントのルートユーザー 認証情報を使用して AWS にアクセスしないでください。また、認証情報を他のだれにも譲渡しないでください。代わりに、AWS アカウントへのアクセスが必要な人用に個別のユーザーを作成します。また同様にご自身にも IAM ユーザーを作成することにより、IAM ユーザーに管理アクセス許可を付与し、それらのユーザーをお客様の全作業で使用することができます。

IAM でのセキュリティのベストプラクティス - AWS Identity and Access Management

マネジメントコンソール操作を行う際はIAMユーザーの作成が必要になります。 とても単純な例ですが、以下のようにIAMユーザーに該当するIAMポリシー等を直接紐付けて、AWS各種リソースの操作を行うことができます。

さて、この例ではIAMユーザーに直接インラインポリシーを定義しています。

※インラインポリシーとは、IAMユーザー等に直接埋め込まれるポリシーです。

ユーザーと権限が1対1に紐づいており、非常にシンプルでわかりやすい構成ですよね。

ただ、このような構成では次第に以下のような弊害が生じてきます。

  • 定義済みのIAMポリシーを他IAMユーザーと共有・再利用できない

  • 複数のIAMユーザーのIAMポリシー変更作業が手間であり、作業効率が悪い

そのため、AWSでは、インラインポリシーではなく、カスタマー管理ポリシーの利用が推奨されています。

※カスタマー管理ポリシーとは、IAMユーザー等とは独立して定義・管理可能なポリシーです。

各用途向けにさまざまなポリシーが用意されています。通常、インラインポリシーではなく、管理ポリシーを使用することをお勧めします。

管理ポリシーとインラインポリシー - AWS Identity and Access Management

上記構成をカスタマー管理ポリシーに変更すると以下のようになります。

IAMポリシーの依存関係を切り離すことで、IAMユーザー間で共有したり、ポリシー修正時の作業効率が期待できそうですね。

ここで、カスタマー管理ポリシーとは、利用者側で定義するポリシーです。 その他のIAMポリシー区分の種類として、サービス毎や大まかな職務毎にAWS側で事前に定義されている「AWS管理ポリシー」が存在します。 カスタマー管理ポリシーとAWS管理ポリシーを上手に組み合わせることで、効率よく必要となる権限を付与できます。

IAMグループによるポリシー適用ユーザーの集約

ポリシー付与の方針を改善しましたが、実はまだまだ問題点があります。 ビジネスの規模が大きくなり、仮にIAMユーザーが増えてくると、どのようなことが起こるのでしょうか?

  • IAMユーザー毎に都度IAMポリシーを紐付けないといけない(既存のIAMユーザーと同じ責務にも関わらず、都度ポリシー付与が必要となる)

  • IAMポリシーのつけ忘れや消し忘れなどの作業ミスが誘発する

上記のような問題に対処するために、IAMグループを利用します。 具体的には、運用上必要となる役割を決め、それをIAMグループとして定義し、IAMグループに管理ポリシーを付与してIAMユーザーを参加させれば良さそうです。

※要は同じ役割の人たちをぐるっとまとめてしまおう、という発想ですね

これで同じ役割のIAMユーザーが追加された際は、IAMグループに参加させるだけで個別のポリシー付与は不要になりました。 ここまでは比較的基本的なIAM設計の流れかと思います。

マルチアカウント利用時の問題点

IAMユーザーをIAMグループでひとくくりにし、そのIAMグループにIAMポリシーを付与することで、 効率よく権限管理ができそうなところまで見えてきました。

ここで、実業務でAWSを利用する上では監査要件や各環境への影響分離等を考慮し、 ほとんどのケースでマルチアカウント運用になります。

マルチアカウントの目的や考え方は以下の資料が参考になります。

https://d0.awsstatic.com/events/jp/2017/summit/slide/D4T2-2.pdf

実際には請求用アカウントや監査用アカウントなどもありますが、考え方をシンプルにするため、今回は以下のような構成を例に考えます。

  • 開発環境

  • ステージング環境

  • 本番環境

これらのアカウントに対し、先程のIAM設計を適用すると、どうなるのでしょうか?

ご覧の通り、それぞれの環境にIAMユーザーが定義される形になり、環境毎にログインが必要となります。 実際の開発現場では、環境間でアカウントを行き来することも多いのではないでしょうか。 上記の例ではアカウントが3つですが、提供するサービス毎にアカウントを分離する方針をとり、かつ複数サービスの保守作業を担当している場合、その分扱うIAMユーザー数も増えていきます。

整理すると、以下のような懸念点が存在します。

  • 作業負荷: 都度マネジメントコンソールにログインが発生するので、ログインが手間となる(ユーザー名、パスワード、MFAコード入力が都度必要となる)。パスワード更新の対象数なども増え、管理負荷が高まる。

  • 管理負荷: MFA認証のためのコード管理が煩雑になる。

  • セキュリティ: 利用者へのMFA認証登録を促す際、対象IAMユーザーが多くなり登録漏れが発生しやすい。また、マネジメントコンソールからのログイン可能なユーザー数が増えるため、セキュリティ上のリスクが高まる。

たくさんの問題点が列挙されました。 これらを解決するための方針として、極力IAMユーザーを集約することでログイン可能な認証ユーザー数を限定し、各AWSアカウントを利用できれば望ましいのではと考えられます。

ここで登場するのがIAMロールです。

クロスアカウントのスイッチロールによるIAMユーザー集約

このIAMロールですが、AWSサービスに関連付けて必要な権限を付与する用途で多用されます。 一方で、IAMユーザー利用の観点からも利用することができます。

具体的には、クロスアカウントと呼ばれるAWSアカウントを跨いでスイッチロールすることができます。そして、スイッチロールを行うと、スイッチ先のIAMロールに紐づいたポリシー権限の一時キーを利用することができます。 つまり、スイッチ先の権限を肩代わりして利用することが可能になります。

そして、スイッチ対象のIAMロール側に必要なIAMポリシーを付与すれば、 一度IAMユーザーにログインし、その後はスイッチロールするだけで環境毎の権限を利用できるようになります。

IAMユーザーを開発環境に一旦集約する方針をとると、以下のようになります。

ここで少し視点を変えてみると、IAMユーザー定義は開発環境に依存すべきではなく、本来は各環境とは独立的した共通的な存在です。 そのため、マルチアカウント戦略の一つとして、以下のように作業用アカウントとして切り出し、スイッチロールする方がリソース管理上理想でしょう。

※この作業用アカウントはJumpアカウントと呼ばれることもあります

このようにIAMユーザーを集約することで、各環境アカウント内にIAMユーザー定義が不要となり、環境別アカウント間定義の差異も少なくなります。 Infrastructure as Codeで構成管理している場合、作成対象のリソースが共通化されるため、シンプルなコード管理が可能となります。

最終的には、以下AWSBlack Belt資料の22スライド目で紹介されているような構成となりました。

www.slideshare.net

規模の拡大を見越して設計しておくことが重要ですね。

IAMロールの責務分離

各環境毎にIAMロールを定義することで、IAMユーザーを作業アカウントに集約し、 一度のログインで各AWS環境にクロスアカウントアクセスできるようになりました。 さて、作成したIAMロールにはそれぞれどのような責務を定義すればよいのでしょうか。 私の実務経験ベースですが、以下のように整理してみました。

  1. 管理者
  2. 作業者
  3. 閲覧者
  4. アプリケーション開発者
  5. リリース承認者
  6. 経理担当者
  7. サポートQA担当者

では、順番に責務の内容を追っていきます。

管理者(Administrator)

先ほどの説明の通り、ルートユーザーは基本利用すべきではない、との方針でした。 代わりにルートユーザーに近い役割を持つ責務として、管理者用ロールを設けています。 ただし、管理者ロールは非常に強い権限を持つため、多数のIAMユーザーからスイッチを許可するべきでありません。 とは言え、1人だけに割り当てると、有事の際に担当者不在等で対応できない場合に困ってしまいます。 そのため、通常は2人程度の割り当てが望ましいのでは、と考えています。

※スイッチ可能なユーザーはIAMグループ側のIAMユーザー追加で制御します

また、管理者ロールは多用せず、必要作業時のみ利用する方針が望ましいでしょう。

※私の場合、シンプルに権限管理したいため、このIAMロールにはAWS管理ポリシーのAdministratorAccessを割り当てています

作業者(Maintainer)

次に、AWSリソース作成や削除などを行う作業者のロールを設けています。 管理者IAMロールとは異なり、こちらはAWS作業に関する普段使い用IAMロールの位置付けです。 AWS管理者との違いは、例えば明確に利用したいリソースを拒否しておくことで、想定外のサービス利用を防ぐ方針を持つ点です。

例えば、AWSリソースを東京リージョンとバージニアリージョン以外で利用しない方針となっている場合、 他リージョンでのリソース作成をDenyすることで、ある程度の自由度は保ちつつも、管理者ロールより権限を制限した作業が可能です。

また、削除を防ぎたいAWSリソースを保護するような権限も関連付けています。

※CodeCommitリポジトリ、CloudTrail証跡設定、各種IAMユーザーのDelete権限をDenyする、など

考え方としては、「"AdministratorAccess" と"複数AWSリソースのDenyを定義したポリシー"」を組み合わるようなイメージです。

話が少々変わりますが、AdministratorAccessより権限が制限されたPowerUserAccessというAWS管理ポリシーがあります。 こちらのポリシーはIAM操作に関する権限が広めにDenyされており、作業者ロールベースでは割と作業する際に困ることが多く、私の場合は利用していません。

※例えば、あるAWSサービスを新規作成する際にアタッチするIAMロールが作成できない、など

閲覧者(Viewer)

管理者や作業者とは別に、参照専用のロールを用意しています。 これは、例えばCloudWatchでリソースやログ内容を確認したり、AWSリソースの設定値を確認するユースケースにおいて、 想定外に更新作業が行われないように参照権限だけを与えたロールとなります。

AWS管理ポリシーとして、ReadOnlyAccessが用意されており、こちらを割り当てています。

アプリケーション開発者(Developer)

アプリケーション開発者向けにコード管理やビルド、デプロイ、稼働確認に必要なロールを定義します。 具体的には、ソースコードAWS上で管理している場合はCodeCommitへのアクセス権限、 CI/CDを組んでいる場合はCodeBuildやCodePipelineのステータス確認権限等が該当します。

リリース承認者(Authorizer)

私が担当しているサービスの場合、金融関連のサービスということもあり、CI/CDに承認フローを設けています。

※以下はJAWS DAYS 2020にて登壇したCI/CDフローになります。こちらも適宜ご参照ください。

speakerdeck.com

作業統制を意識すると、この承認フローは然るべき担当者に割り当てるべきであり、その用途としてリリース承認者ロールを切り出しています。

経理担当者(Accountant)

AWSの料金を把握するための経理担当者用のロールを設けてます。 経理担当者は他のAWSリソース閲覧が不要なケースも多く、その場合は予算表示や使用状況レポート等の閲覧などに絞った権限となります。

Billing and Cost Management でのアイデンティティベースのポリシー (IAM ポリシー) の使用 - AWS 請求情報とコスト管理

(2020-05-30 修正) 補足ですが、作業者ロールではAdministratorAccessが割り当てられており、予算表示等の権限を所有しています。 この点について、作業者視点からみると過剰な権限であり、また必要な作業は必要なロールに切り替えて行う方が安全でしょう。そのため、作業者には経理担当のポリシーをDenyするほうが適切かもしれません。

サポートQA担当者(Questioner)

AWSではサポートケースを作成し、テクニカルな問い合わせ等が行えます。 これに関し、AWSでは問い合わせに関するガイドラインが提供されています。

技術的なお問い合わせに関するガイドライン - AWS サポート | AWS

言い換えれば、ガイドラインに従わず、むやみやたらに問い合わせするのは避けるべきという方針を採用しています。 そのため、私の担当するAWS環境では、ある程度問い合わせに習熟した作業者が問い合わせするようにロールを割り当てています。

(2020-05-30 訂正) 経理担当者と同じく、作業者ロールからサポートQAロールを除外するほうが適切かと思われます。

責務のまとめ

ここでご紹介したIAMロールの責務は一例ですが、ある程度のユースケースをカバーできるのではないでしょうか。

一人のIAMユーザーは複数のIAMグループに所属することができます。そして、作業時に必要な権限を持つロールにスイッチすることで、安全に作業を進めることができると考えています。

IAMグループの設計

ここまでの内容でマルチアカウント運用時のIAMロール設計を整理しました。

先ほど述べた通り、各IAMロールにスイッチ可能なIAMグループを作成するのはもちろんですが、 それらとは別に、全てのIAMユーザーが所属する共通用IAMグループ作成をオススメします。

通常、スイッチロール用のIAMグループはスイッチロールするために必要な権限のみを含むべきです。 一方、IAMユーザーは自身のパスワード変更やMFA認証登録などができる必要があり、これは全てのIAMユーザーで共通に定義すべきです。 これを共通IAMグループとして切り出し、上記の権限を割り振ることでIAMグループの責務を明確にすることができます。

以上の内容を全て考慮し、マルチアカウント時のIAMユーザー・IAMロール設計は以下のようになりました。

その他のIAM設計の考慮点

これまでに述べた以外に考慮すべきIAM設計も触れておきます。

複数サービスに跨がるIAMユーザー管理

今回は作業用アカウントと開発・ステージング・本番用アカウントの計4つでビジネス上の1つのサービス提供の単位として仮定し、 IAMユーザー・ロールの設計をご紹介しています。

仮にこのサービスが複数存在する場合、どのような構成となるのでしょうか?

管理者や作業者などのIAMロールがサービスの数分だけ増えていきます。 仮に、IAMユーザー集約の観点から管理用アカウントを全てのサービスで共通利用する場合、以下のような方針を検討する必要があります。

  • IAMグループに全サービス分の該当IAMロールのスイッチ権限を全て付与する

  • サービス毎にIAMグループを分離し、IAMグループ毎にスイッチロール用のIAMポリシーを関連づける

前者の場合、管理者用IAMグループに所属するユーザーAが、仮にサービスAのみを担当している場合でも、 サービスBの管理者IAMロールにスイッチできてしまいます。 これはセキュリティ上好ましくありません。

後者の場合、ユーザーAは必要なサービスA用のIAMグループに所属することでサービスA用のIAMロールのみにスイッチでき、前者の問題は解決できます。 ただし注意点として、1IAMユーザーが参加できるIAMグループ数の上限は10となります。 こちらは制限引き上げリクエストもできず、IAMユーザーが既に複数のグループに所属している場合、 この制限に該当してしまうかもしれません。

IAM および STS の制限

そのため、私としては、サービス毎に作業用アカウントを用意し、OktaやoneloginなどのIDaaSと呼ばれる認証連携サービスを利用することで、 ログイン操作を一元化して効率化を図るのが戦略としてよいかと考えています。

個別環境毎のIAMポリシーの考慮

先ほど紹介した管理者ロールは権限が強く、従事するビジネスによっては利用を限定したいニーズもあります。 同様に、本番環境などは然るべき作業場所からのアクセスに限定すべきシーンもあります。

私はAWSで金融サービスを担当しており、管理者ロールのスイッチは社内のLANからのみに限定し、 本番環境用IAMロールのスイッチは本番作業を行う部屋のIPアドレスからのみに限定する必要がありました。

スイッチロール自体の制限を検討することも忘れないようにしましょう。

スイッチロールの手間を回避できるか?

AWSアカウントの数が多くなってきたり、一人が複数責務を負うような状況の場合、「スイッチロールでさえ手間でしょ!」と感じる方もいるかもしれません。 実際その通りで、アカウント数が多くなってくると割りと面倒です。 また、1人のユーザーが多数の責務を負う場合は尚更ですね。

そこで、一度だけIAMロールにスイッチすれば、そのアカウント内でスイッチ可能なIAMロール権限を 全て持った状態にすれば、この点は緩和できると考えてられるかもしれません。 ただし、そのような場合、スイッチ先アカウントに作成するIAMロールは実質的にはIAMユーザー単位になります。

※あるIAMユーザーが複数IAMグループに所属する、ということを考慮するとIAMユーザー毎に組み合わせが異なるからです

IAMユーザーが増減するたびに、本番環境含めたIAMロールの作成・削除の運用は非常に負荷が高くなりますし、 ユーザーに関する定義を作業用アカウントに寄せるという思想から外れてします。

以上を考慮すると、多少面倒ではあっても、ご紹介したアカウント毎の責務とIAMロール定義の考え方はセキュリティと作業効率のちょうど良い落とし所なのかもしれません。

さいごに

本稿では、AWSマルチアカウントにおけるIAMユーザー設計の戦略についてご紹介しました。 基本的なIAMポリシーの方針から、IAMロールを活用したクロスアカウントアクセス、さらにはIAMロール責務の考え方について踏み込んで触れてみました。 少々文量が多くなってしまいましたが、IAMロール設計でお困りの方のお力になれれば幸いです。

少し話が変わりますが、先日AWSより「2020 APN AWS Top Engineers」に選出いただきました。

aws.amazon.com

これをきっかけに私自身、いろいろな方々と技術を共有していきたいという気持ちが強くなっています。 本ブログを通し、(最低月1ぐらいのペースで、、)シナリオベースの設計戦略や実践的なベストプラクティスを紹介していければいいなぁ、と考えています。

※ただし、ネタが尽きない限り...

ちょっとだけ本の宣伝

本ブログは、以下、佐々木拓郎さんのIAM本に強くインスパイアされています。 IAMの内容が明快かつコンパクトに網羅されており、全てのAWS初心者の方から上級者にオススメしたい一冊です。

booth.pm

また、私自身も技術書典#8向けにAWSコンテナ本を共著で執筆していたりします。 6月中旬ごろに書籍版が入荷予定ですので、AWSコンテナサービスに興味をお持ちの方は、是非お手にとっていただけると嬉しいです。

umarai-books.booth.pm

Twitterでも適当に技術ネタを呟いています。 アカウントは@msy78です。気軽にフォローしてメンションしてください。

Masaya Arai (@msy78) | Twitter

ではでは。