Control Towerのカスタマイズ(CfCT)を使ってSCPの作成・変更をやってみた

Control TowerのカスタマイズソリューションでSCPを実装してみました。結構大きな注意点があるので利用するときは気をつけましょう。
2021.10.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

最近Control Towerのカスタマイズソリューション(CfCT)にハマっている鈴木です。

今回はCfCTを使ってSCPを実装してみました。

概要

CfCTはAWSのソリューションでCodeCommit、もしくはS3にアップロードした情報からCloudFormationスタックやSCPを指定したOUやアカウントに自動展開してくれるソリューションです。

CloudFormationスタックの展開は何度か実施していますが、SCPはまだワークショップしか試してなかったので、SCPをCfCTで実装して動作の確認をしていきます。

手軽にマルチアカウント環境にSCPを作成できるのですが、、CfCTを使ってSCPを管理するには問題となる点もあったので合わせて解説しています。

前提

  • Control Tower有効化済
  • Control Towerのカスタマイズ展開済
  • Gitが利用できること

CfCTの展開がまだの人

以下の記事の「やってみた-CfCTの展開」まで実施して、CodeCommitのクローンまで完了させてください。デフォルトで入っているmanifest.yaml等は全て削除してください。

やってみる

それでは早速やっていきます。

ポリシーファイルの作成

クローンで作成されたフォルダ直下にpoliciesというフォルダを作成して、その中にSCPとして設定するポリシーを保存していきます。今回はサンプルとしてIAMユーザーの作成禁止と指定したリージョン以外を禁止するポリシーを作成していきます。

custom-control-tower-configuration
└── policies
    ├── DenyCreateUser.json
    └── RegionRestrictions.json

