Control Towerカスタマイズソリューション(CfCT)で新規アカウント発行時にCloudFormationを自動展開してみた
前回以下の記事でControl Towerのカスタマイズソリューションを展開して、CodeCommitへのPushからCloudFormationとガードレールを展開しました。
Control Towerカスタマイズソリューション(CfCT)を使ってガードレールとCloudFormationを自動展開してみた | DevelopersIO
このソリューションではCodeCommitやS3の変更だけでなく、アカウントファクトリーからの新規アカウントの発行時にもパイプラインを実行することが可能なのでやってみました。
前提
- Control Tower有効化済(バージョン2.7)
- ホームリージョンは東京
- カスタマイズソリューション展開済
構成
今回試すのは、新規アカウントが発行された時に動くライフサイクルイベントワークフローの部分です。Control Towerカスタマイズソリューションを既に展開していれば、個別にリソースを作成する必要はありません。
各リソースについて簡単に説明します。
Control Tower ライフサイクルイベント
Control Towerではイベントが記録され、ライフサイクルイベントとして発行されます。今回利用するライフサイクルイベントは、アカウントファクトリーからAWSアカウントの作成が完了したときに発行されるCreateManagedAccount
というライフサイクルイベントです。その他にいくつかライフサイクルイベントがあり、そこからEventBridgeを利用して自動化のフローを作成できます。
AWS Control Tower のライフサイクルイベント - AWS Control Tower
EventBridge
ライフサイクルイベントCreateManagedAccount
を取得しSQSにイベントを送信します。イベントパターンは以下のように定義されています。
{ "detail-type": ["AWS Service Event via CloudTrail"], "source": ["aws.controltower"], "detail": { "serviceEventDetails": { "createManagedAccountStatus": { "state": ["SUCCEEDED"] } }, "eventName": ["CreateManagedAccount"] } }
CreateManagedAccount
のイベントを取得して、成功していればSQSに送るように設定されています。
SQS
EventBridgeからイベントを受け取ります。アカウント発行が連続で行われた時には順序性を保つためにキューのタイプはFIFOで作成されています。Lambdaトリガーが定義されており、イベントが格納される度にLambdaを動かす構成となっています。
ソリューションを展開すると、合わせてDLQ用のSQSキューも作成されます。
Lambda
SQSキューからキックされ起動するLambdaです。受け取ったイベントがControl Towerのものであれば後続に定義しているCodePipelineを実行するようになっています。最初はこのLambdaの中でイベントからアカウント番号を取得し実行しているのかと思いましたが、展開する先についてはソースのマニフェストファイルで全て定義しているようです。
構成としてはそこまで難しいものではないので分かりやすいですね。
やってみる
前回と事前準備はほぼ同じなので割愛します。まだソリューションを展開していない方は以下記事の「カスタマイズソリューションを展開する」まで進めてください。
Control Towerカスタマイズソリューション(CfCT)を使ってガードレールとCloudFormationを自動展開してみた | DevelopersIO
マニフェストファイルの修正
マニフェストファイルを新規発行するアカウントを配置するOUにも反映させるため、展開先のOUとして追加します。今回はSandBox OUに追加するため、マニフェストファイルに以下の様に追記します
--- #Default region for deploying Custom Control Tower: Code Pipeline, Step functions, Lambda, SSM parameters, and StackSets region: ap-northeast-1 # Control Tower Home Region version: 2021-03-15 resources: # Control Tower Custom Service Control Policies - Additional Preventive Guardrails - name: test-preventive-guardrails description: To prevent from deleting or disabling resources in member accounts resource_file: s3://marketplace-sa-resources/ctlabs/preventive-guardrails.json deploy_method: scp #Apply to the following OU(s) deployment_targets: organizational_units: - Security # Control Tower Custom CloudFormation Resources - Create Additional IAM Role - name: create-iam-role resource_file: template/describe-regions-iam-role.template deploy_method: stack_set deployment_targets: organizational_units: - Security - Sandbox regions: - ap-northeast-1 # Control Tower Config Rule - Additional Detective Guardrails - name: rotate-access-keys-guardrail resource_file: template/access_keys_rotated.template parameters: - parameter_key: maxAccessKeyAge parameter_value: '24' deploy_method: stack_set deployment_targets: organizational_units: - Security regions: - ap-northeast-1
create-iam-role
の定義ではSandbox OUが対象のためIAMロールをStackSetsで展開しますが、test-preventive-guardrails
とrotate-access-keys-guardrail
の定義では展開対象がSecurity OUのみのため展開されない動作となるはずです。
マニフェストファイルの書き方については開発者ガイドを参照してください。
AWS Control Towerのカスタマイズ開発者ガイド
ちなみに今回展開するCloudFormationテンプレートはIAMロールを1つ作成するだけです。
Resources: TestLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: DescribeRegions PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ec2:DescribeRegions Resource: '*'
新規アカウントを発行
動作を確認するため、Control TowerのAccount Factoryからアカウントの登録を発行します。
アカウント発行に必要な情報を入力して発行します。今回はアカウントをSandboxに配置しました。
アカウントが利用可能になるまでしばらくかかります。アカウントが利用可能となったとき、Control Towerカスタマイズソリューションのアカウント発行フローが動き始めます。
ここからは前回実施したソースへPushしたときと同じパイプラインが実行されるので、中の動作は同じです。新規発行のアカウントなのか既存のアカウントなのかは関係なく、マニフェストファイルで定義されたターゲットに未展開のアカウントがあれば展開されます。
ソース(CodeCommit/S3)の更新とライフサイクルイベントの発行でパイプラインの動作が変わらないのはわかり易くていいですね。
作成されたリソースの確認
パイプラインが完了したら、StackSetsからスタックインスタンスが対象のアカウントに展開されていることを確認できます。新規発行したアカウントにログインしてIAMロールが展開されているか見てみます。
問題なくStackSet-CustomControlTower-create-TestLambdaRole-XXXXXXXXXX
という名前で作成されていることが確認できました。
定義していないスタックの確認
マニフェストファイルではcreate-iam-role
のセクションだけSandboxを定義したので、他のリソースについては展開されていません。CloudFormationスタックを確認すると、IAMロールを展開しているStackSet-CustomControlTower-create-iam-role-XXXX
以外はカスタマイズソリューションによって展開されていませんでした。
気をつけたいこと
注意したい点としてはマニフェストファイル側でアカウント単位の指定をしてしまうと、アカウントを発行だけしたとしても展開されないことです。パイプラインは起動されますが、マニフェストファイル側でアカウントが展開対象となっていないので、新規アカウントにはリソースが展開されずに正常終了します。
基本的にはOU単位で定義しておくと、アカウント発行時にも自動で展開されるのでこのソリューションを最大限活かせるのかなと思っています。どの範囲(OU単位、アカウント単位)まで自動で展開したいのかをよく考えた上でマニフェストファイルを作成するようにしましょう。
まとめ
Control Towerカスタマイズソリューションの新規アカウント発行の動作を確認してみました。コードで構成を管理でき、自動展開できるためいろいろと活用できそうなソリューションです。ぜひControl Towerを利用している環境で、リソースをマルチアカウントに自動展開したい場合は検討してみてはいかがでしょうか。