Control Towerカスタマイズソリューション(CfCT)を使ってガードレールとCloudFormationを自動展開してみた

2021.08.04

Control Towerのカスタマイズという以下ソリューションを利用して、Control Tower配下のOUに対してCloudFormationスタックとSCPを自動展開してみました。

今回は以下のワークショップに沿って実施しています。単純な内容ですが、少しハマりどころもあったので手順含めて載せておきます。

AWS Control Towerのカスタマイズ (CfCT) :: AWS Control Tower ワークショップ

前提

  • Control Tower有効化済(バージョン2.7)
  • ホームリージョンは東京

構成

仕組みとしてはControl Towerからアカウントを発行した時やCodeCommitかS3のソースが更新されたとき、CloudFormationスタックやSCPを展開するというものです。

Control Towerのアカウントファクトリーからアカウントが発行された時には、ライフサイクルイベントcreateManagedAccountStatusというイベントが発生します。発生したイベントをEventBridgeで取得してSQS、Lambdaと実行することでCodePipelineを新規アカウントに対し実行します。

CodePipelineではソースとなるS3かCodeCommitからテンプレートを取得してCodeBuildを実行しています。CodeBuildでは公開されているスクリプト群を取得して、StepFunctionsを動かすような仕組みとなっています。

このソリューションを利用することで、既存で管理しているアカウントや新規に発行したアカウントに対しても同じようにCloudFormationスタックやSCPを展開することが可能となります。

各リソースの詳細については実装ガイドを参照ください。

https://d1.awsstatic.com/Solutions/ja_JP/customizations-for-aws-control-tower.pdf

やってみた

今回はワークショップ通りに実施していくため、赤枠で囲ったCodeCommitへのPushからPipelineを実行してリソースを展開するフローを体験してみます。(新規アカウント発行からのフローについては別でまたブログを書きます。)

Control Towerが有効化されていることが前提です。

CfCTの展開

Control Towerのホームリージョンへ以下のリンクからスタックを展開します。このときリーションがホームリージョンとなっているか確認を忘れないようにしましょう。

スタック展開URL

AWS CodePipeline SourceにはS3ではなくCodeCommitを指定します。

その他はデフォルトのまま作成します。

次にCodeCommitへ接続する環境を用意します。Gitを利用できる環境であればどこでも構いませんが、今回はCloud9を使って実施しています。

Cloud9のCreate environmentから適当な名前を入力して起動してください。スペックなどはデフォルトで大丈夫です。

おそらくデフォルトで入っていますが念のため、以下のコマンドでGitをインストールします。

$ sudo yum install git -y

コンソールからCodeCommitの画面を開いて、custom-control-tower-configurationのリポジトリからHTTPSのURLをコピーしてください。

コピーできたらCloud9のターミナルからクローンを実行します。

$ git clone {コピーしたHTTPSのURL}

ローカルにリポジトリのフォルダ(デフォルト:custom-control-tower-configuration)があることを確認してください。

カスタマイズソリューションを展開する

本来であれば、次の手順でmanifest.yamlをワークショップ通りに上書きしてCodeCommitへPushするのですが、CodeBuildでエラーとなり実行できませんでした。

CodeBuildでは公開されているS3上のテンプレートをダウンロードして実行しており、そのURLを作成する過程でホームリージョンの東京リージョンを指定することが原因のようでした。(恐らくこのワークショップは東京リージョンをホームリージョンとして利用する想定となっていないため)

そのため、手動でテンプレートをダウンロードして、テンプレートファイルの指定をマニフェストファイルからS3ではなくローカルファイルへ変更してあげます。

今回は以下の方法で対応しました。

以下2つのテンプレートをダウンロードしてください。クリックでダウンロードできます。

Cloud9のクローンしたフォルダ配下にtemplateフォルダを作成して、その中にダウンロードしたテンプレート2つをアップロードします。

クローンしたフォルダ直下にmanifest.yamlファイルがあるので、以下の内容で置き換えます。

organizational_unitsregionsについては各自の環境に合わせて変更してください。

---
#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
    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

このマニフェストファイルではガードレールとIAMロールが指定したOU配下のアカウントへ展開されます。マニフェストファイルの書き方について詳細に知りたい方は以下開発者ガイドをご参照ください。(英語版)

customizations-for-aws-control-tower-developer-guide.pdf

