[アップデート] Account Factory for Terraform (AFT) のカスタマイズ対象にログアーカイブ、監査、管理アカウントが追加に!

これで我が軍の包囲網(アカウントカスタマイズ)に隙間なし!
2022.06.14

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

ちゃだいん(@chazuke4649)です。

AWS Control Tower Account Factory for Terraform (AFT) のカスタマイズ対象にログアーカイブ、監査および管理アカウントが追加になりました!

以下対象バージョン1.4.0のリリース情報です。

  • Includes support for customizing Control Tower Shared Accounts (Log Archive, Audit), and the Organization Management Account.
  • AFT now uses an AWSAFTService role to deploy AFT resources, which is deployed in all managed accounts. The existing AWSAFTExecution role is now used for deploying customizations only. You can use IAM permissions boundaries to limit the permissions of the AWSAFTExecution role to match the permission requirements of your customizations, and limit their access to managed accounts.

引用元)Release 1.4.0 · aws-ia/terraform-aws-control_tower_account_factory

以下は公式ドキュメント側のリリース情報です。

AFT は、AWS Control Tower の共有アカウントの自動カスタマイズをサポートします - AWS Control Tower

何が嬉しい?

Control Tower管理のメンバーアカウントのカスタマイズやベースライン設定自動化を簡単に実現できるAFTですが、今までカスタマイズ対象アカウントにControl Tower/Organizationsの管理アカウント、ログアーカイブアカウント、監査アカウントは対象外でした。ですので、もしこれらアカウントも他と同様の設定にしたい場合は別途対応が必要でした。今回のアップデートで、管理アカウントを含む全てのアカウントをAFTにてカスタマイズできるようになりました。いわゆる地味に結構嬉しいアップデートです!

やってみた

1.AFTモジュールのバージョンのアップグレード

まずはTerraform RegistryのAFTモジュールのバージョンをアップグレードします。 現時点では最新版がv1.4.2なので、最新にまで上げます。

Release 1.4.2 · aws-ia/terraform-aws-control_tower_account_factory

## モジュールのバージョンアップのため、terraform initが必要
## さらに、AWSプロバイダーのバージョンも上げるため、-upgradeオプションを追加
terraform init -upgrade

Upgrading modules...
Downloading aws-ia/control_tower_account_factory/aws 1.4.2 for aft...

~中略~

Terraform has been successfully initialized!

## planが通るか試します
terraform plan

~中略~

Plan: 39 to add, 46 to change, 5 to destroy.

## 実際に環境適用します
terraform apply

~中略~

Apply complete! Resources: 39 added, 46 changed, 5 destroyed.

AFTモジュールのアップグレードが完了しました。

1.4.0のアップデートに AFT now uses an AWSAFTService role to deploy AFT resources, which is deployed in all managed accounts. とのことでしたので、管理アカウントで探してみたところ、確かに AWSAFTService IAMロールが作成されていました。

2.グローバルカスタマイズを追加

AFTのカスタマイズには、全てのアカウントに適用されるグローバルカスタマイズと、一部指定した対象のみに適用されるアカウントカスタマイズがありますが、今回はグローバルカスタマイズ設定にS3バケットを作るTerraformコードを追加してみます。 コードを配置するリポジトリはAFTモジュール適用時に指定した4種類のリポジトリのうち、グローバルカスタマイズのリポジトリを使用します。

% tree global-customizations
global-customizations
├── api_helpers
│   ├── post-api-helpers.sh
│   ├── pre-api-helpers.sh
│   └── python
│       └── requirements.txt
└── terraform
    ├── aft-providers.jinja
    ├── backend.jinja
    └── s3.tf ## <-ここに配置

とてもシンプルにS3バケットだけを作成します。

data "aws_caller_identity" "current" {}

resource "aws_s3_bucket" "test_bucket" {
  bucket = "chadain-aft-test-temp-bucket-${data.aws_caller_identity.current.account_id}"
  acl    = "private"
  tags = { AccountId = "chadain-aft-test-temp-bucket-${data.aws_caller_identity.current.account_id}" }
}

問題なければ、リモートリポジトリにプッシュして完了です。

3.既存アカウントのAFT登録

今回対象のログアーカイブ、監査、管理アカウントをAFTに登録するには、基本的に以下と同様と思ってよさそうです。

[待望アップデート] Account Factory for Terraform (AFT) に 既存AWSアカウントの追加登録が可能に! | DevelopersIO

ただし、これらコアアカウントはService Catalog製品は作成されていないので、そこを意識する必要はなさそうです。

この作業では、4種類のAFT関連リポジトリのうち、アカウントリクエストのリポジトリを使用します。