policies/DenyCreateUser.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyCreateUser",
            "Effect": "Deny",
            "Action": [
                "iam:CreateUser",
                "iam:DeleteUser",
                "iam:CreateLoginProfile",
                "iam:CreateAccessKey"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

policies/RegionRestrictions.json

{
    "Version": "2012-10-17",
    "Statement": {
        "Sid": "RegionRestrictions",
        "Effect": "Deny",
        "NotAction": [
            "a4b:*",
            "acm:*",
            "aws-marketplace-management:*",
            "aws-marketplace:*",
            "aws-portal:*",
            "awsbillingconsole:*",
            "budgets:*",
            "ce:*",
            "chime:*",
            "cloudfront:*",
            "config:*",
            "cur:*",
            "directconnect:*",
            "ec2:DescribeRegions",
            "ec2:DescribeTransitGateways",
            "ec2:DescribeVpnGateways",
            "fms:*",
            "globalaccelerator:*",
            "health:*",
            "iam:*",
            "importexport:*",
            "kms:*",
            "mobileanalytics:*",
            "networkmanager:*",
            "organizations:*",
            "pricing:*",
            "route53:*",
            "route53domains:*",
            "s3:GetAccountPublic*",
            "s3:ListAllMyBuckets",
            "s3:PutAccountPublic*",
            "shield:*",
            "sts:*",
            "support:*",
            "trustedadvisor:*",
            "waf-regional:*",
            "waf:*",
            "wafv2:*",
            "wellarchitected:*"
        ],
        "Resource": "*",
        "Condition": {
            "StringNotEquals": {
                "aws:RequestedRegion": [
                    "ap-northeast-1",
                    "us-east-1",
                    "ap-southeast-1"
                ]
            },
            "ArnNotLike": {
                "aws:PrincipalARN": [
                    "arn:aws:iam::*:role/AWSControlTowerExecution",
                    "arn:aws:iam::*:role/aws-controltower-ConfigRecorderRole"
                ]
            }
        }
    }
}

マニフェストファイルの作成

ポリシーの作成が完了したら、次はマニフェストファイルを作成していきます。

フォルダ直下にmanifest.yamlというファイル名で作成してください。

manifest.yaml

---
#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 - DenyCreateUser.json
  - name: region-restrictions
    description: Prohibit the use of regions other than the specified ones.
    resource_file: policies/RegionRestrictions.json
    deploy_method: scp
    #Apply to the following OU(s)
    deployment_targets:
      organizational_units:
        - Security
        - Sandbox
  # Control Tower Custom Service Control Policies - RegionRestrictions.json
  - name: deny-create-user
    description: Prohibit the creation of IAM users.
    resource_file: policies/DenyCreateUser.json
    deploy_method: scp
    #Apply to the following OU(s)
    deployment_targets:
      organizational_units:
        - Sandbox

先ほど作成したポリシーをSCPとしてアタッチする対象を定義しています。指定したリージョン以外を利用させないポリシー(RegionRestrictions.json)はSecurity、Sandbox2つOUにアタッチ、IAMユーザーの作成禁止ポリシーは(RegionRestrictions.json)SandboxのOUのみにアタッチしています。

この時点でのフォルダ構成はこんな感じです。

custom-control-tower-configuration
├── manifest.yaml
└── policies
    ├── DenyCreateUser.json
    └── RegionRestrictions.json

SCPの展開

それでは作成したマニフェストファイルとポリシーをPushしてSCPを展開してみましょう。

$ git add -A 
$ git commit -m 'Add scp'
$ git push

CodeCommitへのPushが完了すると、CodePipelineが起動します。15分程度かかるので、終わったら成功したことを確認しましょう。

まずはSandboxのOUを確認してみます。SandboxOUではマニフェストファイルで定義したように2つのSCPがアタッチされていることが確認できます。

SecurityOUを確認してみると、こちらはリージョン制限のSCPしかアタッチされていないことが確認できます。

とっても簡単にポリシーの作成とOUへのアタッチをマニフェストファイルに定義することができました。

SCPの変更

SCPが設定できたので、次は展開したSCPに変更を加えてみます。ポリシー内容の変更として、DenyCreateUser.jsonから"iam:CreateAccessKey"を削除します。

policies/DenyCreateUser.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyCreateUser",
            "Effect": "Deny",
            "Action": [
                "iam:CreateUser",
                "iam:DeleteUser",
                "iam:CreateLoginProfile"
            -   "iam:CreateAccessKey"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

この状態でPushしてSCPの内容が書き換わっているのかを確認します。

無事jsonへの変更内容がSCP側にも反映されていることが確認できました。

注意点

CfCTでSCPを取り扱う時の注意点を記載しておきます。

SCPの削除・OUからのデタッチはできない

執筆時点ではCfCTではSCPの作成とOUのアタッチはできますが、SCPの削除やOUからのデタッチはできませんでした。

アタッチするOUを変更するため、マニフェストファイルのdeny-create-userアタッチ対象OUをSandboxからSecurityに変更を試してみます。

manifest.yaml

---
#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 - DenyCreateUser.json
  - name: region-restrictions
    description: Prohibit the use of regions other than the specified ones.
    resource_file: policies/RegionRestrictions.json
    deploy_method: scp
    #Apply to the following OU(s)
    deployment_targets:
      organizational_units:
        - Security
        - Sandbox
  # Control Tower Custom Service Control Policies - RegionRestrictions.json
  - name: deny-create-user
    description: Prohibit the creation of IAM users.
    resource_file: policies/DenyCreateUser.json
    deploy_method: scp
    #Apply to the following OU(s)
    deployment_targets:
      organizational_units:
  -      - Sandbox
  +      - Security
```

PushしてSCPの状態を確認すると、マニフェストファイルでSandboxから削除したはずのdeny-create-userのSCPがアタッチされたままになっていました。(追加したSecurityOUにはSCPが追加されていたのでアタッチは問題ない。)

また、マニフェストファイルのセクション丸々コメントアウトして削除の動作をしてくれるかを確認してみました。

manifest.yaml

---
#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 - DenyCreateUser.json
  - name: region-restrictions
    description: Prohibit the use of regions other than the specified ones.
    resource_file: policies/RegionRestrictions.json
    deploy_method: scp
    #Apply to the following OU(s)
    deployment_targets:
      organizational_units:
        - Security
        - Sandbox
# Control Tower Custom Service Control Policies - RegionRestrictions.json
  # - name: deny-create-user
  #   description: Prohibit the creation of IAM users.
  #   resource_file: policies/DenyCreateUser.json
  #   deploy_method: scp
  #   #Apply to the following OU(s)
  #   deployment_targets:
  #     organizational_units:
  #       - Security

SCPを確認するとセクションをコメントアウトしたのにも関わらずdeny-create-userのポリシーが残ったままとなっていました。当然OUにもアタッチされたままです。

ということで、CfCTを使ったSCPの管理ではSCPの作成とアタッチはできますが、削除とデタッチはできませんでした。正直マニフェストファイルからの変更が反映されていないのはIaCベースの考え方からすると、とても違和感がありますね…

マニフェストファイルで定義した情報と実態が一致しないケースが発生するということを覚えておきましょう。

ですが、この問題については既にGitHub上のIssueとして上がっており、ロードマップに含まれているため将来リリース予定とのコメントがありました。いつ来るかは分かりませんがアップデートに期待しましょう!

まとめ

CfCTを使ってSCPの作成・OUへのアタッチ、変更をマニフェストファイル側からやってみました。現時点ではOUからのデタッチやSCP自体の削除ができないという注意点はあるため、SCPの管理として利用するかは少し考える必要がありそうです。

SCPの作成やOUへのアタッチはCfCTから実施、デタッチなどはコンソールから実施するなど割り切った上で、アップデートを待つのであれば採用してもいいかなと個人的には思いました。

参考