日本語版の開発者ガイドもあるのですが、マニフェストファイルのバージョンが古くなっていました。記述方法が少し違うため、今のところは英語版を参照するのが良さそうです。

<2021/10/04追記>日本語版の開発者ガイドも最新バージョンとなっていたので、これから参照する場合は日本語の開発者ガイドを参照してください。

以下コマンドでCodeCommitにPushします。

git status
git add -A 
git commit -m 'Initial checkin'
git push

CodePipelineが動き始めるのでコンソールから確認して10分程度待ちましょう。マニフェストファイルが間違っていなければ問題なく成功するはずです。

展開した結果を確認する

Control Tower展開時に作成されるOUであるSecurityを展開先と指定したので、Auditアカウントにログインして確認していきます。

ガードレールの展開

ガードレールとして展開されたSCPから確認してみます。OrganizationsのSCPを確認すると、test-preventive-guardrailsというマニフェストで指定した名前のSCPが展開されています。

中身を確認してみると、Security OUのみに展開されていることが確認できました。

StackSetsで展開されたリソース

展開されているIAMロールを確認してみます。StackSet-CustomControlTower-create-TestLambdaRole-XXXXXXXXXXというロールがStackSetsより展開されていることが確認できます。

もう1つ展開されているConfigルールを確認します。Configを開くとACCESS_KEYS_ROTATEDというルールが展開されています。

中身を見ると、マニフェストで指定したパラメータが確認できました。

ここまででワークショップは終了です。展開されている2つのStackSetsはControl Towerのマネジメントアカウントから確認できます。

マニフェストファイルを修正して再Push

せっかくなのでマニフェストファイルの値を変更したとき、正しく各アカウント側で修正されるか確認してみます。manifest.yamlparameter_valueを30に変更してみます。

# 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: '30'
    deploy_method: stack_set
    deployment_targets:
      organizational_units:
        - Security
    regions:
    - ap-northeast-1

CodePipelineが問題なく完了したのを確認したら、同じようにAuditアカウントからConfigのルールを見てみます。

問題なくマニフェストファイルで指定した値が利用されて更新されていることが確認できました。

クリーンアップ

環境が不要な方は以下のクリーンアップ手順も実施してください。

SCPの削除

OrganizationsのSCPからtest-preventive-guardrailsを削除します。ターゲットから紐づいているOUをデタッチすればSCPを削除できます。

StackSetsの削除

Control Towerのマネジメントアカウントにログインして展開したStackSetsを削除します。

CloudFormation > StackSetsを確認してCustomControlTower-create-iam-roleにチェックを入れてアクションからスタックを削除します。

展開したOU単位、もしくはアカウント番号を入れて展開したリージョンを指定します。今回の例の通りであれば、リージョンは東京リージョンのみです。

その他はデフォルトで送信すると削除が実行されます。全てのスタックが削除されたらアクションからStackSetsの削除を選べば削除できます。同じ手順でCustomControlTower-rotate-access-keys-guardrailも実施してください。

ソリューションスタックの削除

カスタマイズソリューション自体を削除します。CloudFormationからCustomizationsForCTSolutionのスタックを削除してください。

ただし、展開済のS3とCodeCommmitはスタックを削除しただけでは消えないので、不要であれば手動で削除してください。S3はバージョニングが有効化されているので、旧バージョンのオブジェクトまで全て削除してからバケットを削除するように注意しましょう。

対象のS3バケット

  • custom-control-tower-configuration-{アカウントID}-{リージョン名}
  • customizationsforctsolut-customcontroltowerpipeli-xxxxxxxxxxxx
  • customizationsforctsolut-customcontroltowers3acce-xxxxxxxxxx

対象のリポジトリ名(CodeCommit)

  • custom-control-tower-configuration

まとめ

Control Towerカスタマイズソリューション(CfCT)を使ってCloudFormationスタックとガードレールを展開してみました。Control Towerによる統制を考える際、同じリソースの展開やSCPの適用など各アカウントごとに実施する手間を減らすことができる良いソリューションだと感じました。

ただし、導入・運用するにあたりマニフェストファイルの書き方やソリューションの理解などが必要となるため少し学習コストが必要となることを忘れないようにしましょう。

マルチアカウント統制を考えるときの選択肢となれば幸いです。

参考