Account Factory for Terraform (AFT)でマルチリージョンのカスタマイズを行う

東京以外に、バージニア・シンガポールリージョンをカスタマイズしてみます
2022.02.21

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

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

AWS Control Tower Account Factory for Terraform (AFT) を使って、AWSアカウントのカスタマイズをマルチリージョンに対して実施してみます。

AFTに関する過去の記事は以下ハッシュタグよりご確認ください。

経緯

Control Towerにてマルチアカウント管理を行う上で、セキュリティ・ガバナンス系サービスを利用する際に全リージョンに同じリソースを作成したいケースがあります。例えば、GuardDutyやSecurity Hubがそれに該当します。

これらをAFTで実現する場合どうするか調べました。

すると、すでにイシューにて「マルチリージョンのカスタマイズ方法」についてのやりとりを見つけました。

Customizations multiple regions · Issue #59 · aws-ia/terraform-aws-control_tower_account_factory

こういった要望を経て、現時点で最新バージョンの 1.3.3 では、Deploying customizations to multiple regions の Example が追加されました。

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

実際のExampleはこちらです。

Terraformでやってみる

前提

前々回で既存AWSアカウントに対してカスタマイズを実行しましたが、この続きとして行いますので、ここまでの作業が完了している前提で進めます。

手順

Exampleを参考に行います。 以下手順となります。

  • 1.aft-providers.jinjaにてproviderを追加する
  • 2.Terraformコードにてリソースブロックを追加する
  • 3.カスタマイズを実行する

「3.カスタマイズを実行する」については、前々回のカスタマイズと同じ作業になるので、こちらの記事の「3.手動でStep Functionsを実行」を参照ください。

1.aft-providers.jinjaにてproviderを追加する

そもそもJinjaとはPythonのテンプレートエンジンであり、Terraformコードを動的に生成するツールとのことです。AFTではterraformブロックとproviderブロックの生成にこのJinjaが使われているようです。

そのテンプレートである aft-providers.jijna`を以下ハイライト箇所を追加します。

aft-providers.jinja

## Auto generated providers.tf ##
## Updated on: {{ timestamp }} ##

provider "aws" {
  region = "{{ provider_region }}"
  assume_role {
    role_arn    = "{{ target_admin_role_arn }}"
  }
  default_tags {
    tags = {
      Project        = "Example",
      Terraform      = true,
      AFT            = true
    }
  }
}

provider "aws" {
  alias  = "ap-se-1"
  region = "ap-southeast-1"
  assume_role {
    role_arn    = "{{ target_admin_role_arn }}"
  }
  default_tags {
    tags = {
      Project        = "Example",
      Terraform      = true,
      AFT            = true
    }
  }
}

provider "aws" {
  alias  = "us-ea-1"
  region = "us-east-1"
  assume_role {
    role_arn    = "{{ target_admin_role_arn }}"
  }
  default_tags {
    tags = {
      Project        = "Example",
      Terraform      = true,
      AFT            = true
    }
  }
}

今回は、ホームリージョンである東京以外に、バージニアとシンガポールリージョンのproviderを追加しています。

2. Terraformコードにてリソースブロックを追加する

続いて、上記により生成される各リージョンのプロバイダーを使用し、S3バケットを3つのリージョンに作成するよう定義します。

s3.tf

data "aws_caller_identity" "current" {}

resource "aws_s3_bucket" "ap-ne-1" {
  bucket = "aft-test-${data.aws_caller_identity.current.account_id}-${local.regions.ap-ne-1}"
  tags = { Name = "aft-test-${data.aws_caller_identity.current.account_id}-${local.regions.ap-ne-1}" }
}

resource "aws_s3_bucket" "ap-se-1" {
  provider = aws.ap-se-1
  bucket = "aft-test-${data.aws_caller_identity.current.account_id}-${local.regions.ap-se-1}"
  tags = { Name = "aft-test-${data.aws_caller_identity.current.account_id}-${local.regions.ap-se-1}" }
}

resource "aws_s3_bucket" "us-ea-1" {
  provider = aws.us-ea-1
  bucket = "aft-test-${data.aws_caller_identity.current.account_id}-${local.regions.us-ea-1}"
  tags = { Name = "aft-test-${data.aws_caller_identity.current.account_id}-${local.regions.us-ea-1}" }
}

ポイントとしては、ハイライト箇所にて、それぞれバージニアとシンガポールリージョンのプロバイダーを指定している点です。

また、ここは個人の好みですが、Resourceブロック内のリージョン表記を全て短い略称にするために、以下のようなローカル変数を設定し使用しています。

locals.tf

locals {
  regions = {
    "ap-ne-1" = "ap-northeast-1", ## Tokyo
    "ap-se-1" = "ap-southeast-1", ## Singapore
    "us-ea-1" = "us-east-1",      ## Virginia 
  }
}

以上で、設定が完了しました。

実行結果

設定後にStep Functionsを実行してカスタマイズを行った結果、以下の通り3つのリージョンにS3バケットを作成することができました。

Shellでやってみる

AFTではTerraform以外にもPythonやShellスクリプトによってカスタマイズを行うことも可能です。実際、やりたい処理内容によってはTerraformよりも都合がいいものもあります。Shellスクリプトで上記同様に3つのリージョンに対して、何かコマンドを実行したい場合は、デフォルトで配置している api_helpersディレクトリ内の pre-api-helpers.sh などで以下のように実行できます。

例として、3つのリージョンに対してSecurity HubのCISベンチマークのスタンダードを無効化するコマンドとなります。

pre-api-helpers.sh

#!/bin/bash

echo "Executing Pre-API Helpers"

## Security HubにてCISスタンダードを無効化
accountId=`aws sts get-caller-identity --query "Account" --output text`
for region in ap-northeast-1 ap-southeast-1 us-east-1;do
  echo "##### disable CIS standard in ${region} for AccountID ${accountId}"
  aws --region $region  securityhub batch-disable-standards \
  --standards-subscription-arns "arn:aws:securityhub:${region}:${accountId}:subscription/cis-aws-foundations-benchmark/v/1.2.0"
done

終わりに

AFTでのマルチリージョンのアカウントカスタマイズを行いました。AFTはスピーディに改良がなされていくので、超ありがたいですしワクワクします。「Control Tower x Terraform 環境では AFT が鉄板」と言える日も近いかと! ぜひ使ってみてください。

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