AWS Control TowerのアカウントファクトリーをAWS CLIで利用する

目次

はじめに

AWSを効率的に利用する上で、AWSのマルチアカウントでの管理は欠かせない手法です。本ブログでも度々取り上げているように、Audit, Log Archive, Shared Service, Networkなど特定の機能単位でアカウントを分割して、管理アカウントと合わせてランディングゾーンと呼ばれるセキュリティ統制やスケーラビリティ、運用の効率性などの一貫したガバナンスを構成する方法は、AWSからも推奨される手法です。

What Is AWS Control Tower? - AWS Control Tower

AWSマルチアカウント管理を実践する上で、AWS Organizationsを利用することが前提となりますが、その利便性を更に高めてくれるのがAWS Control Towerです。AWS Control Towerはランディングゾーンの構成を支援するサービスであり、これを利用することで例えば各アカウントのセキュリティ状態を管理するAWS Security Hubのスコアリングに必要となるAWS Configの有効化をまとめて行ってくれたり、Cloudtrailの証跡をOrganizationsでまとめて取得する設定を行うなど、マルチアカウントで利用する上で便利な設定の多くを支援してくれます。

AWS Control Towerの詳細な機能解説は別記事に譲るとして、本記事では、AWS Control Towerの一機能であるアカウントファクトリーの利用について説明します。

AWS Control Towerのアカウントファクトリーとは

アカウントファクトリーを利用することで、マルチアカウント環境におけるAWSアカウントの新規作成が容易になります。AWSアカウントの通常の作成方法は、新規にAWSアカウントを取得する操作を行ってrootユーザーのメールアドレスや支払情報を登録します。既にAWS Organizationsが構成されているのであれば、AWS Organizationsの機能を利用して自身の組織のメンバーアカウントとして新規のAWSアカウントを作成することも可能です。AWS Control Towerでランディングゾーンを構成している環境では、AWS Control Towerの機能であるアカウントファクトリーを利用してAWSアカウントを作成します。

Account Factory

アカウントファクトリーで作成されるAWSアカウントと、スタンドアローンで作成されるAWSアカウントや、AWS Organizationsで作成されるAWSアカウントは何が異なるでしょうか。
アカウントファクトリーで作成されるAWSアカウントには、AWS Control Towerのベースライン設定が自動で反映され、AWS Control Towerの管理下に自動で登録されます。具体的には、下記ドキュメントに記載されているように、冒頭で述べたAWS Configの一括有効化の設定や、Cloudtrail証跡の組織レベルでの有効化、Control Towerを利用する上で必要なIAMロール、サービスロールの作成などがCloudFormation StackSetsでデプロイされます。

  • AWSControlTowerBP-BASELINE-CLOUDTRAIL
  • AWSControlTowerBP-BASELINE-CLOUDWATCH
  • AWSControlTowerBP-BASELINE-CONFIG
  • AWSControlTowerBP-BASELINE-ROLES
  • AWSControlTowerBP-BASELINE-SERVICE-ROLES
  • AWSControlTowerBP-BASELINE-SERVICE-LINKED-ROLES
  • AWSControlTowerBP-VPC-ACCOUNT-FACTORY-V1

Resource Considerations for Account Factory - AWS Control Tower

アカウントファクトリーの自動化手法

アカウントファクトリーによるAWSアカウントの新規作成は、AWSマネージメントコンソールから行うことができますが、ランディングゾーンによるマルチアカウント管理を行っていて、利用者用の新規AWSアカウントを繰り返し払い出す業務を行っている場合、毎回マネージメントコンソールで作成する手作業を省力化したいと思うようになります。
こうしたニーズによって登場したアカウントファクトリーの自動化手法が、Account Factory for Terraform (AFT)です。アカウントファクトリーによるAWSアカウントの新規作成をTerraformとGitOpsの手法で自動化することが可能です。

Provision accounts with AWS Control Tower Account Factory for Terraform (AFT) - AWS Control Tower

AFTが有用である一方、AFTは必要になるサービスが色々ありTerraformが前提となっていることも相まって、もっとシンプルな方法が欲しいと考えることもあるでしょう。

