技術2課の松田です。こんにちは。
今回はAWS CloudFormation StackSetsを使ってAWS Organizations配下のアカウントにIAM Roleを一括デプロイする方法について解説します。
今回の構成
今回はAWS CloudFormation StackSetsを使ってAWS Organizations配下のアカウントに対するIAM Roleの一括デプロイを行います。
構成イメージは以下の様になります。
CloudFormation StackSetsをマネジメントアカウントに作成し、ターゲットとしてOU-01を指定します。すると自動処理でOU-01配下のAccount-01にIAM Roleが作成されるという流れです。アカウントが少ないので一括デプロイ感はないですが、準備がめんどかったのでわけあって最小限の構成になっています。
余談ですが、マルチアカウント環境ではコンソールへのログイン経路を一つのアカウントに集約するという手法がしばしば取られます。ログインのためのIAMユーザーをアカウントAだけに作成し、アカウントB、C、DへのログインにはアカウントAからのスイッチロールを利用するという方法ですね。この場合、全てのアカウントにIAMロールを作成する必要がありますが、それをCloudFormation StackSetsで行うことで運用の手間をかなり削減することができます。今回はそのようなケースをイメージしています。
利用サービスについて
本記事の根幹となるサービスに簡単に触れておきます。
AWS Organizationsについて
以下は公式ドキュメントより。
AWS Organizations は、ユーザーが作成して一元管理する組織に、複数の AWS アカウント を統合するためのアカウント管理サービスです。
分かりにくい日本語ですが、要するに複数のAWSアカウントの一元管理を可能にする、運用効率化を目的としたサービスになります。機能はたくさんあるのですが、本記事に関連する機能に絞ってさらっておきます。
AWSサービスの統合
AWS Organizationsでは、いくつかのAWSサービスを統合することが可能です。例えばCloudTrailを統合した場合、組織内の全アカウントでCloudTrailを一括で有効化したり、一括で設定を変更できるようになります。
なお統合されたサービスの操作は、通常マネジメントアカウント(AWS Organizationsのルートとなるアカウント)で行うことになります。サービスによっては、操作をマネジメントアカウント以外のアカウントに委任することも可能です。
Service Control Policy(SCP)
SCPを使用することで、組織内のアカウントを対象として、アクセス権を制御することが可能です。SCPで定義されたアクセス制御は、対象のアカウント内のすべてのユーザー、ロールに適用されます。
Organizational Unit(OU)
AWS Organizationsでは、アカウントをOUという単位でグルーピング可能です。上述のSCPや後述のCloudFormation StackSetsはアカウントのグループであるOUに適用することが可能です。
またOUはネスト可能であり(OUの中にOUを作れる)、上位のOUに適用されたSCPなどは下位のOUにも適用(=継承)されます。OUをうまく活用することで、アカウントの管理を効率的に行うことが可能です。
AWS CloudFormationについて
AWS CloudFormation は AWS リソースのモデル化およびセットアップに役立つサービスです。
とのことですが、つまりはAWSマネージドなInfrastructure as Code(IaC)ツールです。テンプレートと呼ばれるYAML形式のファイルを用意し、それを流すことでAWSリソースを作成できます。ちなみにテンプレートはAWSおなじみのJSONにも対応していますが、コメントが書けるYAMLを使うのが無難です。
※以下はYAMLテンプレートのサンプル。これを流すとVPCが作成可能。
AWSTemplateFormatVersion: "2010-09-09" Description: Create VPC Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 172.16.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true
AWS CloudFormation StackSets
CloudFormationによるリソースのデプロイを、マルチアカウント・マルチリージョンに拡張させたものがAWS CloudFormation StackSetsです。StackSetsはAWS Organizationsに統合することが可能で、また上述の委任にも対応しています。つまりマネジメントアカウント(もしくは委任されたアカウント)でテンプレートを流すことで、複数アカウントに一括してリソースをデプロイすることが可能になります。また一括デプロイのターゲットはアカウントを1つずつ選択するだけでなく、OUを選択することも可能です。
設計
IAMロール
IAMロールにはAWS管理ポリシーであるReadOnlyAccess
と、以下のカスタマー管理ポリシーをアタッチします。中身はAWS管理ポリシーAmazonS3FullAccess
と全く同じですが、カスタマー管理ポリシーを使うパターンも試したいのでこのようにします。
- StackSetsTestPolicy
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*", "s3-object-lambda:*" ], "Resource": "*" } ] }
IAMロールの信頼関係は以下です。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<AWSアカウントID>:root" }, "Action": "sts:AssumeRole", "Condition": {} } ] }
CloudFormation StackSets
上述のIAMリソースをデプロイするCloudFormation StackSetsテンプレートは以下となります。
- CreateIAMRoleForAssumeRole.yaml
AWSTemplateFormatVersion: "2010-09-09" Description: "Create IAM Role for Assume Role" Resources: IAMPolicy: Type: AWS::IAM::Policy Properties: PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "s3:*" - "s3-object-lambda:*" Resource: "*" PolicyName: StackSetsTestPolicy Roles: - StackSetsTestRole DependsOn: IAMRole IAMRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: AWS: - "arn:aws:iam::<AWSアカウントID>:root" Action: - "sts:AssumeRole" Condition: Bool: aws:MultiFactorAuthPresent: "true" RoleName: StackSetsTestRole ManagedPolicyArns: - "arn:aws:iam::aws:policy/ReadOnlyAccess"
構築手順
では構築していきます。 まずはマネジメントアカウントにログインしてStackSetsの画面を開き、「StackSetsの作成」をクリックします。
「テンプレートの指定」で作成したYAMLテンプレートを指定し、あとはデフォルトで進みます。
ちなみにStackSetsを実行すると、ターゲットとなるAWSアカウントにCloudFormationスタックが作成されます。なのでStackSetsには、ターゲットに対してスタックを作成する権限を予め付与する必要があるのですが、「アクセス許可」で「サービスマネージドアクセス許可」を指定すると、この権限設定を自動で処理してくれます。詳細はこちらをご参照ください。
StackSets名を適当に入力し、次へ進みます。説明はYAMLに予め埋め込んでいるので入力不要、パラメータは宣言していないので無視します。
タグの設定はスキップして次に進みます。
「デプロイターゲット」はOU-01のOU-IDを入力します。残念ながらこのウィザードから検索できないので、OU-IDが分からない場合はOrganizationsの画面を開いて確認します。
「リージョンの指定」は「東京リージョン」を指定しました。ここで指定したリージョンはYAMLテンプレートで定義したリソース(今回の場合はIAMロールとポリシー)を作成するリージョンではなく、CloudFormationスタックを作成するリージョンである点にご注意ください。IAMはグローバルサービスでかつリソース名の重複は許されないはずなので、ここで複数リージョンを指定するとエラーになります。
最後に設定内容を見返してメッセージにチェックを入れ、「送信」でStackSetsを作成します。
作成されたStackSetsのステータスが「Succeed」になることを確認します。これで完了になりますので、実際にリソースが作成されているかを見てみます。
StackSetsのターゲットとしたアカウントにログインすると、CloudFormationスタックが作成されています。
IAM Roleもちゃんと作成されていますね。
まとめ
今回はCloudFormation StackSetsを使ってOrganizations配下のアカウントにIAM Roleの一括デプロイを行いました。 本記事がどなたかのお役に立てば幸いです。
松田 渓(記事一覧)
2021年10月入社。散歩が得意です。