以下のように3つのAWSアカウントを登録してみました。

% tree request
request
├── README.md
├── examples
│   └── account-request.tf
└── terraform
    ├── account-request.tf ## <-ここにコードを追加
    ├── aft-providers.jinja
    ├── backend.jinja
    ├── locals.tf
    └── modules
        └── aft-account-request
            ├── ddb.tf
            ├── variables.tf
            └── versions.tf
#-------------------------------------------------------
# Core Accounts
#-------------------------------------------------------
## 000000000000 ## 管理しやすくするためにAWSアカウントIDをコメントアウトで記載しておく
module "master" {
  source = "./modules/aft-account-request"

  control_tower_parameters = {
    AccountEmail              = "aws+master@example.jp" ## 管理アカウントのEメールアドレスを入力
    AccountName               = "Payer" ## 指定しているAWSアカウント名を入力
    ManagedOrganizationalUnit = "MasterOU" ## OU名を入力(※本環境では便宜上当該OUに配置しているが、デフォルトならRootで問題なさそう)
    SSOUserEmail              = "chadain@example.jp" ## 使用しないので任意の値で問題なさそうだが、念の為他と合わせてControl Tower有効化に使用したSSOユーザーのメールアドレスを入力
    SSOUserFirstName          = "NOT" ## 当該値でOK
    SSOUserLastName           = "USE" ## 当該値でOK (以下監査とログアーカイブも基本同様)
  }

  account_tags = {
    "Project"     = "Master"
    "Environment" = "Production"
    "AFT"         = true
  }

  change_management_parameters = {
    change_requested_by = "chadain"
    change_reason       = "Adding existing account to AFT"
  }

  custom_fields = {
    custom1 = "a"
    custom2 = "b"
  }
}

## 111111111111
module "audit" {
  source = "./modules/aft-account-request"

  control_tower_parameters = {
    AccountEmail              = "aws+audit@example.jp"
    AccountName               = "Audit"
    ManagedOrganizationalUnit = "Security"
    SSOUserEmail              = "chadain@example.jp"
    SSOUserFirstName          = "NOT"
    SSOUserLastName           = "USE"
  }

  account_tags = {
    "Project"     = "Audit"
    "Environment" = "Production"
    "AFT"         = true
  }

  change_management_parameters = {
    change_requested_by = "chadain"
    change_reason       = "Adding existing account to AFT"
  }

  custom_fields = {
    custom1 = "a"
    custom2 = "b"
  }
}

## 222222222222
module "log_archive" {
  source = "./modules/aft-account-request"

  control_tower_parameters = {
    AccountEmail              = "aws+log-archive@example.jp"
    AccountName               = "Log-Archive"
    ManagedOrganizationalUnit = "Security"
    SSOUserEmail              = "chadain@example.jp"
    SSOUserFirstName          = "NOT"
    SSOUserLastName           = "USE"
  }

  account_tags = {
    "Project"     = "LogArchive"
    "Environment" = "Production"
    "AFT"         = true
  }

  change_management_parameters = {
    change_requested_by = "chadain"
    change_reason       = "Adding existing account to AFT"
  }

  custom_fields = {
    custom1 = "a"
    custom2 = "b"
  }
}

問題なければ、リモートリポジトリにプッシュします。

4.確認

3.を行うと、AFT環境の各リソースが順次発火され、自動的にジョブが実行されます。

まずは、リクエストリポジトリへのプッシュをCodePipelineが検知して、ct-aft-account-requestが実行されます。(下図は完了後ですが直後はステータスが実行中になります)



上記を受け、次はStep Functionsステートマシンの aft-account-provisioning-framework が実行され、3つのAWSアカウントのカスタマイゼーションのためのCodePipelineがそえぞれ1つずつ作成される指示をします。

上記を受け、次は同じくステートマシンの aft-account-provisioning-customizations が実行され、3つのCodePipelineにグローバルカスタマイズとアカウントカスタマイズのコードをインプットとして渡します(ただし今回はアカウントカスタマイズでは何も追加されません)

あとは各アカウントのカスタマイズ実行用のCodePipelineが完了するのを待ちます。
完了すると下図のようにステータスが成功になりました。

管理アカウントにログインし、S3バケットが作成されているか確認すると、確かにS3バケットが確認できました。

検証は以上です。

終わりに

今回のアップデートで、AFTで基本的に全てのControl Towerに所属するAWSアカウントのカスタマイズが可能となりました。よりAFTに寄せられることが増えシンプルな構成にできそうです。やったぜ!!!

それではこの辺で。ちゃだいん(@chazuke4649)でした。