![[アップデート] Control Tower のガードレール適用が API と CloudFormation 経由で行える様になりました](https://devio2023-media.developers.io/wp-content/uploads/2022/08/aws-control-tower.png)
[アップデート] Control Tower のガードレール適用が API と CloudFormation 経由で行える様になりました
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、大前です。
Control Tower について以下のアップデートがありましたので、紹介したいと思います。
どんなアップデートか
Control Tower のガードレール設定を行うための API が提供されました。また、CloudFormation を利用した変更もできる様になっています。
端的に書くと大したアップデートではないですが、Control Tower を活用している方からすると大きなアップデートではないでしょうか。
本アップデート以前は Control Tower のガードレールを手作業で有効化する必要がありました。ガードレールは多数存在するため、単純に各ガードレールを手作業で有効化していくのは大変ですし、手作業ゆえの設定ミスもリスクとしてあったと思います。
今回のアップデートで API や CloudFormation を利用したガードレールの有効化が可能となったため、単純に作業時間が短縮できますし、ガードレールの最新状態を管理しやすくなったかと思います。
やってみた
では実際に今回のアップデートを利用してガードレールの設定変更をやってみます。
執筆時点では AWS CLI v2 にて Control Tower API の対応がされていない様なので、今回は CloudFormation のみの確認としています。(v1 では対応している様なので、どうしても早く CLI で有効化したい、という場合は v1 でお試しください)
以下に、いくつかのパターンについて、利用した CloudForamtion テンプレートとその結果を記載していきます。
具体的なテンプレートは後ほど記載しますが、ControlIdentifier(有効化対象のガードレールの ARN)と TargetIdentifier(ガードレール適用先となる OU) を指定する形式の様です。
また、ControlIdentifier に指定する ARN については、以下ドキュメントにて一覧を確認可能です。
パターン 1 : 有効化されていないガードレールを CloudFormation で有効化する
まずはシンプルな有効化作業です。
以下のテンプレートを利用しました。リージョンは Control Tower を有効化しているホームリージョンに置き換えてください。
また、有効化するガードレールとしては Amazon EC2 インスタンスの Amazon EBS 最適化が有効になっているかどうかを検出する を指定しています。
AWSTemplateFormatVersion: "2010-09-09"
Description: "Setup Control Tower Control"
Resources:
TestControl:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_EBS_OPTIMIZED_INSTANCE"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
上記テンプレートを利用して CloudFormation スタックを作成すると、約 3分ほどでスタックの作成が完了しました。

スタック作成の完了後、Control Tower の画面にて、指定した OU にガードレールがアタッチされていることが確認できます。今回は Sandbox という OU を対象にしています。

パターン 2 : CloudFormation で有効化したガードレールを無効化
続いて、CloudFormation で有効化したガードレールを無効化します。
結論から述べると、CloudFormation のスタックを削除することでガードレールが対象の OU から外れます。
以下はスタック削除後の状態です。先ほど追加された Sandbox がなくなっていることがわかるかと思います。

下記のように、DisabledControl を利用して無効化ができないか試してみましたが、"Unrecognized resource types" のエラーが出てしまったので、どうやら現状は EnabledControl のみサポートされている様です。(念の為、"DisableControl" など文字列を変えて試してみましたが、同じ結果でした)
AWSTemplateFormatVersion: "2010-09-09"
Description: "Setup Control Tower Control"
Resources:
TestControl:
Type: "AWS::ControlTower::DisabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_EBS_OPTIMIZED_INSTANCE"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
パターン 3 : 手動で有効化済みのガードレールに対して CloudFormation で有効化を実行してみる
続いて、既に手動で有効化されているガードレールに対し、CloudFormation で有効化のリクエストを実行してみました。
結果としては失敗し、下記のように AlreadyExists というエラーが出ました。後述しますが、既に手動で有効化済みのガードレールはインポートができますので、インポートを利用して CloudFormation スタックの管理下におきましょう。

パターン 4 : 11個以上のガードレールを CloudFormation で有効化してみる
公式ドキュメントには下記の様に「同時操作は 10個まで」と記載があるので、11個以上のガードレール(全て有効化されていないもの)を同時に有効化してみます。
The limit for EnableControl and DisableControl updates in AWS Control Tower is 10 concurrent operations.
下記のテンプレートを作成してみました。11個のガードレールを有効化するテンプレートになっています。
AWSTemplateFormatVersion: "2010-09-09"
Description: "Setup Control Tower Control"
Resources:
TestControl01:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_ENCRYPTED_VOLUMES"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl02:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_EBS_OPTIMIZED_INSTANCE"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl03:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_EC2_VOLUME_INUSE_CHECK"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl04:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RDS_INSTANCE_PUBLIC_ACCESS_CHECK"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl05:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RDS_SNAPSHOTS_PUBLIC_PROHIBITED"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl06:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RDS_STORAGE_ENCRYPTED"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl07:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RESTRICTED_COMMON_PORTS"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl08:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RESTRICT_ROOT_USER"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl09:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RESTRICT_ROOT_USER_ACCESS_KEYS"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl10:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_ROOT_ACCOUNT_MFA_ENABLED"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl11:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_S3_BUCKET_PUBLIC_READ_PROHIBITED"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
実行したところ、下記の様なエラーが発生し、スタック作成が失敗しました。

また、CloudFormation のスタック作成イベントを見ていると、全てロールバックされるのではなく、一部が DELETE_SKIPPED となっており、Control Tower 側では一部ガードレールが有効化された状態で残っていました。


上記より、予期せぬ状態になってしまう可能性があるため、一度に 10個以上のガードレールを一気に設定するのは避けたほうがよさそうです。
ただ、あくまで「同時に 10個を超えるガードレール適用が NG」であるため、下記の様に 11個目以降のガードレールを一時的にコメントアウトし、コメントアウトを少しずつ外して変更セットの適用を繰り返せば 1つのスタックで 10個以上のガードレールを管理できます。ただ、結構手間ですし、ガードレールは 10個以上有効化したいケースも多いかと思いますので、改善を期待したいところです。
AWSTemplateFormatVersion: "2010-09-09"
Description: "Setup Control Tower Control"
Resources:
TestControl01:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_ENCRYPTED_VOLUMES"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl02:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_EBS_OPTIMIZED_INSTANCE"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl03:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_EC2_VOLUME_INUSE_CHECK"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl04:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RDS_INSTANCE_PUBLIC_ACCESS_CHECK"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl05:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RDS_SNAPSHOTS_PUBLIC_PROHIBITED"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl06:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RDS_STORAGE_ENCRYPTED"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl07:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RESTRICTED_COMMON_PORTS"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl08:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RESTRICT_ROOT_USER"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl09:
Type: "AWS::ControlTower::EnabledControl"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_RESTRICT_ROOT_USER_ACCESS_KEYS"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
TestControl10:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_ROOT_ACCOUNT_MFA_ENABLED"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
#TestControl11:
# Type: "AWS::ControlTower::EnabledControl"
# DeletionPolicy: "Retain"
# Properties:
# ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_S3_BUCKET_PUBLIC_READ_PROHIBITED"
# TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
パターン 5 : 既に有効化済みのガードレールを CloudFormation スタックにインポートする
既に Control Tower が有効化されている環境では、当然ながらガードレール設定が既にされているものと思います。そのため、既に手動で有効化したガードレールを CloudFormation でインポートできるかも試してみます。
下記の様に、既存リソースをインポートするための記法に従い、CloudFormation テンプレートを用意します。
AWSTemplateFormatVersion: "2010-09-09"
Description: "Setup Control Tower Control"
Resources:
TestControl03:
Type: "AWS::ControlTower::EnabledControl"
DeletionPolicy: "Retain"
Properties:
ControlIdentifier: "arn:aws:controltower:ap-northeast-1::control/AWS-GR_EC2_VOLUME_INUSE_CHECK"
TargetIdentifier: "arn:aws:organizations::000011112222:ou/o-aaaabbbb/ou-aaaa-bbbb"
コンソールより、スタックのインポートを進めると、下記のように ControlIdentifier と TargetIdentifier の入力を求められるので、テンプレート内と同じ値を指定してスタックの作成を進めます。

スタックの作成を実行したところ、無事にインポートができました。インポートに対応している様ですね。

手順は省略しますが、テンプレート内の DeletionPolicy: "Retain" 部分を削除するようにスタックを更新したのち、スタック自体を削除したところガードレールが外れていたので、問題なくインポートが機能しているものと思われます。
おわりに
Control Tower のアップデートで、ガードレールの有効化/無効化 が API と CloudFormation を利用して実施できる様になりました。
手作業でやる必要があった Control Tower のガードレール有効化作業から解放されると思うと、個人的にはなかなか嬉しいです。
以上、AWS 事業本部の大前でした。