AWS Control Tower Account Factory for Terraform – account provisioning workflow

AFT Architecture - AWS Control Tower

AWSのブログではAFTとは異なる方法でアカウントファクトリーを自動化する方法が紹介されていますが、こちらも仕組化され過ぎていて、もっとシンプルに既存のアカウント申請のワークフローの中に処理を組み込む方法がないかと考えました。

How to automate the creation of multiple accounts in AWS Control Tower | AWS Cloud Operations & Migrations Blog

アカウントファクトリーをAWS CLIから利用する

アカウントファクトリーの実体は、AWS Service Catalogに登録されたポートフォリオと製品です。AWS Service CatalogはCloudFormationテンプレートなど管理者が構成済みのテンプレートを共有し、利用者が定義済みのリソースを簡単にデプロイすることが可能なサービスです。アカウントファクトリーはAWS Service Catalogのポートフォリオの一つとして登録されており、アカウントファクトリーでAWSアカウントを作成する際は、裏でAWS Service Catalogが実行されます。

AWS Control Tower Account Factory Portfolio

AWS Service CatalogにはAPIが用意されており、AWS CLIからも実行が可能となっているため、AWS Control Towerのアカウントファクトリーをシンプルな形で利用したい場合は、AWS CLIからAWS Service Catalogのコマンドを実行すれば良いことになります。AFTの利用についての情報は世の中で多くありますが、AWS Service CatalogのAWS CLIからの利用については情報が乏しいため、この記事に記載します。

aws servicecatalog provision-product \
--product-name "AWS Control Tower Account Factory" \
--provisioning-artifact-name "AWS Control Tower Account Factory" \
--provisioned-product-name "NewAWSAccount" \
--provisioning-parameters "file://AccountFactoryParameters.json"

AWS CLIのコマンドレファレンスは以下になります。

provision-product — AWS CLI 2.15.42 Command Reference

AWS CLIからAWS Control Towerのアカウントファクトリーで新しいAWSアカウントを作成する場合は、上記のようにaws servicecatalog provision-productのコマンドで実行することが可能です。オプションとして必須なのはproduct-name, provisioning-artifact-name, provisioned-product-name, provisioning-parametersになります。
product-name, provisioning-artifact-nameは"AWS Control Tower Account Factory"で固定で指定可能で、provisioned-product-nameには新しく作成するAWSアカウントの名前などを任意で指定することができます。provisioning-parametersファイルの内容はJSONで以下のように記述します。

[
  {
    "Key": "AccountEmail",
    "Value": "xxx@example.com"
  },
  {
    "Key": "AccountName",
    "Value": "New AWS Account"
  },
  {
    "Key": "ManagedOrganizationalUnit",
    "Value": "xxx (ou-xxx)"
  },
  {
    "Key": "SSOUserEmail",
    "Value": "AWSAdmin@example.com"
  },
  {
    "Key": "SSOUserFirstName",
    "Value": "xxx"
  },
  {
    "Key": "SSOUserLastName",
    "Value": "xxx"
  }
]
Key Value
AccountEmail 新しく作成するAWSアカウントのrootユーザー用の一意のメールアドレスを指定
AccountName 新しく作成するAWSアカウントの任意の名前を指定
ManagedOrganizationalUnit 新しく作成するAWSアカウントを組織のどのOUに所属させるかを名前とOU IDで指定
SSOUserEmail IAM Identity Centerで新しく作成するAWSアカウントへのログイン権限を持つSSOユーザーのメールアドレスを指定
SSOUserFirstName IAM Identity Centerで新しく作成するAWSアカウントへのログイン権限を持つSSOユーザーの名を指定
SSOUserLastName IAM Identity Centerで新しく作成するAWSアカウントへのログイン権限を持つSSOユーザーの姓を指定

アカウントファクトリーではAWS IAM Identity Centerの利用を半ば前提としており、パラメーターとして新しく作成するAWSアカウントの既定の管理者としてのSSOユーザーの指定を求められます。このユーザーに実際のメールアドレスを指定すると、IAM Identity Centerに新しいSSOユーザーが作成されるか、同メールアドレスの既存のSSOユーザーに新規AWSアカウントへのログイン権限が付与されます。アカウントファクトリーで新規作成されるAWSアカウントのrootユーザーは作成時点で誰もパスワードを知らない状態になるため、SSOUserEmailに実在しないメールアドレスを指定するなどして、新規AWSアカウントにログインできるユーザーがいない場合は、rootユーザーのパスワードリセットを行って、rootユーザーでアカウントへログインする必要が発生するかもしれません。AWS Organizationsの機能で新規AWSアカウントを作成すると、既定ではOrganizationAccountAccessRoleというスイッチ可能なロールがアカウントに作成されますが、アカウントファクトリーで作成した場合はこの名前のロールは作成されていませんでした。

Accessing member accounts in your organization - AWS Organizations

JSONのパラメーターファイルの中身については、以下のAWSドキュメントにも簡単に説明がありますが、説明がやや分かりにくいところもありました。

Walkthrough: Automate Account Provisioning in AWS Control Tower by Service Catalog APIs - AWS Control Tower

AWS Service Catalogの実行は非同期であるため、以下のようにコマンドの戻り値でStatusがCREATEDとなっていても実際のAWSアカウントの作成は完了していません。

{
    "RecordDetail": {
        "RecordId": "rec-xxxx",
        "ProvisionedProductName": "NewAWSAccount",
        "Status": "CREATED",
        "CreatedTime": "20xx-0x-xxT09:52:49.960000+00:00",
        "UpdatedTime": "20xx-0x-xxT09:52:49.969000+00:00",
        "ProvisionedProductType": "CONTROL_TOWER_ACCOUNT",
        "RecordType": "PROVISION_PRODUCT",
        "ProvisionedProductId": "pp-xxxx",
        "ProductId": "prod-xxx",
        "ProvisioningArtifactId": "pa-xxx",
        "PathId": "lpv3-xxx",
        "RecordErrors": [],
        "RecordTags": []
    }
}

アカウント作成が完了したかは、aws servicecatalog describe-provisioned-productを実行して、StatusがAVAILABLEになったことを確認しましょう。

aws servicecatalog describe-provisioned-product \
--name NewAWSAccount
{
    "ProvisionedProductDetail": {
        "Name": "NewAWSAccount",
        "Arn": "arn:aws:servicecatalog:ap-northeast-1:xxxxxxxxxxxx:stack/NewAWSAccount/pp-xxx",
        "Type": "CONTROL_TOWER_ACCOUNT",
        "Id": "pp-xxx",
        "Status": "AVAILABLE",
        "CreatedTime": "20xx-0x-xxT09:52:49.960000+00:00",
        "IdempotencyToken": "xxx-xxxx-xxxx-xxxx-xxx",
        "LastRecordId": "rec-xxx",
        "LastProvisioningRecordId": "rec-xxx",
        "LastSuccessfulProvisioningRecordId": "rec-xxx",
        "ProductId": "prod-xxx",
        "ProvisioningArtifactId": "pa-xxx"
    },
    "CloudWatchDashboards": []
}

なお、補足としてアカウントファクトリーで作成されたAWSアカウントはアカウントファクトリーで管理されているため、AWS OrganizationsのコンソールからOU移動などを行うと状態の不一致が発生し、OUへのAWSアカウントの再登録が必要になります。(30-40分程度要する)
アカウントファクトリーを使用して作成したAWSアカウントのOUを移動するなどパラメーターファイルで指定した内容を変更する際は、AWS Service Catalogのプロビジョニングされた製品の詳細から更新アクションで変更する必要があります。

まとめ

本記事では、AWS Control TowerのアカウントファクトリーでのAWSアカウントの作成を自動化する手法として、一番シンプルな方法であるAWS Service CatalogをAWS CLIから実行する手法を取り上げました。AWS CLIはシンプルで普遍的な実行方法であるため、既存のアカウント作成ワークフローにも取り込みやすく、AFTのような大きな仕組みをデプロイしなくても良いメリットがあります。
アカウントファクトリーの自動化手法はシンプルな方法が情報としてまとまった形で出てこないものになりますので、同様の要望をお持ちの方のお役に立てば幸いです。