

# Provision and manage accounts in AWS Control Tower
<a name="provision-and-manage-accounts"></a>

This chapter includes:
+ an overview and procedures for provisioning and managing new member accounts in AWS Control Tower.
+ an overview and procedures for enrolling an existing AWS account into AWS Control Tower.

For general information about accounts in AWS Control Tower, see [About AWS accounts in AWS Control Tower](accounts.md). For information about enrolling multiple acounts into AWS Control Tower, see [Register an existing organizational unit with AWS Control Tower](importing-existing.md).

**Note**  
Single account provision, update and customization must target an organizational unit (OU) with AWSControlTowerBaseline enabled. If an OU does not have the AWSControlTowerBaseline enabled, you can activate account auto-enrollment or use ResetEnabledBaseline and ResetEnabledControl APIs on EnabledBaselines and EnabledControls on that OU to enroll accounts. For details of AWSControlTowerBaseline, see: [Baseline types that apply at the OU level](types-of-baselines.md#ou-baseline-types). 

**Note**  
You can perform up to five (5) account-related operations concurrently, including provisioning, updating, and enrolling.

## Permissions required for provisioning accounts
<a name="permissions"></a>

With the appropriate user group permissions, provisioners can specify standardized baselines and network configurations for any accounts in their organization.

When you create accounts from the AWS Control Tower console with Account Factory, you must be signed into an account with an IAM user that has the `AWSServiceCatalogEndUserFullAccess` policy enabled, along with permissions to use the AWS Control Tower console, and you cannot be signed in as the **Root** user.

**Note**  
When provisioning an account, the account requester always must have the `CreateAccount` and the `DescribeCreateAccountStatus` permissions. This permission set is part of the **Admin** role, and it is given automatically when a requester assumes the **Admin** role. If you delegate permission to provision accounts, you may need to add these permissions directly for the account requestors.

For general information about permissions required in AWS Control Tower, see [Using identity-based policies (IAM policies) for AWS Control Tower](access-control-managing-permissions.md). For information about roles and accounts in AWS Control Tower, see [Roles and accounts](https://docs.aws.amazon.com//controltower/latest/userguide/roles.html).

# Provision accounts within AWS Control Tower
<a name="methods-of-provisioning"></a>

AWS Control Tower provides several methods for creating and updating member accounts. Some methods are primarily console-based, and some methods are primarily automated.

**Overview**

One standard way to create member accounts in AWS Control Tower is through Account Factory, a console-based product that's part of the Service Catalog. Also, from the AWS Control Tower console, you can use **Create account** as a method to provision new accounts, as well as **Enroll account** to enroll existing AWS accounts into AWS Control Tower, if your landing zone is not in a state of drift. 

With Account Factory, you can provision basic accounts, relying on the AWS Control Tower default settings. You also can provision *customized* accounts that meet requirements for specialized use cases.

[Account Factory Customization (AFC)](https://docs.aws.amazon.com//controltower/latest/userguide/af-customization-page.html) is a way of provisioning customized accounts from the AWS Control Tower console, and it automates the customization and deployment of your accounts. It allows console-based, automated provisioning, after some one-time setup steps, which eliminates the need to write scripts or set up pipelines. For more information, see [Customize accounts with Account Factory Customization (AFC)](af-customization-page.md).

**Automatic enrollment**  
You also can create AWS accounts *outside* AWS Control Tower and move them into an OU that's registered with AWS Control Tower, without creating inheritance drift, if you opt into the **Automated account enrollment** feature of your landing zone **Settings**. For more information, see [Move and enroll accounts with auto-enrollment](account-auto-enrollment.md).

**Console-based methods:**
+ Through the Account Factory console that is part of AWS Service Catalog, for basic or customized accounts. Review [Provision and manage accounts with Account Factory](account-factory.md) for details and instructions.
+ Through automated enrollment, by moving an account into an OU from the console. See [Move and enroll accounts with auto-enrollment](account-auto-enrollment.md)
+ Through the **Enroll account** feature within AWS Control Tower, if your landing zone is not in a state of drift. See [Enroll an existing account from the AWS Control Tower console](quick-account-provisioning.md).
+ In the AWS Control Tower console, you can use Account Factory to create, update, or enroll up to five accounts at the same time.

**Automated methods:**
+ **Lambda code: **From your AWS Control Tower landing zone's management account, using Lambda code and appropriate IAM roles. See [Automated Account Provisioning with IAM Roles](https://docs.aws.amazon.com//controltower/latest/userguide/roles-how.html#stacksets-and-roles).
+ **Terraform: **From the AWS Control Tower Account Factory for Terraform (AFT), which relies on Account Factory and a GitOps model to allow automation of account provisioning and updating. See [Provision accounts with AWS Control Tower Account Factory for Terraform (AFT)](taf-account-provisioning.md).
+ Through automated enrollment, by moving an existing account into an OU using APIs. See [Move and enroll accounts with auto-enrollment](account-auto-enrollment.md)
+ **Account Factory customization in the AWS Control Tower console:** After the setup steps, future provisioning of customized accounts requires no additional configuration or pipeline maintenance. Accounts are provisioned by means of a AWS Service Catalog product called a *blueprint*. A blueprint can use CloudFormation templates, or Terraform templates.
**Note**  
CloudFormation blueprints can deploy resources to multiple Regions. Terraform blueprints can deploy resources to a single Region only. By default, that is the home Region.

# Provision accounts in the AWS Control Tower console
<a name="account-create-console"></a>

 The following procedure describes how to create and provision accounts as a user in IAM Identity Center through the AWS Control Tower console. This procedure also is referred to as *manual account provisioning*. Optionally, you may be able to provision AWS Control Tower accounts programmatically, with the AWS CLI, with Service Catalog APIs, or with AWS Control Tower Account Factory for Terraform (AFT), or automatically enroll an existing account into a registered OU. You may be able to provision customized accounts in the console if you've previously set up custom blueprints. For more information about customization, see [Customize accounts with Account Factory Customization (AFC)](af-customization-page.md).

**To provision accounts individually in the AWS Control Tower console, as a user**

1. Sign in to AWS and navigate to the AWS Control Tower console..

1. From the left navigation, choose **Organizations** to view the **Organization** page.

1. From the upper right, choose **Create resources**. 

1. In the dropdown menu, choose **Create account**.

1. Fill in the information on the page, and keep the following in mind:
   + The **Account email** must be an email address that isn't already associated with an AWS account. 
   + The display name is the name you want to see for this account.

1. Fill in the fields to define your **Access configuration**, with an IAM Identity Center email address and user name.

1. Select a registered OU from the dropdown list, to indicate the OU in which you'd like to provision the account. 

1. Optionally use a pre-defined blueprint to provision your account with customized resources. You can do this task later. 

1. Review your account selections, and then choose **Create account**, in the lower right. 

1. Your account is now being provisioned. It can take a few minutes to complete. You can refresh the page to update the displayed status information.
**Note**  
Up to five accounts can be provisioned at a time.

# View your accounts
<a name="view-your-accounts"></a>

The **Organization** page lists all OUs and accounts in your organization, regardless of OU or enrollment status in AWS Control Tower. You can view and enroll member accounts into AWS Control Tower—individually or by OU groups—if each account meets the prerequisites for enrollment.

**To view a specific account**
+ Navigate to the **Organization** page.
+ You can choose **Accounts only** from the dropdown menu at the upper right.
+ Then, select the name of your account from the table.
+ Alternatively, you can select the name of the parent OU from the table, and view a list of all accounts within that OU on the **Details** page for that OU.

On the **Organization** page and the **Account details** page, you can see the account's **State**, which is one of these:
+ **Not enrolled** – The account is a member of the parent OU, but it is not fully managed by AWS Control Tower. If the parent OU is registered, the account is governed by the preventive controls configured for its registered parent OU, but the OU’s detective controls do not apply to this account. If the parent OU is unregistered, no controls apply to this account. 
+ **Enrolling** – The account is being brought into governance by AWS Control Tower. We are aligning the account with the control configuration for the parent OU. This process may require several minutes per account resource. 
+ **Enrolled** – The account is governed by the controls configured for its parent OU. It is fully managed by AWS Control Tower.
+ **Enrollment failed** – The account could not be enrolled in AWS Control Tower. For more information, see [Common causes for failure of enrollment](quick-account-provisioning.md#common-causes-for-enrollment-failure).
+ **Update available** – The account has an update available. Accounts in this state are still **Enrolled**, but the account must be updated to reflect recent changes made to your environment. To update a single account, navigate to the account detail page and select **Update account**.

  If you have multiple accounts with this state under a single OU, you can choose to **Re-register** the OU and update those accounts together. 

# About enrolling existing accounts
<a name="enroll-account"></a>

You can extend AWS Control Tower governance to an individual, existing AWS account when you *enroll* it into an organizational unit (OU) that's already governed by AWS Control Tower. Eligible accounts exist in *unregistered OUs that are part of the same AWS Organizations organization* as the AWS Control Tower OU.

Several methods exist for enrolling accounts into AWS Control Tower. **The information on this page applies to all methods of enrollment.**

**Note**  
You cannot enroll an existing AWS account to serve as your audit or log archive account except during initial landing zone setup.

## What happens during account enrollment
<a name="what-happens-during-account-enrollment"></a>

During the enrollment process, AWS Control Tower performs these actions:
+ Baselines the account, which includes deploying these stack sets:
  + `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`

  It is a good idea to review the templates of these stack sets and make sure that they don’t conflict with your existing policies.
+ Identifies the account through AWS IAM Identity Center or AWS Organizations.
+ Places the account into the OU that you've specified. Be sure to apply all SCPs that are applied in the current OU, so that your security posture remains consistent.
+ Applies mandatory controls to the account by means of the SCPs that apply to the selected OU as a whole.
+ Enables AWS Config and configures it to record all resources in the account.
+ Adds the AWS Config rules that apply the AWS Control Tower detective controls to the account.

**Accounts and organization-level CloudTrail trails**  
For landing zone versions 3.1 and greater, if you've selected the optional AWS CloudTrail integration in landing zone settings:  
All member accounts in an OU are governed by the AWS CloudTrail trail for the OU, enrolled or not.
When you enroll an account into AWS Control Tower, your account is governed by the AWS CloudTrail trail for the new organization. If you have an existing deployment of a CloudTrail trail, you may see duplicate charges unless you delete the existing trail for the account before you enroll it in AWS Control Tower. 
If you move an account into a registered OU—for example by means of the AWS Organizations console or APIs—you may wish to remove any remaining account-level trails for the account. If you have an existing deployment of a CloudTrail trail, you will incur duplicate CloudTrail charges.
If you update your landing zone and choose to opt out of organization-level trails, or if your landing zone is older than version 3.0, organization-level CloudTrail trails do not apply to your accounts.

## Enroll existing accounts with VPCs
<a name="enroll-existing-accounts-with-vpcs"></a>

AWS Control Tower handles VPCs differently when you provision a new account in Account Factory than when you enroll an existing account.
+ When you create a new account, AWS Control Tower automatically removes the AWS default VPC and creates a new VPC for that account.
+ When you enroll an existing account, AWS Control Tower does not create a new VPC for that account.
+ When you enroll an existing account, AWS Control Tower does not remove any existing VPC or AWS default VPC associated with the account.

**Tip**  
You can change the default behavior for new accounts by configuring Account Factory, so it does not set up a VPC by default for accounts in your organization under AWS Control Tower. For more information, see [Create an Account in AWS Control Tower Without a VPC](configure-without-vpc.md#create-without-vpc).

## Enroll accounts with AWS Config resources
<a name="example-config-cli-commands"></a>

The account to be enrolled must not have existing AWS Config resources. See [Enroll accounts that have existing AWS Config resources](https://docs.aws.amazon.com//controltower/latest/userguide/existing-config-resources.html).

Here are some example AWS Config CLI commands you can use to determine the status of your existing account's AWS Config resources, such as the configuration recorder and delivery channel.

**View commands:**
+ `aws configservice describe-delivery-channels`
+ `aws configservice describe-delivery-channel-status`
+ `aws configservice describe-configuration-recorders`

The normal response is something like `"name": "default"`

**Delete commands:**
+ `aws configservice stop-configuration-recorder --configuration-recorder-name NAME-FROM-DESCRIBE-OUTPUT`
+ `aws configservice delete-delivery-channel --delivery-channel-name NAME-FROM-DESCRIBE-OUTPUT`
+ `aws configservice delete-configuration-recorder --configuration-recorder-name NAME-FROM-DESCRIBE-OUTPUT`

# Prerequisites for enrollment
<a name="enrollment-prerequisites"></a>

*This section describes how to enroll an existing AWS account into AWS Control Tower if you have not selected the optional auto-enroll feature on the landing zone **Settings** page, or if you are operating with a landing zone version previous to 3.1.*

These prerequisites are required before you can enroll an existing AWS account in AWS Control Tower:

**Note**  
The prerequisite to add the `AWSControlTowerExecution` role is not required if you have activated the AWS Control Tower auto-enroll capability in the landing zone **Settings** page, or if you are enrolling the account as part of a **Register OU** process. However, in all cases, the account to be enrolled may not have existing AWS Config resources. See [Enroll accounts that have existing AWS Config resources](https://docs.aws.amazon.com//controltower/latest/userguide/existing-config-resources.html)

1. To enroll an existing AWS account, the `AWSControlTowerExecution` role must be present in the account you are enrolling. You can review [Enroll an account](https://docs.aws.amazon.com//controltower/latest/userguide/quick-account-provisioning.html) for details and instructions. 

1. In addition to the `AWSControlTowerExecution` role, the existing AWS account you want to enroll must have the following permissions and trust relationships in place. Otherwise, enrollment will fail.

   Role Permission: `AdministratorAccess` (AWS managed policy)

   **Role Trust Relationship:**

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::111122223333:root"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

1. We recommend that the account should not have an AWS Config configuration recorder or delivery channel. These may be deleted or modified through the AWS CLI before you can enroll an account. Otherwise, review [Enroll accounts that have existing AWS Config resources](https://docs.aws.amazon.com//controltower/latest/userguide/existing-config-resources.html) for instructions on how you can modify your existing resources.

1. The account that you wish to enroll must exist in the same AWS Organizations organization as the AWS Control Tower management account. The account that exists can be enrolled *only* into the same organization as the AWS Control Tower management account, in an OU that already is registered with AWS Control Tower. 

To check other prerequisites for enrollment, see [Getting Started with AWS Control Tower](https://docs.aws.amazon.com//controltower/latest/userguide/getting-started-with-control-tower.html).

**Note**  
When you enroll an account into AWS Control Tower, your account is governed by the AWS CloudTrail trail for the AWS Control Tower organization. If you have an existing deployment of a CloudTrail trail, you may see duplicate charges unless you delete the existing trail for the account before you enroll it in AWS Control Tower.

**About trusted access with the `AWSControTowerExecution` role**

Before you can enroll an existing AWS account into AWS Control Tower you must give permission for AWS Control Tower to manage, or *govern*, the account. Specifically, AWS Control Tower requires permission to establish trusted access between AWS CloudFormation and AWS Organizations on your behalf, so that CloudFormation can deploy your stack automatically to the accounts in your selected organization. With this trusted access, the `AWSControlTowerExecution` role conducts activities required to manage each account. That's why you must add this role to each account before you enroll it.

 When trusted access is enabled, CloudFormation can create, update, or delete stacks across multiple accounts and AWS Regions with a single operation. AWS Control Tower relies on this trust capability so it can apply roles and permissions to existing accounts before it moves them into a registered organizational unit, and thereby brings them under governance.

To learn more about trusted access and AWS CloudFormation StackSets, see [AWS CloudFormationStackSets and AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-cloudformation.html). 

# Move and enroll accounts with auto-enrollment
<a name="account-auto-enrollment"></a>

The account auto-enrollment feature is available for landing zones of version 3.1 and above.

 If you optionally enable this feature, you can utilize the AWS Organizations APIs and console to move accounts into AWS Control Tower, without creating [https://docs.aws.amazon.com//controltower/latest/userguide/governance-drift.html](https://docs.aws.amazon.com//controltower/latest/userguide/governance-drift.html). The account automatically receives baseline resources and control configurations from the destination organizational unit (OU) in AWS Control Tower. This optional capability also allows you to move accounts between OUs within AWS Control Tower, without creating inheritance drift, if the two OUs have the same baseline configuration and the same controls enabled.

**To activate auto-enrollment:** You can select auto-enrollment of accounts on the landing zone **Settings** page in the AWS Control Tower console, or by calling the AWS Control Tower `CreateLandingZone` or `UpdateLandingZone` APIs, with the value of the `RemediationType` parameter set to **Inheritance Drift**.

**To apply auto-enrollment:** After selecting this option in your **Settings** page, you can move an account by means of the AWS Organizations console, the AWS Organizations `MoveAccount` API, or the AWS Control Tower console.

**To unenroll an account with auto-enrollment:** If you move an account outside an OU that's registered, AWS Control Tower removes all deployed baseline resources and controls automatically.

**Note**  
If the source and destination OUs in AWS Control Tower have different configurations, the account may show [Moved member account](governance-drift.md#drift-account-moved) drift. 

## Prerequisites: Configure for auto-enrollment
<a name="w2aac44c24c18c15"></a>
+ You must be running AWS Control Tower landing zone version 3.1 or later.
+  Opt into the AWS Control Tower auto-enrollment capability through the landing zone **Settings** page in the console, or through the AWS Control Tower landing zone APIs, by setting the value of the `RemediationTypes` parameter to `Inheritance Drift`. When you have opted in, AWS Control Tower reacts to `move account` events for AWS Organizations, and it remediates inheritance drift for the moved accounts immediately, on your behalf.

## Required permissions
<a name="w2aac44c24c18c17"></a>

 Specific roles and permissions are required for you to use the AWS Organizations `CreateAccount` API and `MoveAccount` API. For more information about using AWS Organizations with AWS Control Tower, see [AWS Control Tower and AWS Organizations](https://docs.aws.amazon.com//organizations/latest/userguide/services-that-can-integrate-CTower.html). 

## API usage examples
<a name="w2aac44c24c18c19"></a>

For more information and examples regarding these APIs, see [https://docs.aws.amazon.com//organizations/latest/APIReference/API_CreateAccount.html](https://docs.aws.amazon.com//organizations/latest/APIReference/API_CreateAccount.html) and [https://docs.aws.amazon.com//organizations/latest/APIReference/API_MoveAccount.html](https://docs.aws.amazon.com//organizations/latest/APIReference/API_MoveAccount.html) in the *AWS Organizations API Reference*. 

## Considerations
<a name="w2aac44c24c18c21"></a>
+  **Enrollment timeline:** An account moved to an OU that's registered with AWS Control Tower is enrolled with an *eventual consistency* model. This process typically takes a few minutes, up to several hours, depending on the number of accounts being moved. 
+  **Unenrollment process:** You can use the same process to unenroll your accounts from AWS Control Tower by moving them to an OU outside AWS Control Tower. This process removes any roles and resources deployed by AWS Control Tower and any controls enabled in AWS Control Tower. 

# Enroll an existing account from the AWS Control Tower console
<a name="quick-account-provisioning"></a>

Two common ways exist to enroll an individual AWS account into AWS Control Tower. 

1. After you select the *auto-enrollment* feature in the **Settings** page, you can create an AWS account outside of AWS Control Tower and move it directly into a registered OU. For more information, see [Move and enroll accounts automatically](https://docs.aws.amazon.com//controltower/latest/userguide/account-auto-enroll.html). This option is available for landing zone versions 3.1 and later.

1. You can enroll an existing account from the AWS Control Tower console manually.

**The following sections describe the second option,** which requres no previous configuration of your AWS Control Tower environment. The AWS account must fulfill the required [prerequisites](https://docs.aws.amazon.com//controltower/latest/userguide/enrollment-prerequisites.html).

**View your eligible accounts in the console:**

1. Navigate to the **Organization** page in AWS Control Tower.

1. Find the name of the account you wish to enroll. To find it, choose **Accounts only** from the dropdown menu at the upper right, and then locate the account name in the filtered table.

Next, follow the steps for enrolling an individual account, as shown in the [Steps to enroll an account manually](#enrollment-steps) section.

## Considerations for enrolling from the console
<a name="enroll-from-console"></a>
+ The **Enroll account** feature available in the AWS Control Tower console is intended for enrolling existing AWS accounts so that they are governed by AWS Control Tower. For more information, see [Enroll an existing AWS account](https://docs.aws.amazon.com/controltower/latest/userguide/enroll-account.html).
+ The console-based **Enroll account** capability is available when your landing zone is not in a state of [drift](https://docs.aws.amazon.com//controltower/latest/userguide/drift.html). If your landing zone is in a state of drift, you may not be able to use the **Enroll account** capability successfully. You'll need to provision new accounts through Account Factory or another method, until your landing zone drift has been resolved. 
+ When you enroll accounts from the AWS Control Tower console, you must be signed into an account with a user that has the `AWSServiceCatalogEndUserFullAccess` policy enabled, along with **Administrator** access permissions to use the AWS Control Tower console, and you cannot be signed in as the root user.
+ Accounts that you enroll may be updated by means of the AWS Control Tower Account Factory, as you would update any other account. Update procedures are given in the section called [Update and move accounts with AWS Control Tower](updating-account-factory-accounts.md). 

**Note**  
When you are enrolling an existing AWS account, be sure to verify the existing email address. Otherwise, a new account may be created.

## Steps to enroll an account manually
<a name="enrollment-steps"></a>

After the **AdministratorAccess** access permission (policy) is in place in your existing AWS account account, follow these steps to enroll the account:

**To enroll an individual account in AWS Control Tower from the console**
+ Navigate to the AWS Control Tower **Organization** page.
+ On the **Organization** page, accounts that are eligible to be enrolled allow you to select **Enroll** from the **Actions** dropdown menu at the top of the section. These accounts also show an **Enroll account** button when you view them on the **Account details** page.
+ When you choose **Enroll account**, you’ll see an **Enroll account** page, where you are prompted to add the `AWSControlTowerExecution` role to the account. For some instructions, see [Manually add the required IAM role to an existing AWS account and enroll it](enroll-manually.md).
+ Next, select a registered OU from the drop down list. If the account is already in a registered OU, this list will show the OU.
+ Choose **Enroll account**.
+ You’ll see a modal reminder to add the `AWSControlTowerExecution` role and confirm the action.
+ Choose **Enroll**.
+ AWS Control Tower begins the process of enrollment, and you are directed back to the **Account details** page.

## Common causes for failure of enrollment
<a name="common-causes-for-enrollment-failure"></a>
+ To enroll an existing account, the `AWSControlTowerExecution` role must be present in the account you're enrolling.
+ Your IAM principal may lack the necessary permissions to provision an account.
+ AWS Security Token Service (AWS STS) is disabled in your AWS account in your home Region, or in any Region supported by AWS Control Tower.
+ You may be signed in to an account that needs to be added to the Account Factory Portfolio in AWS Service Catalog. The account must be added before you'll have access to Account Factory so you can create or enroll an account in AWS Control Tower. If the appropriate user or role is not added to the Account Factory portfolio, you’ll receive an error when you attempt to add an account. For instructions on how to grant access to AWS Service Catalog portfolios, see [Granting access to users](https://docs.aws.amazon.com//servicecatalog/latest/adminguide/catalogs_portfolios_users.html).
+ You may be signed in as root.
+ The account you're trying to enroll may have AWS Config settings that are residual. In particular, the account may have a configuration recorder or delivery channel. These must be deleted or modified through the AWS CLI before you can enroll an account. For more information, see [Enroll accounts that have existing AWS Config resources](existing-config-resources.md) and [Interact with AWS Control Tower through AWS CloudShell](cshell-examples.md). 
+ If the account belongs to another OU with a management account, including another AWS Control Tower OU, you must terminate the account in its current OU before it can join another OU. Existing resources must be removed in the original OU. Otherwise, enrollment will fail.
+ Account provisioning and enrollment fails if your destination OU’s SCPs don’t allow you to create all of the resources required for that account. For example, an SCP in your destination OU may block resource creation without certain tags. In this case, account provisioning or enrollment fails, because AWS Control Tower does not support tagging of resources. For help, contact your account representative, or Support.

For more information about how AWS Control Tower works with roles when you're creating new accounts or enrolling existing accounts, see [Roles and accounts](https://docs.aws.amazon.com//controltower/latest/userguide/roles.html).

**Tip**  
If you cannot confirm that an existing AWS account meets the enrollment prerequisites, you can set up an **Enrollment OU** and enroll the account into that OU. After enrollment is successful, you can move the account to the desired OU. If enrollment happens to fail, no other accounts or OUs are affected by the failure.

If you have doubts that your existing accounts and their configurations are compatible with AWS Control Tower, you can follow the best practice recommended in the following section. 

**Recommended: You can set up a two-step approach to account enrollment**
+ First, use an AWS Config *conformance pack* to evaluate how your accounts may be affected by some AWS Control Tower controls. To determine how enrollment into AWS Control Tower may affect your accounts, see [ Extend AWS Control Tower governance using AWS Config conformance packs](https://aws.amazon.com//blogs/mt/extend-aws-control-tower-governance-using-aws-config-conformance-packs/). 
+ Next, you may wish to enroll the account. If the compliance results are satisfactory, the migration path is easier because you can enroll the account without unexpected consequences.
+ After you've done your evaluation, if you decide to set up an AWS Control Tower landing zone, you may need to remove the AWS Config delivery channel and configuration recorder that were created for your evaluation. Then you'll be able to set up AWS Control Tower successfully.

**Note**  
The conformance pack also works in situations where the accounts are located in OUs registered by AWS Control Tower, but the workloads run within AWS Regions that don’t have AWS Control Tower support. You can use the conformance pack to manage resources in accounts that exist in Regions where AWS Control Tower is not deployed.

# If the account does not meet the prerequisites
<a name="fulfill-prerequisites"></a>

 Remember that, as a prerequisite, accounts eligible to be enrolled into AWS Control Tower governance must be part of the same overall organization. To fulfill this prerequisite for account enrollment, you can follow these preparatory steps to move an account into the same organization as AWS Control Tower. 

**Preparatory steps to bring an account into the same organization as AWS Control Tower**

1.  Drop the account from its existing organization. You must provide a separate payment method if you use this approach. 

1.  Invite the account to join the AWS Control Tower organization. For more information, see [Inviting an AWS account to join your organization](https://docs.aws.amazon.com//organizations/latest/userguide/orgs_manage_accounts_invites.html) in the *AWS Organizations User Guide*. 

1.  Accept the invitation. The account shows up in the root of the organization. This step moves the account into the same organization as AWS Control Tower. and establishes SCPs and consolidated billing. 

**Tip**  
 You can send the invitation for the new organization before the account drops out of the old organization. The invitation will be waiting when the account officially drops out of its existing organization. 

**Steps to fulfill the remaining prerequisites:**

1.  Create the necessary `AWSControlTowerExecution` role. 

1.  Clear out the default VPC. (This part is optional. AWS Control Tower doesn't change your existing default VPC.) 

1.  Delete or modify any existing AWS Config configuration recorder or delivery channel through the AWS CLI or AWS CloudShell. For more information, see [Enroll accounts with AWS Config resources](enroll-account.md#example-config-cli-commands) and [Enroll accounts that have existing AWS Config resources](existing-config-resources.md) 

 After you've completed these preparatory steps, you can enroll the account into AWS Control Tower. For more information, see [Steps to enroll an account manually](quick-account-provisioning.md#enrollment-steps). This step brings the account into full AWS Control Tower governance. 

**Optional steps to deprovision an account, so it can be enrolled and keep its stack**

1.  To keep the applied CloudFormation stack, delete the stack instance from the stack sets, and choose **Retain stacks** for the instance. 

1.  Terminate the account provisioned product in AWS Service Catalog Account Factory. (This step only removes the provisioned product from AWS Control Tower. It doesn't delete the account.) 

1.  Set up the account with the necessary billing details, as required for any account that doesn't belong to an organization. Then remove the account from the organization. (You do this, so the account doesn't count against the total in your AWS Organizations quota.) 

1.  Clean up the account if resources remain, and then close it, following the account closure steps in [Unenroll an account](unmanage-account.md). 

1.  If you have a **Suspended** OU with defined controls, you can move the account there instead of doing Step 1. 

# Manually add the required IAM role to an existing AWS account and enroll it
<a name="enroll-manually"></a>

If you’ve already set up your AWS Control Tower landing zone, you can begin enrolling your organization’s accounts into an OU that is registered with AWS Control Tower. If you haven't set up your landing zone, follow the steps as described in the *AWS Control Tower User Guide* at [Getting Started, Step 2](https://docs.aws.amazon.com/controltower/latest/userguide/getting-started-with-control-tower.html#step-two). After the landing zone is ready, complete the following steps to bring existing accounts into governance by AWS Control Tower, manually.

**Be sure to review the [Prerequisites for enrollment](enrollment-prerequisites.md) noted previously in this chapter.**

Before enrolling an account with AWS Control Tower, you must give AWS Control Tower permission to manage that account. To do so, you’ll add a role that has full access to the account, as shown in the steps that follow. These steps must be performed for each account that you enroll.

**For each account:**

**Step 1: Sign in with administrator access to the management account of the organization that currently contains the account you wish to enroll.**

For example, if you created this account from AWS Organizations and you use a cross-account IAM role to sign in, then you may follow these steps:

1. Sign in to your organization’s management account.

1. Go to **AWS Organizations**.

1. Under **Accounts**, select the account you want to enroll and copy its account ID.

1. Open the account dropdown menu on the top navigation bar and choose **Switch Role**.

1. On the **Switch role** form, fill in the following fields:
   + Under **Account**, enter the account ID you copied.
   + Under **Role**, enter the name of the IAM role that enables cross-account access to this account. The name of this role was defined when the account was created. If you did not specify a role name when you created the account, enter the default role name, `OrganizationAccountAccessRole`.

1. Choose **Switch Role**.

1. You should now be signed into the AWS Management Console as the child account.

1. When you’re finished, stay in the child account for the next part of the procedure.

1. Make note of the management account ID, because you will need to enter it in the next step.

**Step 2: Give AWS Control Tower permission to manage the account.**

1. Go to **IAM**.

1. Go to **Roles**.

1. Choose **Create role**.

1. When asked to select which service the role is for, choose **Custom trust policy**. 

1. Copy the code example shown here and paste it into the Policy Document. Replace the string *`Management Account ID`* with the actual management account ID of your management account. Here is the policy to paste:

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::111122223333:root"
               },
               "Action": "sts:AssumeRole",
               "Condition": {}
           }
       ]
   }
   ```

------

1. When asked to attach policies, choose **AdministratorAccess**.

1. Choose **Next:Tags**.

1. You may see an optional screen titled **Add tags**. Skip this screen for now by choosing **Next:Review**

1. On the **Review** screen, in the **Role name** field, enter `AWSControlTowerExecution`.

1. Enter a brief description in the **Description** box, such as *Allows full account access for enrollment.*

1. Choose **Create role**.

**Step 3: Enroll the account by moving it into a registered OU, and verify enrollment.**

After you’ve set up the necessary permissions by creating the role, follow these steps to enroll the account and verify enrollment.

1. **Sign in again as Admin and go to AWS Control Tower.**

1. 

**Enroll the account.**
   + From the **Organization** page in AWS Control Tower, select your account, then choose **Enroll** from the **Actions** dropdown menu at the upper right.
   + Follow the steps for enrolling an individual account, as shown on the [Steps to enroll an account manually](quick-account-provisioning.md#enrollment-steps) page.

1. 

**Verify enrollment.**
   + From AWS Control Tower, choose **Organization** in the left navigation.
   + Look for the account you have recently enrolled. Its initial state will show a status of **Enrolling**.
   + When the state changes to **Enrolled**, the move was successful.

To continue this process, sign into each account in your organization that you want to enroll in AWS Control Tower. Repeat the prerequisite steps and the enrollment steps for each account.

**Example for adding the `AWSControlTowerExecution` role**

The following YAML template may assist you in creating the required role in an account, so that it can be enrolled programmatically.

```
AWSTemplateFormatVersion: 2010-09-09
Description: Configure the AWSControlTowerExecution role to enable use of your
  account as a target account in AWS CloudFormation StackSets.
Parameters:
  AdministratorAccountId:
    Type: String
    Description: AWS Account Id of the administrator account (the account in which
      StackSets will be created).
    MaxLength: 12
    MinLength: 12
Resources:
  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSControlTowerExecution
      AssumeRolePolicyDocument:
        Version: 2012-10-17		 	 	 
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Ref AdministratorAccountId
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - !Sub arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess
```

# Enroll accounts that have existing AWS Config resources
<a name="existing-config-resources"></a>

This topic provides a step-by-step approach for how to enroll accounts that have existing AWS Config resources. For examples of how to check your existing resources, see [Enroll accounts with AWS Config resources](enroll-account.md#example-config-cli-commands).

**Examples of AWS Config resources**

Here are some types of AWS Config resources that your account could have already. These resources may need to be modified so that you can enroll your account into AWS Control Tower.
+ AWS Config recorder
+ AWS Config delivery channel
+ AWS Config aggregation authorization

**Limitations**
+  Enroll account with existing AWS Config resource is not supported for management account or service integration account(s) configured in landing zone. 
+  The account can be enrolled only by using the OU registration or re-registration workflow which enables the `AWSControlTowerBaseline`. The account can not be enrolled by enabling or resetting the `ConfigBaseline`. 
+  Account with existing AWS Config resource is not supported by [Move and enroll accounts with auto-enrollment](account-auto-enrollment.md). 
+ If the resources are modified and create drift on the account, AWS Control Tower does not update the resources.
+ AWS Config resources in Regions that are not governed by AWS Control Tower are not changed.

**Assumptions**
+ You have deployed an AWS Control Tower landing zone.
+ Your account is not enrolled with AWS Control Tower already.
+ Your account has at least one pre-existing AWS Config resource in at least one of the Regions governed by AWS Control Tower.
+ Your account is not in governance drift.

**Note**  
If you attempt to enroll an account that has existing Config resources, without having the account added to the allow list, enrollment will fail. Thereafter, if you subsequently try to add that same account to the allow list, AWS Control Tower cannot validate that the account is provisioned correctly. You must deprovision the account from AWS Control Tower before you can request the allow list and then enroll it. If you only move the account to a different AWS Control Tower OU, it causes governance drift, which also prevents the account from being added to the allow list.

 For a blog that describes an automated approach to enrolling accounts with existing AWS Config resources, see [Automate enrollment of accounts with existing AWS Config resources into AWS Control Tower](https://aws.amazon.com//blogs/mt/automate-enrollment-of-accounts-with-existing-aws-config-resources-into-aws-control-tower/). 

**This process has 5 main steps.**

1. Add the account(s) to the AWS Control Tower allow list.

1. Create a new IAM role in the account.

1. Modify pre-existing AWS Config resources.

1. Create AWS Config resources in AWS Regions where they don't exist.

1. Enroll the account with AWS Control Tower.

**Before you proceed, consider the following expectations regarding this process.**
+ AWS Control Tower does not create any AWS Config resources in this account.
+ After enrollment, AWS Control Tower controls automatically protect the AWS Config resources you created, including the new IAM role.
+ If any changes are made to the AWS Config resources after enrollment, those resources must be updated to align with AWS Control Tower settings before you can re-enroll the account.

## Step 1: Contact support to add account(s) to the allow list
<a name="existing-config-step-1"></a>

**Include this phrase in your ticket subject line:**

*Enroll accounts that have existing AWS Config resources into AWS Control Tower*

**Include the following details in the body of your ticket:**
+ Management account number
+  Account numbers of member accounts that have existing AWS Config resources. You'll be able to create a support case for all of the accounts you wish to enroll. 
+ Your selected home Region for AWS Control Tower setup

**Note**  
The required time for adding your account to the allow list is 2 business days.

## Step 2: Create a new IAM role in the member account
<a name="existing-config-step-2"></a>

1. Open the CloudFormation console for the member account.

1. Create a new stack using the following template

   ```
   AWSTemplateFormatVersion: 2010-09-09
   Description: Configure AWS Config
       
   Resources:
     CustomerCreatedConfigRecorderRole:
       Type: AWS::IAM::Role
       Properties:
         RoleName: aws-controltower-ConfigRecorderRole-customer-created
         AssumeRolePolicyDocument:
           Version: 2012-10-17		 	 	 
           Statement:
             - Effect: Allow
               Principal:
                 Service:
                   - config.amazonaws.com
               Action:
                 - sts:AssumeRole
         Path: /
         ManagedPolicyArns:
           - arn:aws:iam::aws:policy/service-role/AWS_ConfigRole
           - arn:aws:iam::aws:policy/ReadOnlyAccess
   ```

1. Provide the name for the stack as **CustomerCreatedConfigRecorderRoleForControlTower**

1. Create the stack.

**Note**  
Any SCPs that you create should exclude an `aws-controltower-ConfigRecorderRole*` role. Do not modify the permissions that restrict the ability for AWS Config rules to perform evaluations.  
Follow these guidelines so that you don't receive an `AccessDeniedException` when you have SCPs that block `aws-controltower-ConfigRecorderRole*` from calling Config.

## Step 3: Identify the AWS Regions with pre-existing resources
<a name="existing-config-step-3"></a>

For each governed Region (AWS Control Tower governed) in the account, identify and note the Regions that have at least one of the existing AWS Config resource example types shown previously.

## Step 4: Identify the AWS Regions without any AWS Config resources
<a name="existing-config-step-4"></a>

For each governed Region (AWS Control Tower governed) in the account, identify and note the Regions in which there are no AWS Config resources of the example types shown previously.

## Step 5: Modify the existing resources in each AWS Region
<a name="existing-config-step-5"></a>

For this step, the following information is needed about your AWS Control Tower setup.
+  `AUDIT_ACCOUNT` - the AWS Config service integration account (previously known as the Audit account) ID 
+  `CONFIG_BUCKET` - the AWS S3 bucket to which AWS Config delivers configuration snapshots and configuration history files. Locate and confirm that the AWS S3 bucket exists before proceeding to the next steps. 
  + For landing zone version 3.3 or lower, the AWS S3 bucket is named `aws-controltower-logs-LOGGING_ACCOUNT-HOME_REGION`, located in the Logging account.
  + For landing zone version 4.0 or higher, the AWS S3 bucket is named `aws-controltower-config-logs-AUDIT_ACCOUNT-<REGION_STRING>-<SUFFIX_STRING>`, located in the AWS Config service integration account (previously known as the Audit account).
+ `IAM_ROLE_ARN` - the IAM role ARN created in Step 2
+ `ORGANIZATION_ID` - the organization ID for the management account
+ `MEMBER_ACCOUNT_NUMBER` - the member account that is being modified
+ `HOME_REGION` - the home Region for AWS Control Tower setup.

 Modify each existing resource by following the instructions given in sections 5a through 5c, which follow.

## Step 5a. AWS Config recorder resources
<a name="modify-config-recorder-resources-step-5a"></a>

Only one AWS Config recorder can exist per AWS Region. If one exists, modify the settings as shown. Replace the item `GLOBAL_RESOURCE_RECORDING` with **true** in your home Region. Replace the item with **false** for other Regions where an AWS Config recorder exists.
+ **Name:** DON'T CHANGE
+ **RoleARN:**` IAM_ROLE_ARN`
  + **RecordingGroup:**
  + **AllSupported:** true
  + **IncludeGlobalResourceTypes:** `GLOBAL_RESOURCE_RECORDING`
  + **ResourceTypes:** Empty

This modification can be made through the AWS CLI using the following command. Replace the string `RECORDER_NAME` with the existing AWS Config recorder name.

```
aws configservice put-configuration-recorder --configuration-recorder  name=RECORDER_NAME,roleARN=arn:aws:iam::MEMBER_ACCOUNT_NUMBER:role/aws-controltower-ConfigRecorderRole-customer-created --recording-group allSupported=true,includeGlobalResourceTypes=GLOBAL_RESOURCE_RECORDING --region CURRENT_REGION
```

## Step 5b. Modify AWS Config delivery channel resources
<a name="modify-config-delivery-channel-step-5b"></a>

Only one AWS Config delivery channel can exist per Region. If another exists, modify the settings as shown.
+ **Name:** DON’T CHANGE
+ **ConfigSnapshotDeliveryProperties:** TwentyFour\$1Hours
+  **S3BucketName:***CONFIG\$1BUCKET* 
+ **S3KeyPrefix: ***ORGANIZATION\$1ID*
+ **SnsTopicARN: **The SNS topic ARN from the audit account, with the following format:

  `arn:aws:sns:CURRENT_REGION:AUDIT_ACCOUNT:aws-controltower-AllConfigNotifications`

This modification can be made through the AWS CLI using the following command. Replace the string `DELIVERY_CHANNEL_NAME` with the existing AWS Config recorder name.

```
aws configservice put-delivery-channel --delivery-channel name=DELIVERY_CHANNEL_NAME,s3BucketName=CONFIG_BUCKET,s3KeyPrefix="ORGANIZATION_ID",configSnapshotDeliveryProperties={deliveryFrequency=TwentyFour_Hours},snsTopicARN=arn:aws:sns:CURRENT_REGION:AUDIT_ACCOUNT:aws-controltower-AllConfigNotifications --region CURRENT_REGION
```

## Step 5c. Modify AWS Config aggregation authorization resources
<a name="modify-config-aggregator-auth-step-5c"></a>

**Note**  
This step is not required for landing zone version 4.0 or higher.

Multiple aggregation authorizations can exist per Region. AWS Control Tower requires an aggregation authorization that specifies the audit account as the authorized account, and has the home Region for AWS Control Tower as the authorized Region. If it doesn’t exist, create a new one with the following settings:
+ **AuthorizedAccountId: **The Audit account ID
+ **AuthorizedAwsRegion:** The home Region for the AWS Control Tower setup

This modification can be made through the AWS CLI using the following command:

 `aws configservice put-aggregation-authorization --authorized-account-id AUDIT_ACCOUNT_ID --authorized-aws-region HOME_REGION --region CURRENT_REGION` 

## Step 6: Create resources where they don’t exist, in Regions governed by AWS Control Tower
<a name="existing-config-step-6"></a>

Revise the CloudFormation template, so that in your home Region the **IncludeGlobalResourcesTypes** parameter has the value `GLOBAL_RESOURCE_RECORDING`, as shown in the example that follows. Also update the required fields in the template, as specified in this section.

Replace the item `GLOBAL_RESOURCE_RECORDING` with **true** in your home Region. Replace the item with **false** for other Regions where an AWS Config recorder does not exist.

1. Navigate to the management account’s CloudFormation console.

1. Create a new StackSet with the name **CustomerCreatedConfigResourcesForControlTower**.

1. Copy and update the following template:
**Note**  
The `CustomerCreatedAggregationAuthorization` resource in the template is not required for landing zone version 4.0 or higher.

   ```
   AWSTemplateFormatVersion: 2010-09-09
   Description: Configure AWS Config
   Resources:
     CustomerCreatedConfigRecorder:
       Type: AWS::Config::ConfigurationRecorder
       Properties:
         Name: aws-controltower-BaselineConfigRecorder-customer-created
         RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-controltower-ConfigRecorderRole-customer-created
         RecordingGroup:
           AllSupported: true
           IncludeGlobalResourceTypes: GLOBAL_RESOURCE_RECORDING
           ResourceTypes: []
     CustomerCreatedConfigDeliveryChannel:
       Type: AWS::Config::DeliveryChannel
       Properties:
         Name: aws-controltower-BaselineConfigDeliveryChannel-customer-created
         ConfigSnapshotDeliveryProperties:
           DeliveryFrequency: TwentyFour_Hours
         S3BucketName: CONFIG_BUCKET
         S3KeyPrefix: ORGANIZATION_ID
         SnsTopicARN: !Sub arn:aws:sns:${AWS::Region}:AUDIT_ACCOUNT:aws-controltower-AllConfigNotifications
     CustomerCreatedAggregationAuthorization:
       Type: "AWS::Config::AggregationAuthorization"
       Properties:
         AuthorizedAccountId: AUDIT_ACCOUNT
         AuthorizedAwsRegion: HOME_REGION
   ```

**Update the template with required fields:**

   1. In the **S3BucketName** field, replace the *CONFIG\$1BUCKET*

   1. In the **S3KeyPrefix** field, replace the *ORGANIZATION\$1ID*

   1. In the **SnsTopicARN** field, replace the *AUDIT\$1ACCOUNT*

   1. In the **AuthorizedAccountId** field, replace the *AUDIT\$1ACCOUNT*

   1. In the **AuthorizedAwsRegion** field, replace the *HOME\$1REGION*

1. During deployment on the CloudFormation console, add the member account number.

1. Add the AWS Regions that were identified in Step 4.

1. Deploy the stack set.

## Step 7: Register the OU with AWS Control Tower
<a name="existing-config-step-7"></a>

In the AWS Control Tower dashboard, register the OU.

**Note**  
The **Enroll account** workflow will not succeed for this task. You must choose **Register OU** or **Re-register OU**.

# Provision and manage accounts with Account Factory
<a name="account-factory"></a>

**Note**  
Single account provision, update and customization must target an organizational unit (OU) with AWSControlTowerBaseline enabled. If an OU does not have the AWSControlTowerBaseline enabled, you can activate account auto-enrollment or use ResetEnabledBaseline and ResetEnabledControl APIs on EnabledBaselines and EnabledControls on that OU to enroll accounts. For details of AWSControlTowerBaseline, see: [Baseline types that apply at the OU level](types-of-baselines.md#ou-baseline-types). 

 This chapter includes an overview and procedures for provisioning new member accounts in an AWS Control Tower landing zone with Account Factory. 

## Permissions for configuring and provisioning accounts
<a name="configure-provision-new-account"></a>

The AWS Control Tower Account Factory enables cloud administrators and users in AWS IAM Identity Center to provision accounts in your landing zone. By default, IAM Identity Center users that provision accounts must be in the `AWSAccountFactory` group or the management group. 

**Note**  
Exercise caution when working from the management account, as you would when using any account that has permissions across your organization.

The AWS Control Tower management account has a trust relationship with the `AWSControlTowerExecution` role, which allows account setup from the management account, including some automated account setup. For more information about the `AWSControlTowerExecution` role, see [Roles and accounts](https://docs.aws.amazon.com//controltower/latest/userguide/roles-how.html).

**Note**  
To enroll an existing AWS account into AWS Control Tower, that account must have the `AWSControlTowerExecution` role enabled. For more information about how to enroll an existing account, see [About enrolling existing accounts](enroll-account.md).

For more information about permissions, see [Permissions required for provisioning accounts](provision-and-manage-accounts.md#permissions).

## Considerations for managing accounts in Account Factory
<a name="closing-and-repurposing"></a>

 You can update, unenroll, and close accounts that you create and provision through Account Factory. You can recycle accounts by updating the user parameters in the accounts that you want to repurpose. You can also change an account's organizational unit (OU). 

**Note**  
 When updating a provisioned product that's associated with an account that Account Factory vends, if you specify a new user email address for AWS IAM Identity Center, AWS Control Tower creates a new user in IAM Identity Center. The previously created account isn't removed. For information about removing the previous IAM Identity Center user email address from IAM Identity Center, see [Disabling a User](https://docs.aws.amazon.com//singlesignon/latest/userguide/disableuser.html). 

# Update and move accounts with AWS Control Tower
<a name="updating-account-factory-accounts"></a>

The easiest way to update an enrolled account is through the AWS Control Tower console. Individual account updates are useful for resolving drift, such as [Moved member account](governance-drift.md#drift-account-moved). Account updates also are required as part of a full landing zone update.

## Update the account in the console
<a name="update-account-in-console"></a>

**To update an account in the AWS Control Tower console**

1. When signed in to AWS Control Tower, navigate to the **Organization** page.

1. In the list of OUs and accounts, select the name of the account you wish to update. Accounts that are available for updating show a status of **Update available**.

1. Next you'll see the **Account details** page for your selected account.

1. In the upper right, choose **Update account**.

If you move an account from one organizational unit (OU) to another, remember that the controls applied by the new OU may be different than the controls in the former OU. Be sure that the controls in the new OU meet your policy requirements for the account.

AWS Control Tower accounts are modified differently, depending on whether you have opted-in for auto-enrollment of accounts, or not. For more information about auto-enrollment, see [Optionally configure auto-enrollment for accounts](configure-auto-enroll.md).

**Control behavior when accounts are moved between  OUs, with auto-enroll enabled**

When you move an account into a new OU, AWS Control Tower applies the OU's enabled baselines and controls to the account. Controls and baselines from the previous OU are removed. If you move an account outside an OU that's registered, AWS Control Tower removes all deployed baselines and controls. 

**Control behavior when accounts are moved between  OUs, without auto-enroll**

When you move an account between OUs, the controls for the destination OU are applied to the  account. However, the controls that applied to the account from the former OU are not  removed. The exact behavior of the controls is specific to the implementation of the  controls that are active on the former OU and the destination OU.
+  *For controls implemented with AWS Config rules:* The controls from the previous OU  are not removed. These controls must be removed manually.
+ *For controls implemented with SCPs:* The SCP-based controls from the previous OU are  removed. The SCP-based controls for the destination OU go into effect on this account. 
+ *For controls implemented with CloudFormation hooks:* This behavior  depends on the status of controls in the new OU.
  + *If the destination OU has no hook-based controls active:* The old  controls remain active for the moved account, unless you remove them  manually.
  + *If the destination OU has hook controls active:* The old controls are  removed and the controls in the destination OU are applied to the  account.

# Change email address of an enrolled account
<a name="change-account-email"></a>

 To change the email address of an enrolled member account in AWS Control Tower, follow the procedure in this section. 

**Note**  
 The following procedure doesn't allow you to change the email address of a **management account**, **log archive account**, or **audit account**. For more information about that, see [How do I change the email address associated with my AWS account?](https://aws.amazon.com//premiumsupport/knowledge-center/change-email-address/) or contact AWS Support. 

**To change the email address of an account that AWS Control Tower creates**

1.  Recover the root user password for the account. You can follow the steps in the article [How do I recover a lost or forgotten AWS password?](https://aws.amazon.com//premiumsupport/knowledge-center/recover-aws-password/) 

1.  Sign in to the account with the root user password. 

1.  Change the email address as you would for any other AWS account, and wait for the change to reflect in AWS Organizations. You might experience a delay while the email address change finishes updating. 

1.  Update the provisioned product in Service Catalog using the email address that previously belonged to the account. The process for updating the provisioned product includes associating the new email address with the provisioned product. This way the email address change takes effect in AWS Control Tower. Use the new email address for updates to subsequently provisioned products. 

To change the password or email address of a member account that you created with AWS Organizations, see [Accessing a member account as the root user](https://docs.aws.amazon.com//organizations/latest/userguide/orgs_manage_accounts_access.html#orgs_manage_accounts_access-as-root) in the *AWS Organizations User Guide*. 

Alternatively, you can update the email address for an Account Factory or other member account from the AWS Organizations console without logging in as the root user. For more information, see [Updating the root user email address for a member account with AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_accounts_update_primary_email.html) in the *AWS Organizations User Guide*.

# Change the name of an enrolled account
<a name="change-account-name"></a>

Follow the procedure in this section to change the name of an enrolled AWS Control Tower account.

**Note**  
To change the name of an AWS *administrator* account, you must have admin permissions and be logged in as the account's root user. 

**To change the name of an account created by AWS Control Tower, by using AWS Organizations console or APIs**
+ Follow the [instructions available](https://docs.aws.amazon.com//accounts/latest/reference/manage-acct-update-acct-name.html#update-account-name-orgs) in the *AWS Account Management Reference Guide*.

**Alternative method to change the name of an account created by AWS Control Tower**

1. Recover the root password for the account. You can follow the steps outlined in this article, [How do I recover a lost or forgotten AWS password?](https://aws.amazon.com//premiumsupport/knowledge-center/recover-aws-password/)

1. Sign in to the account with the root password.

1. In the AWS Billing console, navigate to the **Account settings** page.

1. Change the name in **Account settings**, as you would for any other AWS account.

1. AWS Control Tower automatically updates itself to reflect the name change. This update will not be reflected in the provisioned product in AWS Service Catalog.

# Configure Account Factory with Amazon Virtual Private Cloud settings
<a name="configuring-account-factory-with-VPC-settings"></a>

Account Factory allows you to create pre-approved baselines and configuration options for accounts in your organization. You can configure and provision new accounts through AWS Service Catalog.

On the Account Factory page, you can see a list of organizational units (OUs) and their **allow list** status. By default, all OUs are on the allow list, which means that accounts can be provisioned under them. You can disable certain OUs for account provisioning through AWS Service Catalog.

You can view the Amazon VPC configuration options available to your end users when they provision new accounts. 

**To configure Amazon VPC settings in Account Factory**

1. As a central cloud administrator, sign into the AWS Control Tower console with administrator permissions in the management account.

1. From the left side of the dashboard, select **Account Factory** to navigate to the Account Factory network configuration page. There you can see the default network settings displayed. To edit, select **Edit** and view the editable version of your Account Factory network configuration settings. 

1. You can modify each field of the default settings as needed. Choose the VPC configuration options you'd like to establish for all new Account Factory accounts that your end users may create, and enter your settings into the fields. 
+ Choose **disabled** or **enabled** to create a public subnet in Amazon VPC. By default, the internet-accessible subnet is disallowed.
**Note**  
If you set the account factory VPC configuration so that public subnets are **enabled** when provisioning a new account, account factory configures Amazon VPC to create a [NAT Gateway](https://docs.aws.amazon.com//vpc/latest/userguide/vpc-nat-gateway.html). You will be billed for your usage by Amazon VPC. See [VPC Pricing](https://aws.amazon.com//vpc/pricing/) for more information. 
+ Choose the maximum number of private subnets in Amazon VPC from the list. By default, 1 is selected. The maximum number of private subnets allowed is 2 per availability zone.
+  Enter the range of IP addresses for creating your account VPCs. The value must be in the form of a classless inter-domain routing (CIDR) block (for example, the default is `172.31.0.0/16`). This CIDR block provides the overall range of subnet IP addresses for the VPC that Account Factory creates for your account. Within your VPC, subnets are assigned automatically from the range you specify, and they are equal in size. By default, subnets within your VPC do not overlap. However, subnet IP address ranges in the VPCs of all your provisioned accounts could overlap.
+ Choose a region or all the regions for creating a VPC when an account is provisioned. By default all available regions are selected.
+ From the list, choose the number of Availability Zones to configure subnets for in each VPC. The default and recommended number is 3.
+ Choose **Save**.

 You can set up these configuration options to create new accounts that don't include a VPC. See the [walkthrough](https://docs.aws.amazon.com//controltower/latest/userguide/configure-without-vpc.html).

# Unenroll an account
<a name="unmanage-account"></a>

If you created an account in Account Factory or enrolled an AWS account, and you no longer want the account to be managed by AWS Control Tower in a landing zone, you can *unenroll* the account from the AWS Control Tower console. 

When you unenroll an AWS Control Tower account, all resources provisioned by AWS Control Tower are removed, including any controls and blueprints. The account is moved out of any AWS Control Tower OU and into the **Root** area. The account is no longer part of a registered OU, and it is no longer subject to AWS Control Tower SCPs. You can close the account through AWS Organizations.

**To unenroll an enrolled account from the AWS Control Tower console**

1. Open the AWS Control Tower console in your web browser at [https://console.aws.amazon.com/controltower](https://console.aws.amazon.com/controltower)

1. In the left navigation pane, choose **Organization**.

1. In the **Organization** page, expand the OU that contains the account, by selecting the **\$1** button near the OU.

1. Select the account and then choose **Unmanage**.

**Note**  
Wait for the account's status to show **Not enrolled**.

If you no longer need the account, close it. For more information about closing AWS accounts, see [Closing an account](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/close-account.html) in the *AWS Billing User Guide*

**Unenroll an account when auto-enroll is active**  
If the auto-enroll capability is active in your **Settings** page, you also can unenroll an account by moving it into an OU that is not registered in AWS Control Tower. All AWS Control Tower resources are removed. Be aware that you do not unenroll the account accidentally in this manner. However, you can re-enroll the account by returning it to the OU.

When you unenroll a customized account, AWS Control Tower removes the resources that the landing zone has deployed, as well as any other resources that AWS Control Tower created within the account. AWS Control Tower also removes the **AWSControlTowerExecution** role, even if it was added manually. Removing this role aligns with the principle of least privilege, because a service execution role should not stay in an unmanaged account.

After you unenroll the account, you can close the account through AWS Organizations.

**Note**  
An unenrolled account is not closed or deleted. When the account has been unenrolled, the IAM Identity Center user that you selected when you created the account in Account Factory still has administrative access to the account. If you do not want this user to have administrative access, you must change this setting in IAM Identity Center by updating the account in Account Factory and changing the IAM Identity Center user email address for the account. For more information, see [Update and move accounts with AWS Control Tower](updating-account-factory-accounts.md).

## Video walkthrough
<a name="unmanage-account-video"></a>

This video (3:25) describes how to remove an account from AWS Control Tower, gain root access to the account, and finally close the AWS account. You also can close an account with [an AWS Organizations API](https://docs.aws.amazon.com//controltower/latest/userguide/delete-account.html). For better viewing, select the icon at the lower right corner of the video to enlarge it to full screen. Captioning is available.

[![AWS Videos](http://img.youtube.com/vi/n3eALEKZaHc/0.jpg)](http://www.youtube.com/watch?v=n3eALEKZaHc)


You can view a list of AWS [YouTube videos](https://www.youtube.com/playlist?list=PLhr1KZpdzukdS9skEXbY0z67F-wrcpbjm) that explain common tasks in AWS Control Tower.

# Close an account created in Account Factory
<a name="delete-account"></a>

Accounts created in Account Factory are AWS accounts. For information about closing AWS accounts, see [Closing an account](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/close-account.html) in the [https://docs.aws.amazon.com//accounts/latest/reference/manage-acct-closing.html ](https://docs.aws.amazon.com//accounts/latest/reference/manage-acct-closing.html ).

**Note**  
 Closing an AWS account is not the same as unenrolling an account from AWS Control Tower—these are separate actions. You must unenroll the account before you close it.

## Close an AWS Control Tower member account through AWS Organizations
<a name="close-account-with-orgs-api"></a>

You can close your AWS Control Tower member accounts from your organization’s management account without a requirement to sign in to each member account individually with root credentials, by means of AWS Organizations. You cannot close your management account in this way, however. 

When you call the AWS Organizations [CloseAccount API](https://docs.aws.amazon.com//organizations/latest/APIReference/API_CloseAccount.html), or close an account in the AWS Organizations console, the member account is isolated for 90 days, as any AWS account would be. The account shows a **Suspended** status in AWS Control Tower and AWS Organizations. If you attempt to work with the account during that 90 days, AWS Control Tower gives an error message.

**Note**  
If an OU has suspended accounts, EnabledControl operations will fail for regional controls on the target.

Before the 90 days expire, you can restore the member account, as you can do with any AWS account. After that 90-day time, the account’s records are removed.

We recommend, as a best practice, to unenroll a member account before you close that account. If you close a member account without first unmanaging it, AWS Control Tower shows the account’s status as **Suspended**, but also as **Enrolled**. As a result, if you attempt to **Re-register** the account's OU during that 90-day time, AWS Control Tower produces an error message. The suspended account essentially blocks the re-registering actions with a pre-check failure. If you remove the account from the OU, you can **Re-register** the OU, but AWS may produce an error regarding a missing method of payment for the account. To work around this constraint, create another OU, and move the account to that OU before you try to re-register. We recommend naming this OU the **Suspended** OU.

**Note**  
If you do not unenroll the account before you close it, you must delete the account's provisioned product in AWS Service Catalog after those 90 days are finished.

For more information, see the AWS Organizations documentation about the [CloseAccount API](https://docs.aws.amazon.com//organizations/latest/APIReference/API_CloseAccount.html).

# Resource Considerations for Account Factory
<a name="account-factory-considerations"></a>

When an account is provisioned with Account Factory, the following AWS resources are created within the account.


| AWS service | Resource type | Resource name | 
| --- | --- | --- | 
| AWS CloudFormation | Stacks |  StackSet-AWSControlTowerBP-BASELINE-CLOUDTRAIL-\$1 StackSet-AWSControlTowerBP-BASELINE-CLOUDWATCH-\$1 StackSet-AWSControlTowerBP-BASELINE-CONFIG-\$1 StackSet-AWSControlTowerBP-BASELINE-ROLES-\$1 StackSet-AWSControlTowerBP-BASELINE-SERVICE-ROLES-\$1  | 
| AWS CloudTrail | Trail | aws-controltower-BaselineCloudTrail | 
| Amazon CloudWatch | CloudWatch Event Rules | aws-controltower-ConfigComplianceChangeEventRule | 
| Amazon CloudWatch | CloudWatch Logs | aws-controltower/CloudTrailLogs /aws/lambda/aws-controltower-NotificationForwarder | 
| AWS Identity and Access Management | Roles | aws-controltower-AdministratorExecutionRole aws-controltower-CloudWatchLogsRole aws-controltower-ConfigRecorderRole aws-controltower-ForwardSnsNotificationRole aws-controltower-ReadOnlyExecutionRole  AWSControlTowerExecution | 
| AWS Identity and Access Management | Policies | AWSControlTowerServiceRolePolicy  | 
| Amazon Simple Notification Service | Topics | aws-controltower-SecurityNotifications | 
| AWS Lambda | Applications | StackSet-AWSControlTowerBP-BASELINE-CLOUDWATCH-\$1 | 
| AWS Lambda | Functions | aws-controltower-NotificationForwarder | 
| Amazon EventBridge | Rule | AWSControlTowerManagedRule | 
| Amazon EventBridge | Rule | aws-controltower-ConfigComplianceChangeEventRule | 

# Customize accounts with Account Factory Customization (AFC)
<a name="af-customization-page"></a>

**Note**  
Single account provision, update and customization must target an organizational unit (OU) with AWSControlTowerBaseline enabled. If an OU does not have the AWSControlTowerBaseline enabled, you can activate account auto-enrollment or use ResetEnabledBaseline and ResetEnabledControl APIs on EnabledBaselines and EnabledControls on that OU to enroll accounts. For details of AWSControlTowerBaseline, see: [Baseline types that apply at the OU level](types-of-baselines.md#ou-baseline-types). 

AWS Control Tower allows you to customize new and existing AWS accounts when you provision their resources from the AWS Control Tower console. After you set up Account Factory customization, AWS Control Tower automates this process for future provisioning, so you don't have to maintain any pipelines. Customized accounts are available for use immediately after the resources are provisioned.

**Provision new accounts with blueprints**

Your customized accounts are provisioned in the AWS Control Tower Account Factory, through CloudFormation templates, or with Terraform. You'll define a template that serves as customized account *blueprint*. Your blueprint describes the specific resources and configurations you require when an account is provisioned. Pre-defined blueprints, built and managed by AWS partners, also are available. For more information about partner-managed blueprints, see the [AWS Service Catalog Getting Started Library](https://docs.aws.amazon.com//servicecatalog/latest/adminguide/getting-started-library.html).

**Apply blueprints to existing accounts**

You can apply customized blueprints to existing accounts, also, by following the **Update account** steps in the AWS Control Tower console. For details, see [Update the account in the console](updating-account-factory-accounts.md#update-account-in-console).

**Definition: Your hub account**

Your account blueprints are stored in an AWS account, which for our purposes is referred to as a *hub account*. Blueprints are stored in the form of an Service Catalog product. We call this product a blueprint, to distinguish it from any other Service Catalog products. To learn more about how to create Service Catalog products, see [Creating products](https://docs.aws.amazon.com//servicecatalog/latest/adminguide/productmgmt-cloudresource.html) in the *AWS Service Catalog Administrator Guide*.

**Note**  
AWS Control Tower contains *proactive controls*, which monitor CloudFormation resources in AWS Control Tower. Optionally, you can activate these controls in your landing zone. When you apply proactive controls, they check to make sure that the resources you're about to deploy to your accounts are compliant with your organization's policies and procedures. For more information about proactive controls, see [Proactive controls](https://docs.aws.amazon.com//controltower/latest/userguide/proactive-controls.html).

For more information about working with AFC, see [Automate account customization using Account Factory Customization in AWS Control Tower](https://aws.amazon.com//blogs/mt/automate-account-customization-using-account-factory-customization-in-aws-control-tower/).

**Prerequisites**  
Before you begin to create customized accounts with AWS Control Tower Account Factory, you must have an AWS Control Tower landing zone environment deployed, and you must have an organizational unit (OU) registered with AWS Control Tower, where your newly created accounts will be placed.

**Preparation for customization**
+ *Designate a hub account:* You may create a new account to serve as the hub account, or you may use an existing AWS account. We strongly recommend that you do not use the AWS Control Tower management account as your blueprint hub account.
+ *Add the necessary role:* If you plan to enroll AWS accounts into AWS Control Tower and customize them, you must first add the `AWSControlTowerExecution` role to those accounts, as you would for any other account you are enrolling into AWS Control Tower.
+ *Configure partner blueprints (optional): *If you plan to use partner blueprints that have marketplace subscription requirements, you must configure these from your AWS Control Tower management account before you deploy the partner blueprints as account factory customization blueprints.

**Topics**
+ [Set up for customization](afc-setup-steps.md)
+ [Create a customized account from a blueprint](create-afc-customized-account.md)
+ [Customize accounts with AFC as you enroll them](enroll-and-customize.md)
+ [Add a blueprint to an AWS Control Tower account](add-blueprint-to-account.md)
+ [Update a blueprint](update-a-blueprint.md)
+ [Remove a blueprint from an account](remove-a-blueprint.md)
+ [Partner blueprints](partner-blueprints.md)
+ [Considerations for Account Factory Customizations (AFC)](#af-limitations)
+ [In case of a blueprint error](#af-error)
+ [Customizing your policy document for AFC blueprints based on CloudFormation](#custom-policy-document)
+ [Additional permissions required for creating a Terraform-based Service Catalog product](#custom-policy-document-tf)
+ [Transition to the AWS Service Catalog External product type](#service-catalog-external-product-type)

# Set up for customization
<a name="afc-setup-steps"></a>

The next sections give steps to set up Account Factory for the customization process. We recommend that you set up [delegated admin](https://docs.aws.amazon.com//accounts/latest/reference/using-orgs-delegated-admin.html) for the hub account, before you begin these steps.

**Summary**
+ **Step 1. Create the required role.** Create an IAM role that grants permission for AWS Control Tower to have access to the (hub) account, where the Service Catalog products, also called blueprints, are stored.
+ **Step 2. Create the AWS Service Catalog product.** Create the AWS Service Catalog product (also called a “blueprint product”) that you'll need for baselining the custom account.
+ **Step 3. Review your custom blueprint.** Inspect the AWS Service Catalog product (blueprint) that you created.
+ **Step 4. Call your blueprint to create a customized account.** Enter the blueprint product information and the role information into the proper fields in Account Factory, in the AWS Control Tower console, while creating the account.

# Step 1. Create the required role
<a name="step-1-create-blueprint-access-role"></a>

Before you begin to customize accounts, you must set up a role that contains a trust relationship between AWS Control Tower and your hub account. When assumed, the role grants AWS Control Tower access to administer the resources in the hub account. The role must be named **AWSControlTowerBlueprintAccess**. 

AWS Control Tower assumes this role to create a Portfolio resource on your behalf in AWS Service Catalog, then to add your blueprint as a Service Catalog Product to this Portfolio, and then to share this Portfolio, and your blueprint, with your member account during account provisioning.

You'll create the `AWSControlTowerBlueprintAccess` role, as explained in the following sections. You can set up the role in an enrolled or an unenrolled account.

**Navigate to the IAM console to set up the required role.**  


**To set up the AWSControlTowerBlueprintAccess role in an enrolled AWS Control Tower account**

1. Federate or sign in as the principal in the AWS Control Tower management account.

1. From the federated principal in the management account, assume or switch roles to the `AWSControlTowerExecution` role in the enrolled AWS Control Tower account that you select to serve as the blueprint hub account. 

1. From the `AWSControlTowerExecution` role in the enrolled AWS Control Tower account, create the `AWSControlTowerBlueprintAccess` role with proper permissions and trust relationships.

**Important**  
To comply with AWS best practices guidance, it's important that you sign out of the `AWSControlTowerExecution` role immediately after you create the `AWSControlTowerBlueprintAccess` role.  
To prevent unintended changes to resources, the `AWSControlTowerExecution` role is intended for use by AWS Control Tower only.

If your blueprint hub account isn't enrolled in AWS Control Tower, the `AWSControlTowerExecution` role won't exist in the account, and there's no need to assume it before you continue with setting up the `AWSControlTowerBlueprintAccess` role. 

**To set up the AWSControlTowerBlueprintAccess role in an unenrolled member account**

1. Federate or sign in as a principal in the account that you wish to designate as the hub account, by means of your preferred method.

1. When signed in as the principal in the account, create the `AWSControlTowerBlueprintAccess` role with proper permissions and trust relationships.

The **AWSControlTowerBlueprintAccess** role must be set up to grant trust to two principals:
+ The principal (user) that runs AWS Control Tower in the AWS Control Tower management account. 
+ The role named `AWSControlTowerAdmin` in the AWS Control Tower management account.

Here's an example trust policy, similar to one you will need to include for your role. This policy demonstrates the best practice of granting least-privilege access. When you make your own policy, replace the term *YourManagementAccountId* with the actual acccount ID of your AWS Control Tower management account, and replace the term *YourControlTowerUserRole* with the identifier of the IAM role for your management account.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::111122223333:role/service-role/AWSControlTowerAdmin",
                    "arn:aws:iam::111122223333:role/YourControlTowerUserRole"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

------

**Required permissions policy**

AWS Control Tower requires that the managed policy named `AWSServiceCatalogAdminFullAccess` must be attached to the `AWSControlTowerBlueprintAccess` role. This policy provides permissions that AWS Service Catalog looks for when it allows AWS Control Tower to administer your portfolio and AWS Service Catalog Product resources. You can attach this policy when you're creating the role in the IAM console.

**Additional permissions may be required**  
If you store your blueprints in Amazon S3, AWS Control Tower also requires the `AmazonS3ReadOnlyAccess` permission policy for the `AWSControlTowerBlueprintAccess` role.
The AWS Service Catalog Terraform type of product requires you to add some additional permissions to the AFC custom IAM policy, if you don't utilize the default **Admin** policy. It requires these in addition to the permissions required to create the resources that you define in your terraform template.

# Step 2. Create the AWS Service Catalog product
<a name="step-2-create-blueprint-product"></a>

To create an AWS Service Catalog product, follow the steps at [Creating products](https://docs.aws.amazon.com//servicecatalog/latest/adminguide/productmgmt-cloudresource.html) in the *AWS Service Catalog Administrator Guide*. You'll add your account blueprint as a template when you create the AWS Service Catalog product.

**Important**  
As a result of HashiCorp's updated Terraform licensing, AWS Service Catalog changed support for *Terraform Open Source* products and provisioned products to a new product type, called *External*. To learn more about how this change effects AFC, including how to update your existing account blueprints to the External product type, review [Transition to External product type](af-customization-page.md#service-catalog-external-product-type). 

**Summary of steps to create a blueprint**
+ Create or download an CloudFormation template or Terraform tar.gz configuration file that will become your account blueprint. Some template examples are given later in this section.
+ Sign in to the AWS account where you store your Account Factory blueprints (sometimes called the hub account).
+ Navigate to the AWS Service Catalog console. Choose **Product list**, and then choose **Upload new product**.
+ In the **Product details** pane, enter details for your blueprint product, such as a name and description.
+ Select **Use a template file** and then select **Choose file**. Select or paste the template or configuration file you've developed or downloaded for use as your blueprint.
+ Choose **Create product** at the bottom of the console page.

 You can download an CloudFormation template from the AWS Service Catalog reference architecture repository. [One example from that repository helps set up a backup plan for your resources](https://github.com/aws-samples/aws-service-catalog-reference-architectures/blob/master/backup/backup-tagoptions.yml). 

Here's an example template, for a fictitious company called **Best Pets**. It helps set up a connection to their pet database.

```
Resources:
  ConnectionStringGeneratorLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"		 	 	 
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - "sts:AssumeRole"
  ConnectionStringGeneratorLambda:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Join ['-', ['ConnectionStringGenerator', !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]]]
      Description: Retrieves the connection string for this account to access the Pet Database
      Role: !GetAtt ConnectionStringGeneratorLambdaRole.Arn
      Runtime: nodejs22.x
      Handler: index.handler
      Timeout: 5
      Code:
        ZipFile: >
           export const handler = async (event, context) => {
             const awsAccountId = context.invokedFunctionArn.split(“:”)[4]
             const connectionString= “fake connection for account ” + awsAccountId;
             const response = {
               statusCode: 200,
               body: connectionString
             };
           return response;
          };

  ConnectionString:
    Type: Custom::ConnectionStringGenerator
    Properties:
      ServiceToken: !GetAtt ConnectionStringGeneratorLambda.Arn

  PetDatabaseConnectionString:
    DependsOn: ConnectionString
    # For example purposes we're using SSM parameter store.
    # In your template, use secure alternatives to store
    # sensitive values such as connection strings.
    Type: AWS::SSM::Parameter
    Properties: 
      Name: pet-database-connection-string
      Description: Connection information for the BestPets pet database
      Type: String
      Value: !GetAtt ConnectionString.Value
```

# Step 3. Review your custom blueprint
<a name="step-3-review-blueprint"></a>

You can view your blueprint in the AWS Service Catalog console. For more information, see [Managing products](https://docs.aws.amazon.com//servicecatalog/latest/adminguide/catalogs_products.html#productmgmt-menu) in the *Service Catalog Adminstrator Guide*.

# Step 4. Call your blueprint to create a customized account
<a name="step-4-call-the-blueprint"></a>

When you follow the **Create account** workflow in the AWS Control Tower console, you'll see an optional section where you can enter information about the blueprint you'd like to use for customizing accounts.

**Prerequisites**  
You must set up your customization hub account and add at least one blueprint (Service Catalog product) before you can enter that information into the AWS Control Tower console and begin to provision customized accounts.

**Create or update a customized account in the AWS Control Tower console.**

1. Enter the account ID for the account that contains your blueprints.

1. From that account, select an existing Service Catalog product (existing blueprint).

1. Select the proper version of the blueprint (Service Catalog product), if you have more than one version.

1. (Optional) You can add or change a blueprint provisioning policy at this point in the process. The blueprint provisioning policy is written in JSON and attached to an IAM role, so it can provision the resources that are specified in the blueprint template. AWS Control Tower creates this role in the member account so that Service Catalog can deploy resources using CloudFormation stack sets. The role is named `AWSControlTower-BlueprintExecution-bp-xxxx`. The `AdministratorAccess` policy is applied here by default. 

1. Choose the AWS Region or Regions in which you wish to deploy accounts based on this blueprint.

1. If your blueprint contains parameters, you can enter the values for the parameters into additional fields in the AWS Control Tower workflow. The additional values may include: a GitHub repository name, a GitHub branch, an Amazon ECS cluster name, and a GitHub identity for the repository owner.

1. You can customize accounts at a later time by following the **Account update** process, if your hub account or blueprints are not yet ready.

For more details, see [Create a customized account from a blueprint](create-afc-customized-account.md).

# Create a customized account from a blueprint
<a name="create-afc-customized-account"></a>

After you have created custom blueprints, you can start creating custom accounts in AWS Control Tower account factory. 

**Follow these steps to deploy a custom blueprint when you're creating a new AWS account:**

1. Go to AWS Control Tower in the AWS Management Console. 

1. Select **Account factory** and **Create account**.

1. Enter account details such as account name and email address.

1. Configure IAM Identity Center details with email address and user name. 

1. Select a registered OU where your account will be added.

1. Expand the **Account factory customization** section.

1. Enter the account ID of the blueprint hub account that contains your Service Catalog products and choose **Validate**. For more information about a blueprint hub account, see [Customize accounts with Account Factory Customization (AFC)](af-customization-page.md).

1. Select the dropdown menu that contains all blueprints from your Service Catalog Product List (all custom and partner blueprints). Choose a blueprint and corresponding version to deploy. 

1. If your blueprint contains parameters, these fields are displayed for you to populate. Default values are pre-populated. 

1. Finally, select where you'll deploy your blueprint, either **Home Region** or **All governed Regions**. Global resources such as Route 53 or IAM, may need to be deployed to a single Region only. Regional resources, such as Amazon EC2 instances or Amazon S3 buckets, could be deployed to all governed Regions

1. After all fields are completed, select **Create account**.

**Note**  
Blueprints created with Terraform can deploy to one Region only, not multiple Regions.

You can view the progress of your account provisioning on the **Organization** page. When your account provisioning is complete, the resources specified by your blueprint are already deployed within it. To view the details of the account and blueprint, go to the **Account details** page.

# Customize accounts with AFC as you enroll them
<a name="enroll-and-customize"></a>

To enroll and customize accounts in the AWS Control Tower console. 

1. Navigate to the AWS Control Tower console and select **Organization** from the left navigation.

1. You will see a list of your available accounts. Identify the account you would like to enroll with a custom blueprint. The **State** column for that account should reflect the account in a **Not enrolled** status.

1. Select the radio button to the left of the account and choose the **Actions** dropdown menu, in the top right of the screen. Here you will select the **Enroll** option.

1. Complete the **Access configuration** section with the account's IAM Identity Center information.

1. Select the registered OU where your account will become a member.

1. Complete the **Account factory customization** section using the same steps as 7-12 of the **Create account** procedure. For more information, see [Provision Account Factory accounts with AWS Service Catalog](https://docs.aws.amazon.com/controltower/latest/userguide/provision-as-end-user.html). 

You can view the status of your account progress on the **Organization** page. When your account enrollment is complete, the resources specified by the blueprint are already deployed within it.

# Add a blueprint to an AWS Control Tower account
<a name="add-blueprint-to-account"></a>

 To add a blueprint to an existing AWS Control Tower member account, follow the **Update account** workflow in the AWS Control Tower console, and choose a new blueprint to add to the account. For more information, see [Update and move Account Factory accounts with AWS Control Tower or with AWS Service Catalog](https://docs.aws.amazon.com/controltower/latest/userguide/updating-account-factory-accounts.html#update-account-in-console). 

**Note**  
 If you add a new blueprint to an account, the existing blueprint is overwritten. 

**Note**  
One blueprint may be deployed per AWS Control Tower account.

# Update a blueprint
<a name="update-a-blueprint"></a>

The following procedures describe how to update custom blueprints and how to deploy them.

**To update your custom blueprints**

1. Update your CloudFormation template or Terraform tar.gz file (blueprint) with your new configurations.

1. Save the updated blueprint as a new version in AWS Service Catalog.

**To deploy your updated blueprint**

1. Navigate to the **Organization** page in the AWS Control Tower console.

1. Filter the **Organization** page by blueprint name and version.

1. Follow the **Update account** process, and deploy the latest blueprint version in your account.

**If a blueprint update is unsuccessful**

AWS Control Tower allows blueprint updates when the provisioned product is in the `AVAILABLE` state. If your provisioned product is in a `TAINTED` state, the update will fail. We recommend the following workaround:

1. In the AWS Service Catalog console, manually update the `TAINTED` provisioned product to change the state to `AVAILABLE`. For more information, see [Updating provisioned products](https://docs.aws.amazon.com//servicecatalog/latest/userguide/enduser-update.html).

1. Then, follow the update account process from AWS Control Tower to fix the blueprint deployment error.

*We recommend this manual step because:* When you remove a blueprint, it can cause resources in the member account to be removed. Removing resources may affect your existing workloads. For this reason, we recommend this method rather than the alternative way of updating a blueprint—which is by removing and replacing the original blueprint—especially if you are running production workloads.

# Remove a blueprint from an account
<a name="remove-a-blueprint"></a>

To remove a blueprint from an account, follow the **Update account** workflow to remove the blueprint and return the account to the AWS Control Tower default configurations. 

As you enter the **Update account** workflow in the console, you will see that all of the account details are populated, and the customization details are not populated. If you leave these AFC details blank, AWS Control Tower removes the blueprint from the account. You will see a warning message before the action begins.

**Note**  
AWS Control Tower adds a blueprint to an account only if you select a blueprint during the **Create account** or **Update account** process.

# Partner blueprints
<a name="partner-blueprints"></a>

AWS Control Tower Account Factory Customization (AFC) provides access to pre-defined customization blueprints that are built and managed by AWS Partners. These partner blueprints help you customize your accounts for specific use cases. Each partner's blueprints help you build customized accounts, which are pre-configured to work with the product offerings from that particular partner.

 To view a complete list of AWS Control Tower partner blueprints, navigate to the Service Catalog **Getting Started Library** in your console. Search for the source type **AWS Control Tower Blueprints**. 

## Considerations for Account Factory Customizations (AFC)
<a name="af-limitations"></a>
+ AFC supports customization using a single AWS Service Catalog blueprint product only.
+ The AWS Service Catalog blueprint products must be created in the hub account, and in the same Region as the AWS Control Tower landing zone home Region.
+ The `AWSControlTowerBlueprintAccess` IAM role must be created with the proper name, permissions, and trust policy.
+ AWS Control Tower supports two deployment options for blueprints: deploy to the home Region only, or deploy to all Regions governed by AWS Control Tower. Selection of Regions is not available. 
+ When you update a blueprint in a member account, the blueprint hub account ID and the AWS Service Catalog blueprint product cannot be changed.
+ AWS Control Tower doesn't support removing an existing blueprint and adding a new blueprint in a single blueprint update operation. You can remove a blueprint and then add a new blueprint in separate operations.
+ AWS Control Tower changes behavior, based on whether you are creating or enrolling customized accounts, or non-customized accounts. If you are not creating or enrolling customized accounts with blueprints, AWS Control Tower creates an Account Factory provisioned product (through Service Catalog) in the AWS Control Tower management account. If you are specifying customization when creating or enrolling accounts with blueprints, AWS Control Tower does not create an Account Factory provisioned product in the AWS Control Tower management account.

## In case of a blueprint error
<a name="af-error"></a>

**Error while applying a blueprint**

If an error occurs during the process of applying a blueprint to an account—either a new account or an existing account that you are enrolling into AWS Control Tower—the recovery procedure is the same. The account will exist, but it is not customized, and it is not enrolled into AWS Control Tower. To continue, follow the steps to enroll the account into AWS Control Tower, and add the blueprint at time of enrollment.

**Error while creating the `AWSControlTowerBlueprintAccess` role, and workarounds**

When you create the `AWSControlTowerBlueprintAccess` role from an AWS Control Tower account, you must be signed in as the principal using the `AWSControlTowerExecution` role. If you are signed in as any other, the `CreateRole` operation is prevented by an SCP, as shown in the artifact that follows:

```
{
            "Condition": {
                "ArnNotLike": {
                    "aws:PrincipalArn": [
                        "arn:aws:iam::*:role/AWSControlTowerExecution",
                        "arn:aws:iam::*:role/stacksets-exec-*"
                    ]
                }
            },
            "Action": [
                "iam:AttachRolePolicy",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:DeleteRolePermissionsBoundary",
                "iam:DeleteRolePolicy",
                "iam:DetachRolePolicy",
                "iam:PutRolePermissionsBoundary",
                "iam:PutRolePolicy",
                "iam:UpdateAssumeRolePolicy",
                "iam:UpdateRole",
                "iam:UpdateRoleDescription"
            ],
            "Resource": [
                "arn:aws:iam::*:role/aws-controltower-*",
                "arn:aws:iam::*:role/*AWSControlTower*",
                "arn:aws:iam::*:role/stacksets-exec-*"
            ],
            "Effect": "Deny",
            "Sid": "GRIAMROLEPOLICY"
        }
```

The following workarounds are available:
+ (Most recommended) Assume the `AWSControlTowerExecution` role and create the `AWSControlTowerBlueprintAccess` role. If you choose this workaround, be sure to sign out from the `AWSControlTowerExecution` role immediately afterward, to prevent unintended changes to resources.
+ Sign into an account that is not enrolled in AWS Control Tower, and therefore not subject to this SCP.
+ Temporarily edit this SCP to permit the operation.
+ (Strongly not recommended) Use your AWS Control Tower management account as your hub account, so it is not subject to the SCP.

## Customizing your policy document for AFC blueprints based on CloudFormation
<a name="custom-policy-document"></a>

When you enable a blueprint through account factory, AWS Control Tower directs CloudFormation to create a StackSet on your behalf. CloudFormation requires access to your managed account to create CloudFormation stacks in the StackSet. Although CloudFormation already has administrator privileges in the managed account through the `AWSControlTowerExecution` role, this role is not assumable by CloudFormation.

As part of enabling a blueprint, AWS Control Tower creates a role in the member account, which CloudFormation may assume to complete the StackSet management tasks. The simplest way to enable your customized blueprint through account factory is to use an *allow-all* policy, because those policies are compatible with any blueprint template.

However, best practices suggest that you must restrict the permissions for CloudFormation in the target account. You can provide a customized policy, which AWS Control Tower applies to the role it creates for CloudFormation to use. For example, if your blueprint creates an SSM Parameter called *something-important*, you could provide the following policy:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowCloudFormationActionsOnStacks",
            "Effect": "Allow",
            "Action": "cloudformation:*",
            "Resource": "arn:aws:cloudformation:*:*:stack/*"
        },
        {
            "Sid": "AllowSsmParameterActions",
            "Effect": "Allow",
            "Action": [
                "ssm:PutParameter",
                 "ssm:DeleteParameter",
                 "ssm:GetParameter",
                 "ssm:GetParameters"
            ],
            "Resource": "arn:*:ssm:*:*:parameter/something-important"
        }
    ]
}
```

------

The `AllowCloudFormationActionsOnStacks` statement is required for all AFC custom policies; CloudFormation uses this role to create stack instances, therefore it requires permission to perform CloudFormation actions on stacks. The `AllowSsmParameterActions` section is specific to the template being enabled.

**Resolve permission issues**

When you enable a blueprint with a restricted policy, you may find that there are insufficient permissions to enable the blueprint. To resolve these issues, revise your policy document and update the member account's blueprint preferences to use the corrected policy. To check that the policy is sufficient to enable the blueprint, ensure that the CloudFormation permissions are granted, and that you can create a stack directly using that role.

## Additional permissions required for creating a Terraform-based Service Catalog product
<a name="custom-policy-document-tf"></a>

When you're creating an AWS Service Catalog External product with a Terraform configuration file for AFC, AWS Service Catalog requires certain permissions to be added to your AFC custom IAM policy, in addition to permissions required to create the resources defined in your template. If you choose the default full **Admin** policy, you do not need to add these extra permissions.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "resource-groups:CreateGroup",
                "resource-groups:ListGroupResources",
                "resource-groups:DeleteGroup",
                "resource-groups:Tag"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "tag:GetResources",
                "tag:GetTagKeys",
                "tag:GetTagValues",
                "tag:TagResources",
                "tag:UntagResources"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": "s3:GetObject",
            "Effect": "Allow",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "s3:ExistingObjectTag/servicecatalog:provisioning": "true"
                }
            }
        }
    ]
}
```

------

For more information about creating Terraform products using the External product type in AWS Service Catalog, see [Step 5: Create launch roles](https://docs.aws.amazon.com//servicecatalog/latest/adminguide/getstarted-launchrole-Terraform.html) in the Service Catalog Administrator Guide.

## Transition to the AWS Service Catalog External product type
<a name="service-catalog-external-product-type"></a>

AWS Service Catalog changed support for *Terraform Open Source* products and provisioned products to a new product type, called *External*. To learn more about this transition, review [Updating existing Terraform Open Source products and provisioned products to the External product type](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/update_terraform_open_source_to_external.html) in the *AWS Service Catalog administrator guide*. 

This change effects existing accounts that you created or enrolled with AWS Control Tower account factory customization. To transition these accounts to the *External* product type, you need to make changes in both AWS Service Catalog and AWS Control Tower. 

**To transition to the External product type**

1. Upgrade your existing Terraform Reference Engine for AWS Service Catalog to include support for both *External* and *Terraform Open Source* product types. For instructions about updating your Terraform Reference Engine, review the [AWS Service Catalog GitHub Repository](https://github.com/aws-samples/service-catalog-engine-for-terraform-os).

1. In AWS Service Catalog, duplicate any existing *Terraform Open Source* products (blueprints), with the duplicates using the new *External* product type. **Do not terminate the existing Terraform Open Source blueprints**. 

1. In AWS Control Tower, update each account using a *Terraform Open Source* blueprint to use the new *External* blueprint. 

   1. To update a blueprint, you must first remove the *Terraform Open Source* blueprint completely. For more details, review [Remove a blueprint from an account](https://docs.aws.amazon.com/controltower/latest/userguide/remove-a-blueprint.html). 

   1. Add the new *External* blueprint to the same account. For more details, review [Add a blueprint to an AWS Control Tower account](https://docs.aws.amazon.com/controltower/latest/userguide/add-blueprint-to-account.html). 

1. After all accounts using *Terraform Open Source* blueprints are updated to *External* blueprints, return to AWS Service Catalog and terminate any products that use *Terraform Open Source* as the product type.

1. Going forward, all accounts created or enrolled using AWS Control Tower account factory customization must reference blueprints using the *CloudFormation* or *External* product type. 

   For blueprints created using the *External* product type, AWS Control Tower only supports account customizations that use Terraform templates and the Terraform reference engine. To learn more, review [Set up for customization](https://docs.aws.amazon.com/controltower/latest/userguide/afc-setup-steps.html). 

**Note**  
AWS Control Tower does not support *Terraform Open Source* as a product type when creating new accounts. To learn more about these changes, review [Updating existing Terraform Open Source products and provisioned products to the *External* product type](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/update_terraform_open_source_to_external.html) in the *AWS Service Catalog administrator guide*. AWS Service Catalog will support customers through this product type transition, as needed. Contact your account representative to request assistance.

# Provision accounts with AWS Control Tower Account Factory for Terraform (AFT)
<a name="taf-account-provisioning"></a>

AWS Control Tower Account Factory for Terraform (AFT) adopts a GitOps model that automates the process of account provisioning and updating in AWS Control Tower. 

With AFT, you create an account request Terraform file, which contains the input that invokes the AFT workflow. After account provisioning and updating finishes, the AFT workflow continues by running the AFT account provisioning framework and account customizations steps. 

AFT doesn't impact workflow performance in AWS Control Tower. If you provision an account through AFT or Account Factory, the same backend workflow occurs.

## Prerequisites
<a name="aft-prerequisites"></a>

**Note**  
AFT account provision must target an organizational unit (OU) with AWSControlTowerBaseline enabled in AWS Control Tower. For details of AWSControlTowerBaseline, see: [Baseline types that apply at the OU level](types-of-baselines.md#ou-baseline-types).

When you're getting started with AFT, you will create the following: 
+ In AWS Control Tower create the OU, and then the AFT management account, for your AFT environment. Make note of the account ID, so you can enter it in the `main.tf` file later, when you deploy AFT with the Terraform module. You can view this account ID on the AWS Control Tower **Control details** page. For more information, see the [Terraform documentation](https://developer.hashicorp.com/terraform/tutorials/aws/aws-control-tower-aft). 
+ One or more `git` repositories for your fully deployed AFT environment. For more information, see [Post-deployment steps for AFT](https://docs.aws.amazon.com/controltower/latest/userguide/aft-post-deployment.html). 
+ A fully deployed AFT environment. For more information, see [Overview of AWS Control Tower Account Factory for Terraform (AFT)](https://docs.aws.amazon.com/controltower/latest/userguide/aft-overview.html) and [Deploy AWS Control Tower Account Factory for Terraform (AFT).](https://docs.aws.amazon.com/controltower/latest/userguide/aft-getting-started.html) Also see the [Terraform documentation](https://developer.hashicorp.com/terraform/tutorials/aws/aws-control-tower-aft). 

**Tip**  
You can create the AFT management account from the AWS Control Tower console with **Create account**. For more information, see [Methods of provisioning](https://docs.aws.amazon.com//controltower/latest/userguide/methods-of-provisioning.html).  
Also, optionally, you can create an account template folder to help define your additional accounts, in the **aft-account-customizations** repository. 

For accounts enrolled via Auto Enroll:
+ New account creation through AFT continues to work normally.
+ Existing account import requires additional steps:
  + Register OU to create the necessary provisioned products before importing.
  + Register OU will emit `CreateManagedAccount` and `UpdateManagedAccount` events, enabling AFT customizations.

For information about AWS Regions where AFT has deployment limitations, see [Limitations and quotas in AWS Control Tower](limits.md) and [Control limitations](control-limitations.md).

The [Terraform documentation](https://developer.hashicorp.com/terraform/tutorials/aws/aws-control-tower-aft) contains a good overview of how to set up AWS Control Tower Account Factory for Terraform (AFT).

# Overview of AWS Control Tower Account Factory for Terraform (AFT)
<a name="aft-overview"></a>

 Account Factory for Terraform (AFT) sets up a Terraform pipeline to help you provision and customize accounts in AWS Control Tower. AFT provides you with the advantage of Terraform-based account provisioning while allowing you to govern your accounts with AWS Control Tower. 

 With AFT you create an *account request Terraform file* to get the input that triggers the AFT workflow for account provisioning. After the account provisioning stage is complete, AFT automatically runs a series of steps before the account customizations stage begins. For more information, see [AFT account provisioning pipeline](https://docs.aws.amazon.com/controltower/latest/userguide/aft-provisioning-framework.html). 

 AFT supports Terraform Cloud, Terraform Enterprise, and Terraform Community Edition. With AFT you can initiate account creation using an input file and a simple `git push` command and customize new or existing accounts. Account creation includes all of the AWS Control Tower governance benefits and account customizations that help you meet your organization’s standard security procedures and compliance guidelines. 

 AFT supports account customization request tracing. Every time you submit an account customization request, AFT generates a unique tracing token that passes through an AFT customizations AWS Step Functions state machine, which logs the token as part of its execution. You can then use Amazon CloudWatch Logs insights queries to search timestamp ranges and retrieve the request token. As a result, you can see payloads that accompany the token, so you can trace your account customization request throughout the entire AFT workflow. For information about CloudWatch Logs and Step Functions, see the following: 
+  [What is Amazon CloudWatch Logs?](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html) in the *Amazon CloudWatch Logs User Guide* 
+  [What is AWS Step Functions?](https://docs.aws.amazon.com/step-functions/latest/dg/welcome.html) in the *AWS Step Functions Developer Guide* 

AFT combines the capabilities of other AWS services as [Component services](aft-components.md), to build a framework, with pipelines that deploy Terraform Infrastructure as Code (IaC). AFT enables you to:
+ Submit account provisioning and update requests in a GitOps model
+ Store account metadata and audit history
+ Apply account-level tags
+ Add customizations to all accounts, to a set of accounts, or to individual accounts
+ Enable feature options

AFT creates a separate account, called the *AFT management account*, to deploy AFT capabilities. Before you can set up AFT, you must have an existing AWS Control Tower landing zone. The AFT management account is not the same as the AWS Control Tower management account.

**AFT offers flexibility**
+ **Flexibility for your platform:** AFT supports any Terraform Distribution for initial deployment and ongoing operation: Community Edition, Cloud, and Enterprise.
+ **Flexibility for your version control system:** AFT supports AWS CodeCommit, and alternative version control sources through AWS CodeConnections.

**AFT offers feature options**

You can enable several feature options, based on best practices:
+ Creating an organization-level CloudTrail for logging data events
+ Deleting the AWS default VPC for accounts
+ Enrolling provisioned accounts into the AWS Enterprise Support plan

**Note**  
The AFT pipeline is not intended for use in deploying resources, such as Amazon EC2 instances, that your accounts require to run your applications. It is intended solely for automated provisioning and customizing of AWS Control Tower accounts.

## Video Walkthrough
<a name="terraform-provisioning-video"></a>

This video (7:33) describes how to deploy accounts with AWS Control Tower Account Factory for Terraform. For better viewing, select the icon at the lower right corner of the video to enlarge it to full screen. Captioning is available.

[![AWS Videos](http://img.youtube.com/vi/eDbNvHz02dk/0.jpg)](http://www.youtube.com/watch?v=eDbNvHz02dk)


# AFT Architecture
<a name="aft-architecture"></a>

## Order of operations
<a name="aft-operation"></a>

 You run AFT operations in the AFT management account. For a full account provisioning workflow, the order of stages from left to right in the diagram are as follows: 

1.  Account requests are created and submitted to the pipeline. You can create and submit more than one account request at a time. Account Factory processes requests in a first-in-first-out order. For more information, see [Submit multiple account requests](https://docs.aws.amazon.com/controltower/latest/userguide/aft-multiple-account-requests.html). 

1.  Each account is provisioned. This stage runs in the AWS Control Tower management account. 

1.  Global customizations run in the pipelines that are created for each vended account. 

1.  If customizations are specified in the initial account provisioning requests, the customizations run only on targeted accounts. If you have an account that's already provisioned, you must initiate further customizations manually in the account's pipeline. 

**AWS Control Tower Account Factory for Terraform – account provisioning workflow **

![\[Figure: AFT Workflow Diagram\]](http://docs.aws.amazon.com/controltower/latest/userguide/images/high-level-aft-diagram.png)


# Cost
<a name="aft-pricing"></a>

No additional charge exists for AFT. You pay only for the resources deployed by AFT, the AWS services enabled by AFT, and the resources you deploy in your AFT environment.

The default AFT configuration includes the allocation of AWS PrivateLink endpoints, for enhanced data protection and security, and a NAT gateway that is required to support AWS CodeBuild. For details on the pricing of this infrastructure, see the [AWS PrivateLink pricing](https://aws.amazon.com//privatelink/pricing/) and the [Amazon VPC pricing for the NAT Gateway](https://aws.amazon.com//vpc/pricing/). Contact your AWS account representative for more specific information about managing these costs. You can change these default settings for AFT.

# Deploy AWS Control Tower Account Factory for Terraform (AFT)
<a name="aft-getting-started"></a>

 This section is for administrators of AWS Control Tower environments who wish to set up Account Factory for Terraform (AFT) in their existing environment. It describes how to set up an Account Factory for Terraform (AFT) environment with a new, dedicated AFT management account. 

**Note**  
 A Terraform module deploys AFT. This module is available in the [AFT repository](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main) on GitHub, and the entire AFT repository is considered the module.   
 We recommend that you refer to the AFT modules on GitHub instead of cloning the AFT repository. This way you can control and consume updates to the modules as they are available. 

 For details about the latest releases of the AWS Control Tower Account Factory for Terraform (AFT) functionality, see [the Releases file](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/releases) for this GitHub repository.

 **Deployment prerequisites** 

Before you configure and launch your AFT environment, you must have the following resources available: 
+  A home Region for your AWS Control Tower landing zone. For more information, see [How AWS Regions work with AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/region-how.html). 
+  An AWS Control Tower landing zone. For more information, see [Plan your AWS Control Tower landing zone](https://docs.aws.amazon.com/controltower/latest/userguide/planning-your-deployment.html). 
+  An AFT management account, which you can provision in AWS Control Tower, or provision by other means and enroll into AWS Control Tower. 
+  A Terraform version and distribution. For more information, see [Terraform and AFT versions](https://docs.aws.amazon.com/controltower/latest/userguide/version-supported.html). 
+  A VCS provider for tracking and managing changes to code and other files. By default, AFT uses AWS CodeCommit. For more information, see [What is AWS CodeCommit?](https://docs.aws.amazon.com/codecommit/latest/userguide/welcome.html) in the *AWS CodeCommit User Guide*.

  If you're deploying AFT for the first time and you don't have an existing CodeCommit repository, you must choose an external VCS provider, such as GitHub or BitBucket. For more information, see [Alternatives for version control of source code in AFT](https://docs.aws.amazon.com/controltower/latest/userguide/aft-alternative-vcs.html). 
+  A runtime environment where you can run the Terraform module that installs AFT. 
+  AFT feature options. For more information, see [Enable feature options](https://docs.aws.amazon.com/controltower/latest/userguide/aft-feature-options.html). 

## Configure and launch your AWS Control Tower Account Factory for Terraform
<a name="aft-configure-and-launch"></a>

 The following steps assume that you're familiar with the Terraform workflow. You can also learn more about deploying AFT by following the [Introduction to AFT](https://catalog.workshops.aws/control-tower/en-US/customization/aft) lab on the AWS Workshop Studio website. 

 **Step 1: Launch your AWS Control Tower landing zone** 

 Complete the steps in [Getting started with AWS Control Tower](https://catalog.workshops.aws/control-tower/en-US/customization/aft). This is where you create the AWS Control Tower management account and set up your AWS Control Tower landing zone. 

**Note**  
 Make sure to create a role for the AWS Control Tower management account that has **AdministratorAccess** credentials. For more information, see the following:   
 [IAM Identities (users, user groups, and roles)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html) in the *AWS Identity and Access Management User Guide* 
 [AdministratorAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AdministratorAccess.html) in the *AWS Managed Policy Reference Guide* 

 **Step 2: Create a new organizational unit for AFT (strongly recommended)** 

 We recommend that you create a separate OU in your AWS Control Tower landing zone . This OU is where you provision the AFT management account. Create the new OU and the AFT management account from your AWS Control Tower management account. For more information, see [Create a new OU](https://docs.aws.amazon.com/controltower/latest/userguide/create-new-ou.html). 

 **Step 3: Provision the AFT management account** 

 AFT requires that you provision an AWS account dedicated to AFT management operations. Create the AFT management account when you are signed into the AWS Control Tower management account that is associated to your AWS Control Tower landing zone. You can provision the AFT management account from the AWS Control Tower console by selecting **Create account** on the **Organization** page, or by other means. For more information, see [Provision accounts with AWS Service Catalog Account Factory](https://docs.aws.amazon.com/controltower/latest/userguide/provision-as-end-user.html). 

**Note**  
If you created a separate OU for AFT, make sure to select this OU when you create the AFT management account. 

It can take up to 30 minutes to fully provision the AFT management account. 

 **Step 4: Verify that the Terraform environment is available for deployment** 

 This step assumes that you have experience with Terraform and have procedures in place for executing Terraform. For more information, see [Command: init](https://developer.hashicorp.com/terraform/cli/commands/init) on the HashiCorp Developer website. 

**Note**  
 AFT supports Terraform Version `1.6.0` or later. 

 **Step 5: Optional configurations**
+ **Optionally set the virtual private cloud (VPC) configuration**

  The AFT module includes a `aft_enable_vpc` parameter, which specifies whether AWS Control Tower provisions account resources within a VPC in the central AFT management account. By default, the parameter is set to `true`. If you set this parameter to `false`, AWS Control Tower deploys AFT *without* the use of a VPC and private networking resources, such as NAT Gateways or VPC endpoints. Disabling `aft_enable_vpc` may help reduce the operating cost of AFT *for some usage patterns*. Adding any VPC configurations overrides the `aft_enable_vpc` parameter being set to `false`.
**Note**  
Re-enabling the `aft_enable_vpc` parameter (switching the value from `false` to `true`) may require you to run the `terraform apply` command twice in succession.

  Instead of provisioning a new VPC, you can configure AFT to use an existing VPC in your account. To use your own VPC, provide the following VPC configuration parameters:
  + `aft_customer_vpc_id` - The ID of your existing VPC
  + `aft_customer_private_subnets` - A list of private subnet IDs in your VPC

  Example configuration:

  ```
  module "aft" {
    source = "github.com/aws-ia/terraform-aws-control_tower_account_factory"
    
    # VPC configuration
    aft_customer_vpc_id = "vpc-0123456789abcdef0"
    aft_customer_private_subnets = ["subnet-0123456789abcdef0", "subnet-0123456789abcdef1"]
    
    # Other AFT parameters...
  }
  ```
**Important**  
We don't recommend that you use the custom VPC option if you have an existing AFT deployment. You may have dependencies on Lambda functions or CodePipeline that depend on resources within the underlying existing VPC.
+ **Optionally configure the Terraform project name**

  You can customize the Terraform project name used by AFT by setting the `terraform_project_name` parameter. By default, AFT puts the deployment in the "default" project in Terraform Cloud or Terraform Enterprise.

  Example configuration:

  ```
  module "aft" {
    source = "github.com/aws-ia/terraform-aws-control_tower_account_factory"
    
    # Project name configuration
    terraform_project_name = "my-organization-aft"
    
    # Other AFT parameters...
  }
  ```
**Note**  
This parameter is only applicable to Terraform Enterprise or Terraform Cloud deployments.
+ **Optionally apply custom tags to AFT resources**

  You can apply custom tags to all AFT resources by using the `tags` parameter. These tags help with resource organization, cost allocation, and access control.

  Example configuration:

  ```
  module "aft" {
    source = "github.com/aws-ia/terraform-aws-control_tower_account_factory"
    
    # Custom tags configuration
    tags = {
      Environment = "Production"
      CostCenter = "IT-12345"
      Project = "AFT-Deployment"
      Owner = "platform-team@example.com"
    }
    
    # Other AFT parameters...
  }
  ```

  These tags are applied to all resources created by the AFT module. AFT automatically adds a `managed_by = "AFT"` tag to all resources, which can't be overridden by custom tags.
**Note**  
Custom tags can be added at any time, not just during initial deployment.
+ **Optionally apply an AWS KMS customer-managed encryption key (CMK) to CloudWatch log groups and SNS topics**

  To enable KMS CMK encryption for log groups and SNS topics, set the `cloudwatch_log_group_enable_cmk_encryption` and `sns_topic_enable_cmk_encryption` variables.

  If you opt into these settings, AFT uses the existing CMK, *alias/aft*, to encrypt CloudWatch logs and SNS topics. This CMK is created when AFT is deployed in the AFT management account, and it can be applied to log groups and SNS topics. 
  + If the variable `cloudwatch_log_group_enable_cmk_encryption` is set to **true**, the CloudWatch log groups for AFT are encrypted using the CMK. If the variable is set to **false**, which is the default value, the logs are encrypted using [server side encryption with the CloudWatch logs default](https://docs.aws.amazon.com//AmazonCloudWatch/latest/logs/encrypt-log-data-kms.html).
  +  If the variable `sns_topic_enable_cmk_encryption` is set to **true**, notifications sent to the AFT SNS topics (*aft-notifications* and *aft-failure-notifications*) are encrypted using the CMK. If the variable is set to **false**, which is the default value, the SNS messages are encrypted with the AWS-managed key: *alias/aws/sns*. For more information, see [SSE key terms](https://docs.aws.amazon.com//sns/latest/dg/sns-server-side-encryption.html#sse-key-terms).
+ **Optionally change your CodeBuild compute type**

  During deployment, to change the compute type that AFT uses for CodeBuild, set the variable `aft_codebuild_compute_type`.

  For information about accepted compute types, see [About on-demand environment types](https://docs.aws.amazon.com//codebuild/latest/userguide/build-env-ref-compute-types.html#environment.types). The default compute type is `BUILD_GENERAL1_MEDIUM`. 
+ **Optionally configure OpenID Connect (OIDC) for Terraform**

  Customers using Terraform Enterprise or HCP Terraform (formerly Terraform Cloud) can use Terraform's Workload identity tokens (or dynamic provider credentials), built on the OIDC protocol, to securely connect and authenticate workspaces with AFT.

  You can enable OIDC integration for AFT workspaces by setting the `terraform_oidc_integration` parameter to `true`. By default, this parameter is set to `false`. When enabling this parameter, the `terraform_oidc_aws_audience` and `terraform_oidc_hostname` parameters should be reviewed and configured if the defaults (`aws.workload.identity` and `app.terraform.io`, respectively) do not match your environment.

  Example configuration:

  ```
  module "aft" {
    source = "github.com/aws-ia/terraform-aws-control_tower_account_factory"
    
    # Terraform distribution must be "tfc" or "tfe" for OIDC
    terraform_distribution = "tfc"
  
    # Terraform OIDC Configuration
    terraform_oidc_integration  = true
    terraform_oidc_aws_audience = "aws.workload.identity"  # default
    terraform_oidc_hostname     = "app.terraform.io"       # default; set to your TFE hostname if applicable
    
    # Other AFT parameters...
  }
  ```
**Note**  
This parameter is only applicable to Terraform Enterprise or HCP Terraform deployments.
**Note**  
If you are currently leveraging an OIDC provider for Terraform in the AFT management account, you must delete that provider prior to opting-in to this integration. AFT will re-create that provider for you upon deployment.

**Step 6: Call the Account Factory for Terraform module to deploy AFT** 

 Call the AFT module with the role that you created for the AWS Control Tower management account that has **AdministratorAccess** credentials. AWS Control Tower provisions a Terraform module through the AWS Control Tower management account, which establishes all of the infrastructure required to orchestrate AWS Control Tower Account Factory requests. 

 You can view the AFT module in the [AFT repository](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main) on GitHub. The entire GitHub repository is considered the AFT module. Refer to the [README file](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/blob/main/README.md) for information about the inputs that are required to run the AFT module and deploy AFT. Alternatively, you can view the AFT module in the [Terraform Registry](https://registry.terraform.io/modules/aws-ia/control_tower_account_factory/aws/latest). 

 If you have pipelines in your environment that are established for managing Terraform, you can integrate the AFT module into your existing workflow. Otherwise, run the AFT module from any environment that's authenticated with the required credentials. 

 Timeout causes deployment to fail. We recommend using AWS Security Token Service (STS) credentials to ensure you have a timeout that's sufficient for a full deployment. The minimum timeout for AWS STS credentials is 60 minutes. For more information, see [Temporary security credentials in IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html) in the *AWS Identity and Access Management User Guide*. 

**Note**  
 You might wait up to 30 minutes for AFT to finish deploying through the Terraform module. 

 **Step 7: Manage the Terraform state file** 

 A Terraform state file is generated when you deploy AFT. This artifact describes the state of the resources that Terraform created. If you plan to update the AFT version, make sure to preseve the Terraform state file, or set up a Terraform backend using Amazon S3 and DynamoDB. The AFT module doesn't manage a backend Terraform state. 

**Note**  
 You're responsible for protecting the Terraform state file. Some input variables might contain sensitive values, such as a private `ssh` key or Terraform token. Depending on your deployment method, these values can be viewable as plain text in the Terraform state file. For more information, see [Sensitive data in State](https://www.terraform.io/docs/language/state/sensitive-data.html) on the HashiCorp website. 

# Post-deployment steps
<a name="aft-post-deployment"></a>

After the AFT infrastructure deployment is complete, follow these additional steps to complete the setup process and get ready to provision accounts. 

**Step 1: Complete CodeConnections with your desired VCS provider**

If you choose a third-party VCS provider, AFT establishes CodeConnections, and you confirm them. Refer to [Alternatives for version control of source code in AFT](aft-alternative-vcs.md) to learn how to set up AFT with your preferred VCS.

The initial step of establishing the AWS CodeStar connection is accomplished by AFT. You must confirm the connection.

**Step 2: Populate each repository**

AFT requires that you manage [four repositories:](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos)

1. Account requests – This repository handles placing or updating account requests. [Examples available](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-account-request) . For more information about AFT account requests, see [Provision a new account with AFT](aft-provision-account.md).

1. AFT account provisioning customizations – This repository manages customizations that are applied to all accounts created by and managed with AFT, before beginning the global customizations stage. [Examples available](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-account-provisioning-customizations) . To create AFT account provisioning customizations, see [Create your AFT account provisioning customizations state machine](aft-provisioning-framework.md#aft-create-customizations).

1. Global customizations – This repository manages customizations that are applied to all accounts created by and managed with AFT. [Examples available](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-global-customizations) . To create AFT global customizations, see [Apply global customizations](aft-account-customization-options.md#aft-global-customizations).

1. Account customizations – This repository manages customizations that are applied only to specific accounts created by and managed with AFT. [Examples available](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-account-customizations) . To create AFT account customizations, see [Apply account customizations](aft-account-customization-options.md#aft-account-customizations).

 AFT expects that each of these repositories follow a specific directory structure. The templates that are used to populate your repositories and instructions that describe how to populate the templates are available in the Account Factory for Terraform module in the [AFT github repository](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos). 

# Provision a new account with AFT
<a name="aft-provision-account"></a>

*This section assumes that you've already set up AFT and your AFT management account, and you are provisioning additional accounts.*

To provision a new account with AFT, create an account request Terraform file. This file contains the input for parameters in the **aft-account-request** repository. After creating an account request Terraform file, begin processing your account request by running `git push`. This command invokes the `ct-aft-account-request` operation in the AWS CodePipeline, which is created in the AFT management account after account provisioning finishes. For more information, see [AFT account provisioning pipeline](https://docs.aws.amazon.com/controltower/latest/userguide/aft-provisioning-framework.html). 

## Account request Terraform file parameters
<a name="w2aac44c33c15b7"></a>

 You must include the following parameters in your account request Terraform file. You can view [an example account request Terraform file](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-account-request) on GitHub. 
+  The value of `module name` must be unique per the AWS account request. 
+  The value of `module source` is the path to the account request Terraform module that AFT provides. 
+  The value of `control_tower_parameters` captures the required input to create an AWS Control Tower account. The value includes the following input fields: 
  + `AccountEmail`
  + `AccountName`
  +  `ManagedOrganizationalUnit` 
  + `SSOUserEmail`
  + `SSOUserFirstName`
  + `SSOUserLastName`

**Note**  
 The input that you provide for `control_tower_parameters` can't be changed during the account provisioning.   
 The supported formats for specifying `ManagedOrganizationalUnit` in the **aft-account-request** repository include `OUName` and `OUName (OU-ID)`. 
+  `account_tags` captures user-defined keys and values, which can tag AWS accounts according to business criteria. For more information, see [Tagging AWS Organizations resources](https://docs.aws.amazon.com//organizations/latest/userguide/orgs_tagging.html) in the *AWS Organizations User Guide*. 
+  The value of `change_management_parameters` captures additional information, such as why an account request was created and who initiated the account request. The value includes the following input fields: 
  + `change_reason`
  + `change_requested_by`
+  `custom_fields` captures additional metadata with keys and values that deploy as SSM parameters in the vended account under **/aft/account-request/custom-fields/**. You can reference this metadata during account customizations to deploy proper controls. For example, an account that's subject to regulatory compliance might deploy additional AWS Config Rules. The metadata that you collect with `custom_fields` can invoke additional processing during account provisioning and updating. If a custom field is removed from the account request, the custom field is removed from the SSM Parameter Store for the vended account. 
+  (Optional) `account_customizations_name` captures the account template folder in the **aft-account-customizations** repository. For more information, see [Account customizations](https://docs.aws.amazon.com/controltower/latest/userguide/aft-account-customization-options.html). 

# Submit multiple account requests
<a name="aft-multiple-account-requests"></a>

 AFT processes account requests one at a time, but you can submit multiple account requests to the AFT pipeline. When you submit multiple account requests to the AFT pipeline, AFT queues and processes the account requests in a first-in, first-out order. 

**Note**  
 You can create an account request Terraform file for each account that you want AFT to provision or cascade multiple account requests in a single account request Terraform file. 

# Update an existing account
<a name="aft-update-account"></a>

**Auto Enroll Compatibility**  
If your organization uses Auto Enroll for automatic account enrollment, be aware that AFT has limitations with importing these accounts. Accounts enrolled through Auto Enroll lack the Service Catalog provisioned products required by AFT's import workflow.  
**Workaround:** Use the Register OU feature to create provisioned products for automatically enrolled accounts. This enables the necessary lifecycle events for AFT customizations.

 You can update accounts that AFT provisions by editing previously submitted account requests and running `git push`. This command invokes the account provisioning workflow and can process account update requests. You can update the input for `ManagedOrganizationalUnit`, which is part of the required value for `control_tower_parameters`.

`ManagedOrganizationalUnit` is the only parameter that can be updated, among all `control_tower_parameters`. However, other parameters that are part of the account request Terraform file can be updated, such as `custom_fields`. For more information, see [Provision a new account with AFT](https://docs.aws.amazon.com/controltower/latest/userguide/aft-provision-account.html). 

For example, to update the name or email address of an AFT account, you can define the specifics as `custom_fields` in the Account Request file. By doing so, you create SSM parameters, which you can pass into the `aws_account_alternate_contact` resource during global customizations.

```
resource "aws_account_alternate_contact" "operations" {

  alternate_contact_type = "OPERATIONS"

  name          = "Example"
  title         = "Example"
  email_address = "someone@example.com"
  phone_number  = "+1234567890"
}
```

You can add similar fields for other contact types, such as operations and security. In Global Customizations, add data lookups for each custom field, to ensure that you look up all the fields you created in Account Request:

```
data "aws_ssm_parameter" "billing_name" {
            name = "/aft/account-request/custom-fields/billing_name"
            }
            
            data "aws_ssm_parameter" "billing_title" {
            name = "/aft/account-request/custom-fields/billing_title"
            }
            
            data "aws_ssm_parameter" "billing_email_address" {
            name = "/aft/account-request/custom-fields/billing_email_address"
            }
            
            data "aws_ssm_parameter" "billing_phone_number" {
            name = "/aft/account-request/custom-fields/billing_phone_number"
            }
```

Finally, also in the Global Customizations file, create the alternate contact resources. You will need to define one of these blocks for every contact type you created in Account Request:

```
resource "aws_account_alternate_contact" "billing" {
            
            alternate_contact_type = "BILLING"
            
            name          = data.aws_ssm_parameter.billing_name.value
            title         = data.aws_ssm_parameter.billing_title.value
            email_address = data.aws_ssm_parameter.billing_email_address.value
            phone_number  = data.aws_ssm_parameter.billing_phone_number.value
            }
```

**Note**  
 The input that you provide for `control_tower_parameters` can't be changed during account provisioning.   
 The supported formats for specifying `ManagedOrganizationalUnit` in the **aft-account-request** repository include `OUName` and `OUName (OU-ID)`. 

## Update an account that AFT doesn't provision
<a name="aft-update-account-not-provision"></a>

 You can update AWS Control Tower accounts created outside of AFT by specifying the account in the **aft-account-request** repository. 

**Note**  
 Make sure that all account details are correct and consistent with the AWS Control Tower organization and respective AWS Service Catalog provisioned product. 

**Prerequisites for updating an existing AWS account with AFT**
+  The AWS account must be enrolled in AWS Control Tower. 
+  The AWS account must be part of the AWS Control Tower organization. 

# Terraform and AFT versions
<a name="version-supported"></a>

Account Factory for Terraform (AFT) supports Terraform version `1.6.0` or later. You must provide a Terraform version as an input parameter for the AFT deployment process, as shown in the example that follows.

```
terraform_version = "1.6.0"
```

## Terraform distributions
<a name="terraform-distributions"></a>

AFT supports three Terraform distributions:
+ Terraform Community Edition
+ Terraform Cloud
+ Terraform Enterprise

These distributions are explained in the sections that follow. Provide the Terraform distribution of your choice as an input parameter during the AFT bootstrap process. For more information on AFT deployment and input parameters, see [Deploy AWS Control Tower Account Factory for Terraform (AFT)](aft-getting-started.md) .

If you choose the Terraform Cloud or Terraform Enterprise distributions, the [API token](https://www.terraform.io/cloud-docs/users-teams-organizations/api-tokens) you specify for `terraform_token `must be a User or Team API token. An Organization token is not supported for all required APIs. For security reasons, you must avoid checking in this token's value to your version control system (VCS) by assigning a [terraform variable](https://www.terraform.io/cloud-docs/workspaces/variables/managing-variables), as shown in the example that follows.

```
 # Sensitive variable managed in Terraform Cloud:
 terraform_token = var.terraform_cloud_token
```

### Terraform Community Edition
<a name="terraform-oss"></a>

When you select Terraform Community Edition as your distribution, AFT manages the Terraform backend for you in the AFT management account. AFT downloads the `terraform-cli` of your specified Terraform version to run during the AFT deployment and the AFT pipeline phases. The resulting Terraform state configuration is stored in an Amazon S3 bucket, named with the following form:

```
aft-backend-[account_id]-primary-region
```

AFT also creates an Amazon S3 bucket that replicates your Terraform state configuration in another AWS Region, for disaster recovery purposes, named with the following form:

```
aft-backend-[account_id]-secondary-region
```

We recommend that you enable multi-factor authentication (MFA) for delete functions on these Terraform state Amazon S3 buckets. To learn more about Terraform Community Edition, see [the Terraform documentation](https://www.terraform.io/docs/cli/index.html) .

To select Terraform OSS as your distribution, provide the following input parameter:

```
terraform_distribution = "oss"
```

### Terraform Cloud
<a name="terraform-cloud"></a>

 When you select Terraform Cloud as your distribution, AFT creates workspaces for the following components in your Terraform Cloud organization, which initiates an API-driven workflow. 
+  Account request 
+  AFT customizations for accounts that AFT provisions 
+  Account customizations for accounts that AFT provisions 
+  Global customizations for accounts that AFT provisions 

 Terraform Cloud manages the resulting Terraform state configuration. 

 When you select Terraform Cloud as your distribution, provide the following input parameters: 
+  `terraform_distribution = "tfc"` 
+  `terraform_token` – This parameter contains the value of the Terraform Cloud token. AFT marks the as sensitive and stores the value as a secure string in the SSM parameter store in the AFT management account. We recommend that you periodically rotate the value of the Terraform token according to your company's security policies and compliance guidelines. The Terraform token should be a User or Team level API token. Organization tokens are not supported. 
+  `terraform_org_name` – This parameter contains the name of your Terraform Cloud organization. 

**Note**  
 Multiple AFT deployments in a single Terraform Cloud organization is not supported. 

 For information about how to set up Terraform Cloud, see [the Terraform documentation](https://www.terraform.io/docs/cloud/index.html). 

### Terraform Enterprise
<a name="terraform-enterprise"></a>

When you select Terraform Enterprise as your distribution, AFT creates workspaces for the following components in your Terraform Enterprise organization, and it triggers API-driven workflow for the resulting Terraform runs.
+ Account request
+ AFT account provisioning customizations for accounts provisioned by AFT
+ Account customizations for accounts provisioned by AFT
+ Global customizations for accounts provisioned by AFT

The resulting Terraform state configuration is managed by your Terraform Enterprise setup.

To select Terraform Enterprise as your distribution, provide the following input parameters:
+  `terraform_distribution = "tfe"` 
+ `terraform_token` – This parameter contains the value of your Terraform Enterprise token. AFT marks its value as sensitive and stores it as a secure string in the SSM parameter store, in the AFT management account. We recommend that you periodically rotate the value of the Terraform token, according to your company's security policies and compliance guidelines.
+ `terraform_org_name` – This parameter contains the name of your Terraform Enterprise organization.
+ `terraform_api_endpoint` – This parameter contains the URL of your Terraform Enterprise environment. The value of this parameter must be in the format:

  ```
  https://{fqdn}/api/v2/
  ```

See [the Terraform documentation](https://www.terraform.io/docs/enterprise/index.html) to learn more about how to set up Terraform Enterprise.

# Check the AFT version
<a name="check-aft-version"></a>

You can check your deployed AFT version by querying the AWS SSM Parameter Store key:

```
/aft/config/aft/version
```

If you use the registry method, you can pin the version.

```
module "control_tower_account_factory" {
  source  = "aws-ia/control_tower_account_factory/aws"
  version = "1.3.2"
  # insert the 6 required variables here
}
```

You can view more information about AFT versions in the [AFT repository](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main).

# Update the AFT version
<a name="update-aft-version"></a>

Sign in to the AWS Control Tower management account to initiate this AFT update.

You can update your deployed AFT version by pulling it in from the `main` repository branch:

```
terraform get -update
```

After the pull is complete, you can re-run the Terraform plan or run apply to update the AFT infrastructure with the latest changes.

# Enable feature options
<a name="aft-feature-options"></a>

AFT offers feature options based on best practices. You can opt-in to these features, by means of feature flags, during AFT deployment. Refer to [Provision a new account with AFT](aft-provision-account.md) for more information about AFT input configuration parameters.

These features are not enabled by default. You must explicitly enable each one in your environment.

**Topics**
+ [AWS CloudTrail data events](#cloudtrail-data-event-option)
+ [AWS Enterprise Support plan](#enterprise-support-option)
+ [Delete the AWS default VPC](#delete-default-vpc-option)

## AWS CloudTrail data events
<a name="cloudtrail-data-event-option"></a>

When enabled, the AWS CloudTrail data events option configures these capabilities.
+ Creates an Organization Trail in the AWS Control Tower management account, for CloudTrail
+ Turns on logging for Amazon S3 and Lambda data events
+ Encrypts and exports all the CloudTrail data events to an `aws-aft-logs-*` S3 bucket in the AWS Control Tower Log Archive account, with AWS KMS encryption
+ Turns on the **Log file validation** setting

To enable this option, set the following feature flag to **True** in your AFT deployment input configuration.

```
aft_feature_cloudtrail_data_events
```

**Prerequisite**

Before you enable this feature option, be sure that trusted access for AWS CloudTrail is enabled in your organization. 

**To check the status of trusted access for CloudTrail :**

1. Navigate to the AWS Organizations console.

1. Choose **Services > CloudTrail**.

1. Then select **Enable trusted access** in the upper right, if needed.

You may receive a warning message that advises you to use the AWS CloudTrail console, but in this case, disregard the warning. AFT creates the trail as part of enabling this feature option, after you allow trusted access. If trusted access is not enabled, you will receive an error message when AFT attempts to create your trail for data events.

**Note**  
This setting works at the organization level. Enabling this setting affects all accounts in AWS Organizations, whether they are managed by AFT or not. All buckets in the AWS Control Tower Log Archive account at the time of enabling are excluded from Amazon S3 data events. Refer to [the AWS CloudTrail User Guide](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html) to learn more about CloudTrail.

## AWS Enterprise Support plan
<a name="enterprise-support-option"></a>

When this option is enabled, the AFT pipeline turns on the AWS Enterprise Support plan for accounts provisioned by AFT.

AWS accounts by default come with the AWS Basic Support plan enabled. AFT provides automated enrollment into the enterprise support level, for accounts that AFT provisions. The provisioning process opens a support ticket for the account, requesting it to be added to the AWS Enterprise Support plan.

To enable the Enterprise Support option, set the following feature flag to **True** in your AFT deployment input configuration.

```
aft_feature_enterprise_support=false
```

Refer to [Compare AWS Support Plans](https://aws.amazon.com/premiumsupport/plans/) to learn more about AWS Support Plans.

**Note**  
To allow this feature to operate, you must enroll the payer account into the Enterprise Support plan.

## Delete the AWS default VPC
<a name="delete-default-vpc-option"></a>

 When you enable this option, AFT deletes all AWS default VPCs in the AFT management account and in all AWS Regions, even if haven't deployed AWS Control Tower resources in those AWS Regions. 

 AFT doesn't delete AWS default VPCs automatically for any AWS Control Tower accounts that AFT provisions or for existing AWS accounts that you enroll in AWS Control Tower through AFT. 

New AWS accounts are created with a VPC set up in each AWS Region, by default. Your enterprise may have standard practices for creating VPCs, which require you to delete the AWS default VPC and avoid enabling it, especially for the AFT management account. 

To enable this option, set the following feature flag to **True** in your AFT deployment input configuration.

```
aft_feature_delete_default_vpcs_enabled
```

The following is an example of a AFT deployment input configuration.

```
module "aft" {
  source = "github.com/aws-ia/terraform-aws-control_tower_account_factory"
  ct_management_account_id    = var.ct_management_account_id
  log_archive_account_id      = var.log_archive_account_id
  audit_account_id            = var.audit_account_id
  aft_management_account_id   = var.aft_management_account_id
  ct_home_region              = var.ct_home_region
  tf_backend_secondary_region = var.tf_backend_secondary_region

  vcs_provider                                  = "github"
  account_request_repo_name                     = "${var.github_username}/learn-terraform-aft-account-request"
  account_provisioning_customizations_repo_name = "${var.github_username}/learn-terraform-aft-account-provisioning-customizations"
  global_customizations_repo_name               = "${var.github_username}/learn-terraform-aft-global-customizations"
  account_customizations_repo_name              = "${var.github_username}/learn-terraform-aft-account-customizations"

  # Optional Feature Flags
  aft_feature_delete_default_vpcs_enabled = true
  aft_feature_cloudtrail_data_events      = false
  aft_feature_enterprise_support          = false
}
```

Refer to [Default VPC and default subnets](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html) to learn more about default VPCs.

# Resource considerations for AWS Control Tower Account Factory for Terraform
<a name="aft-resources"></a>

When you set up your landing zone using AWS Control Tower Account Factory for Terraform, several types of AWS resources are created within your AWS accounts.

**Search for resources**
+ You can use tags to search for the most updated list of AFT resources. The key-value pair for your search is:

  ```
  Key: managed_by | Value: AFT
  ```
+ For component services that do not support tags, you can locate resources with a search for `aft` in the resource names.

**Note**  
AFT does not create any AWS Backup resources in the management account.

**Tables of resources initially created, by account**


**AWS Control Tower Account Factory for Terraform management account**  

| **AWS service** | **Resource type** | **Resource name** | 
| --- | --- | --- | 
| AWS Identity and Access Management | Roles |  AWSAFTAdmin AWSAFTExecution AWSAFTService ct-aft-\$1 aft-\$1 codebuild\$1trigger\$1role python-layer-builder-aft-common-\$1 | 
| AWS Identity and Access Management | Policies | aft-\$1 | 
| CodeCommit | Repositories | aft-\$1 | 
| CodeBuild | Build Projects | aft-\$1 ct-aft-\$1 python-layer-builder-aft-common-\$1  | 
| Code Pipeline | Pipelines | **YourAccountId**-customizations-pipeline | 
| Amazon S3 | Buckets | aft-\$1  | 
| Lambda | Functions | aft-\$1 | 
| Lambda | Layers | aft-common-\$1 | 
| DynamoDB | Tables | aft-request aft-request-audit aft-request-metadata aft-controltower-events | 
| Step Functions | State Machines | aft-account-provisioning-customizations aft-account-provisioning-framework aft-feature-options aft-invoke-customizations | 
| VPC | VPC | aft-management-vpc | 
| Amazon SNS | Topics | aft-notifications aft-failure-notifications | 
| Amazon EventBridge | Event buses | aft-events-from-ct-management | 
| Amazon EventBridge | Event rules | aft-account-provisioning-customizations-trigger aft-account-request-codepipeline-trigger aft-lambda-account-request-processor aft-controltower-event-logger | 
| Key Management Service (KMS) | Customer Managed Keys | aft-backend-\$1-kms-key aft | 
| AWS Systems Manager | Parameter store | /aft/\$1  | 
| Amazon SQS | Queues | aft-account-request.fifo aft-account-request-dlg.fifo | 
| CloudWatch | Log groups | /aws/\$1/ct-aft-\$1 /aws/\$1/aft-\$1 /aws/codebuild/python-layer-builder-aft-common-\$1 | 
| AWS Backup | Vaults | aft-controltower-backup-vault | 
| AWS Backup | Plans | aft-controltower-backup-plan | 
| AWS Support Center (Optional) | Support plans | Enterprise | 


**AWS accounts provisioned through AWS Control Tower Account Factory for Terraform**  

| **AWS service** | **Resource type** | **Resource name** | 
| --- | --- | --- | 
| AWS Identity and Access Management | Roles | AWSAFTExecution | 
| AWS Support Center (Optional) | Support plans | Enterprise | 


**AWS Control Tower management account**  

| **AWS service** | **Resource type** | **Resource name** | 
| --- | --- | --- | 
| AWS Identity and Access Management | Roles |  AWSAFTExecution AWSAFTService aft-controltower-events-rule  | 
| AWS Systems Manager | Parameter store | /aft/\$1 | 
| EventBridge | Event rules | aft-capture-ct-events | 
| CloudTrail (Optional) | Trails | aws-aft-CustomizationsCloudTrail | 
| AWS Support Center (Optional) | Support plans | Enterprise | 


**AWS Control Tower log archive account**  

| **AWS service** | **Resource type** | **Resource name** | 
| --- | --- | --- | 
| AWS Identity and Access Management | Roles |  AWSAFTExecution AWSAFTService  | 
| Key Management Service (KMS) | Customer Managed Keys | aft | 
| Amazon S3 | Buckets | aws-aft-logs-\$1 aws-aft-s3-access-logs-\$1 | 
| AWS Support Center (Optional) | Support plans | Enterprise | 


**AWS Control Tower audit account**  

| **AWS service** | **Resource type** | **Resource name** | 
| --- | --- | --- | 
| AWS Identity and Access Management | Roles |  AWSAFTExecution AWSAFTService  | 
| AWS Support Center (Optional) | Support plans | Enterprise | 

# Required roles
<a name="aft-required-roles"></a>

In general, roles and policies are part of identity and access management (IAM) in AWS. Refer to the [https://docs.aws.amazon.com//IAM/latest/UserGuide/introduction.html](https://docs.aws.amazon.com//IAM/latest/UserGuide/introduction.html) for more information.

AFT creates multiple IAM roles and policies in the AFT management and AWS Control Tower management accounts to support the operations of the AFT pipeline. These roles are created based on the least privilege access model, which restricts permission to the minimally required sets of actions and resources for each role and policy. These roles and policies are assigned an AWS tag `key:value` pair, as ` managed_by:AFT` for identification. 

Besides these IAM roles, AFT creates three essential roles:
+ the `AWSAFTAdmin` role
+ the `AWSAFTExecution` role
+ the `AWSAFTService` role

These roles are explained in the following sections.

**The AWSAFTAdmin role, explained**

When you deploy AFT, the `AWSAFTAdmin` role is created in the AFT management account. This role allows the AFT pipeline to assume the `AWSAFTExecution` role in AWS Control Tower and AFT provisioned accounts, thereby to perform actions related to account provisioning and customizations.

Here is the inline policy (JSON artifact) attached to the `AWSAFTAdmin` role: 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": [
                "arn:aws:iam::*:role/AWSAFTExecution",
                "arn:aws:iam::*:role/AWSAFTService"
            ]
        }
    ]
}
```

------

The following JSON artifact shows the trust relationship for the `AWSAFTAdmin` role. The placeholder number `012345678901` is replaced by the AFT management account ID number.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::012345678901:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

**The AWSAFTExecution role, explained**

When you deploy AFT, the `AWSAFTExecution` role is created in the AFT management and AWS Control Tower management accounts. Later, the AFT pipeline creates the `AWSAFTExecution` role in each AFT provisioned account during the AFT account provisioning stage.

 AFT utilizes the `AWSControlTowerExecution` role initially, to create the `AWSAFTExecution` role in specified accounts. The `AWSAFTExecution` role allows the AFT pipeline to run the steps that are performed during the AFT framework's provisioning and provisioning customizations stages, for AFT provisioned accounts and for shared accounts.

**Distinct roles help you limit scope**  
As a best practice, keep the customization permissions separate from the permissions allowed during your initial deployment of resources. Remember that the `AWSAFTService` role is intended for account provisioning, and the `AWSAFTExecution` role is intended for account customization. This separation limits the scope of permissions that are allowed during each phase of the pipeline. This distinction is especially important if you are customizing the AWS Control Tower shared accounts, because the shared accounts may contain sensitive information, such as billing details or user information.

Permissions for `AWSAFTExecution` role: **AdministratorAccess** – an AWS managed policy 

The following JSON artifact shows the IAM policy (trust relationship) attached to the `AWSAFTExecution` role. The placeholder number `012345678901` is replaced by the AFT management account ID number.

Trust policy for `AWSAFTExecution`

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::012345678901:role/AWSAFTAdmin"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

**The AWSAFTService role, explained**

The `AWSAFTService` role deploys AFT resources in all enrolled and managed accounts, including the shared accounts and management account. Resources formerly were deployed by the `AWSAFTExecution` role only.

The `AWSAFTService` role is intended for use by the service infrastructure to deploy resources during the provisioning stage, and the `AWSAFTExecution` role is intended to be used only to deploy customizations. By assuming the roles in this way, you can maintain more granular access control during the each stage.

Permissions for `AWSAFTService` role: **AdministratorAccess** – an AWS managed policy 

The following JSON artifact shows the IAM policy (trust relationship) attached to the `AWSAFTService` role. The placeholder number `012345678901` is replaced by the AFT management account ID number.

Trust policy for `AWSAFTService`

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::012345678901:role/AWSAFTAdmin"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

# Component services
<a name="aft-components"></a>

When you deploy AFT, components are added to your AWS environment from each of these AWS services.
+ **[AWS Control Tower](https://docs.aws.amazon.com//controltower/latest/userguide/what-is-control-tower.html)** – AFT uses AWS Control Tower Account Factory in the AWS Control Tower management account to provision accounts.
+ **[Amazon DynamoDB](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/Introduction.html)** – AFT creates Amazon DynamoDB tables in the AFT management account, which store account requests, audit history of account updates, account metadata, and AWS Control Tower lifecycle events. AFT also creates DynamoDB Lambda triggers to initiate downstream processes, such as starting the AFT account provisioning workflow. 
+ **[Amazon Simple Storage Service](https://docs.aws.amazon.com//AmazonS3/latest/userguide/Welcome.html)** – AFT creates Amazon Simple Storage Service (S3) buckets in the AFT management account and the AWS Control Tower log archive account, which store logs generated by the AWS services that the AFT pipeline requires. AFT also creates a Terraform backend S3 bucket, in primary and secondary AWS Regions, to store Terraform states generated during AFT pipeline workflows.
+ **[Amazon Simple Notification Service](https://docs.aws.amazon.com//sns/latest/dg/welcome.html)** – AFT creates Amazon Simple Notification Service (SNS) topics in the AFT management account, which stores success and failure notifications after processing every AFT account request. You may receive these messages using your choice of protocol.
+ **[Amazon Simple Queuing Service](https://docs.aws.amazon.com//AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html)** – AFT creates an Amazon Simple Queuing Service (Amazon SQS) FIFO queue in the AFT management account. The queue allows you to submit multiple account requests in parallel, but it sends one request at a time to AWS Control Tower Account Factory, for sequential processing.
+ **[AWS CodeBuild](https://docs.aws.amazon.com//codebuild/latest/userguide/welcome.html)** – AFT creates AWS CodeBuild build projects in the AFT management account to initialize, compile, test, and apply Terraform plans for AFT source code in various build stages.
+ **[AWS CodePipeline](https://docs.aws.amazon.com//codepipeline/latest/userguide/welcome.html)** – AFT creates AWS CodePipeline pipelines in the AFT management account to integrate with your selected, supported AWS CodeStar connections provider for AFT source code, and to trigger build jobs in AWS CodeBuild.
+ **[AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html)** – AFT creates AWS Lambda functions and layers in the AFT management account to perform steps during the account request, AFT account provisioning, and account customizations processes.
+ **[AWS Systems Manager Parameter Store](https://docs.aws.amazon.com//systems-manager/latest/userguide/systems-manager-parameter-store.html)** – AFT sets up the AWS Systems Manager Parameter Store in the AFT management account, to store the configuration parameters required for the AFT pipeline processes.
+ **[Amazon CloudWatch](https://docs.aws.amazon.com//AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html)** – AFT creates Amazon CloudWatch log groups in the AFT management account to store logs generated by AWS services employed by the AFT pipeline. The retention period for CloudWatch logs is set to `Never Expire`.
+ **[Amazon VPC](https://docs.aws.amazon.com//vpc/latest/userguide/what-is-amazon-vpc.html)** – AFT creates an Amazon Virtual Private Cloud (VPC) to isolate services and resources in the AFT management account into a separate networking environment, for enhanced security.
+ **[AWS KMS](https://docs.aws.amazon.com//kms/latest/developerguide/overview.html)** – AFT uses the AWS Key Management Service (KMS) in the AFT management account and in the AWS Control Tower log archive account. AFT creates keys to encrypt Terraform states, data stored in DynamoDB tables, and SNS topics. These logs and artifacts are generated when AWS resources and services are deployed by AFT. KMS keys created by AFT have yearly rotation enabled by default.
+ **[AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com//IAM/latest/UserGuide/introduction.html)** – AFT follows the recommended Least Privilege model. It creates AWS Identity and Access Management (IAM) roles and policies in the AFT management account, in AWS Control Tower accounts, and in AFT provisioned accounts, as needed, to perform actions required during the AFT pipeline workflow.
+ **[AWS Step Functions](https://docs.aws.amazon.com//step-functions/latest/dg/welcome.html)** – AFT creates AWS Step Functions state machines in the AFT management account. These state machines orchestrate and automate the process and steps for the AFT account provisioning framework and customizations.
+ **[Amazon EventBridge](https://docs.aws.amazon.com//eventbridge/latest/userguide/eb-what-is.html)** – AFT creates an Amazon EventBridge event bus in the AFT and AWS Control Tower management account to capture and store AWS Control Tower lifecycle events long-term in the AFT management account's DynamoDB table. AFT creates Amazon CloudWatch event rules in the AFT management and AWS Control Tower management accounts, which trigger multiple steps required during running of the AFT pipeline workflow
+ **[AWS CloudTrail (Optional)](https://docs.aws.amazon.com//awscloudtrail/latest/userguide/cloudtrail-user-guide.html)** – When this feature is enabled, AFT creates an AWS CloudTrail organization trail in the AWS Control Tower management account, for logging data events for Amazon S3 buckets and AWS Lambda functions. AFT sends these logs to a central S3 bucket in the AWS Control Tower log archive account.
+ **[AWS Support (Optional)](https://aws.amazon.com//premiumsupport/)** – When this feature is enabled, AFT turns on the AWS Enterprise Support plan for accounts provisioned by AFT. By default, AWS accounts are created with the AWS Basic Support plan enabled.

# AFT account provisioning pipeline
<a name="aft-provisioning-framework"></a>

After the account provisioning stage of the pipeline is complete, the AFT framework continues. It automatically runs a series of steps to ensure that the newly provisioned accounts have details in place, before the [Account customizations](aft-account-customization-options.md) stage begins.

**Here are the next steps that the AFT pipeline runs.**

1. Validates the account request input.

1. Retrieves information about the account provisioned, for example, the account ID.

1. Stores the account metadata in a DynamoDB table in the AFT management account.

1. Creates the **AWSAFTExecution** IAM role in the newly provisioned account. AFT assumes this role to perform the account customizations stage, because this role grants access to the account factory portfolio. 

1. Applies the account tags that you provided as part of the account request input parameters.

1. Applies the AFT feature options you chose at the time of AFT deployment.

1. Applies the AFT account provisioning customizations you provided. The next section tells more about how to set up these customizations with an AWS Step Functions state machine, in a `git` repository. This stage is sometimes referred to as the *account provisioning framework* stage. It is part of the core provisioning process, but you've previously set up a framework that delivers customized integrations as part of your account provisioning workflow, before additional customizations are added to the accounts in the next stage.

1. For each account provisioned, it creates an AWS CodePipeline in the AFT management account, which will run to perform the (next, global) [Account customizations](aft-account-customization-options.md) stage.

1. Invokes the account customizations pipeline for each account provisioned (and targeted).

1. Sends a success or failure notification to the SNS topic, from which you can retrieve the messages.

## Set up the account provisioning framework customizations with a state machine
<a name="aft-customizations"></a>

If you set up custom, non-Terraform integrations before you provision your accounts, these customizations are included in your AFT account provisioning workflow. For example, you may require certain customizations to ensure that all accounts created by AFT are compliant with the standards and policies of your organization, such as security standards, and these standards may be added to accounts before additional customization. These *account provisioning framework* customizations are implemented on every provisioned account, before the global account customization stage begins next.

**Note**  
The AFT feature described in this section is intended for advanced users who understand the functioning of AWS Step Functions. As an alternative, we recommend that you work with the global helpers in the account customizations stage.

The AFT account provisioning framework calls an AWS Step Functions state machine, which you define, to implement your customizations. Refer to the [AWS Step Functions documentation](https://docs.aws.amazon.com//step-functions/latest/dg/welcome.html) to learn more about the possible state machine integrations.

Here are some common integrations.
+ AWS Lambda functions in the language of your choice
+ AWS ECS or AWS Fargate tasks, using Docker containers
+ AWS Step Functions activities using custom workers, hosted either in AWS or on-premises
+ Amazon SNS or SQS integrations

If no AWS Step Functions state machine is defined, the stage passes with a no-op. To create an AFT account provisioning customizations state machine, follow the instructions in [Create your AFT account provisioning customizations state machine](#aft-create-customizations). Before you add customizations, be sure you have the prerequisites in place.

These types of integrations are not part of AWS Control Tower, and they cannot be added during the global pre-API stage of AFT account customization. Instead, the AFT pipeline allows you to set up these customizations as part of the provisioning process, and they are run in the provisioning workflow. You must implement these customizations by creating your state machine ahead of time, before you kick off the AFT account provisioning stage, as described in the following sections. 

**Prerequisites for creating a state machine**
+ A fully deployed AFT. See [Deploy AWS Control Tower Account Factory for Terraform (AFT)](aft-getting-started.md) for more information about AFT deployment.
+ Set up a `git` repository in your environment for AFT account provisioning customizations. See [Post-deployment steps](aft-post-deployment.md) for more information.

## Create your AFT account provisioning customizations state machine
<a name="aft-create-customizations"></a>

**Step 1: Modify the state machine definition**

Modify the example `customizations.asl.json` state machine definition. The example is available in the `git` repository you set up for storing AFT account provisioning customizations, in your [post-deployment steps](https://docs.aws.amazon.com//controltower/latest/userguide/aft-post-deployment.html). Refer to the [AWS Step Functions Developer Guide](https://docs.aws.amazon.com//step-functions/latest/dg/welcome.html) to learn more about state machine definitions.

**Step 2: Include the corresponding Terraform configuration**

Include Terraform files with the `.tf` extension in the same `git` repository with the state machine definition for your custom integration. For example, if you choose to call a Lambda function in your state machine task definition, you’d include the `lambda.tf` file in the same directory. Make sure you include the required IAM roles and permissions for your custom configurations.

When you provide the appropriate input, the AFT pipeline automatically invokes your state machine and deploys your customizations as part of the AFT account provisioning framework stage. 

## To re-start the AFT account provisioning framework and customizations
<a name="aft-provisioining-considerations"></a>

AFT runs the account provisioning framework and customizations steps for every account vended through the AFT pipeline. To re-start account provisioning customizations, you can use one of these two methods:

1. Make any change to an existing account in the account request repo.

1. Provision a new account with AFT.

# Account customizations
<a name="aft-account-customization-options"></a>

AFT can deploy standard or customized configurations in provisioned accounts. In the AFT management account, AFT provides one pipeline for each account. With this pipeline, you can implement your customizations in all accounts, in a set of accounts, or in individual accounts. You can run Python scripts, bash scripts, and Terraform configurations, or you can interact with the AWS CLI as part of your account customizations stage.

## Overview
<a name="aft-customizations-overview"></a>

After your customizations are specified in your chosen `git` repositories, either the one where you store your global customizations or where you store your account customizations, the account customizations stage is completed automatically by the AFT pipeline. To customize accounts retroactively, see [Re-invoke customizations](#aft-re-invoke-customizations).

**Global customizations (optional)**

You can choose to apply certain customizations to all accounts that are provisioned by AFT. For example, if you need to create a particular IAM role, or to deploy a custom control in every account, the global customizations stage in AFT pipeline allows you to do so, automatically.

**Account customizations (optional)**

To customize an individual account, or a set of accounts, differently than other AFT provisioned accounts, you can leverage the account customizations portion of the AFT pipeline to implement account-specific configurations. For example, only a certain account may require access to an internet gateway. 

## Customization prerequisites
<a name="aft-account-customization-prerequisites"></a>

Before you begin to customize accounts, be sure these prerequisites are in place.
+ A fully deployed AFT. For information about how to deploy, see [Configure and launch your AWS Control Tower Account Factory for Terraform](aft-getting-started.md#aft-configure-and-launch).
+ Pre-populated `git` repositories for global customizations and account customizations in your environment. See *Step 3: Populate each repository* in [Post-deployment steps](aft-post-deployment.md) for more information.

## Apply global customizations
<a name="aft-global-customizations"></a>

To apply global customizations, you must push a specific folder structure to your chosen repository.
+ If your custom configurations are in the form of Python programs or scripts, place those under **api\$1helpers/python** folder in your repository.
+ If your custom configurations are in the form of Bash scripts, place those under **api\$1helpers** folder in your repository.
+ If your custom configurations are in the form of Terraform, place those under the **terraform** folder in your repository.
+ Refer to the global customizations README file for more details on creating custom configurations.

**Note**  
Global customizations are applied automatically, after the AFT account provisioning framework stage in the AFT pipeline.

## Apply account customizations
<a name="aft-account-customizations"></a>

****

 You can apply account customizations by pushing a specific folder structure to your chosen repository. Account customizations are applied automatically in the AFT pipeline and after the global customizations stage. You can also create multiple folders that contain different account customizations in your account customizations repository. For each account customization that you require, use the following steps. 

**To apply account customizations**

1.  ** Step 1: Create a folder for an account customization ** 

    In your chosen repository, copy the `ACCOUNT_TEMPLATE` folder that AFT provides to a new folder. The name of your new folder should match the `account_customizations_name` that you provide in your account request. 

1.  ** Add the configurations to your specific account customizations folder ** 

    You can add configurations to your account customizations folder based on the format of your configurations. 
   +  If your custom configurations are in the form of Python programs or scripts, place them under the ***[account\$1customizations\$1name]*/api\$1helpers/python** folder that's in your repository. 
   +  If your custom configurations are in the form of Bash scripts, place them under the ***[account\$1customizations\$1name]*/api\$1helpers** folder that's in your repository. 
   +  If your custom configurations are in the form of Terraform, place them under the ***[account\$1customizations\$1name]*/terraform** folder that's in your repository. 

    For more information about creating custom configurations, refer to the account customizations README file. 

1.  ** Refer to the specific `account_customizations_name` parameter in the account request file ** 

    The AFT account request file includes the input parameter `account_customizations_name`. Enter the name of your account customization as the value for this parameter. 

**Note**  
 You can submit multiple account requests for accounts in your environment. When you want to apply different or similar account customizations, specifiy the account customizations using the `account_customizations_name` input parameter in your account requests. For more information, see [Submit multiple account requests](https://docs.aws.amazon.com/controltower/latest/userguide/aft-multiple-account-requests.html). 

## Re-invoke customizations
<a name="aft-re-invoke-customizations"></a>

AFT provides a way to re-invoke customizations in the AFT pipeline. This method is useful when you’ve added a new customization step, or when you are making changes to an existing customization. When you re-invoke, AFT initiates the customizations pipeline to make changes to the AFT provisioned account. An event-source-based re-invoke allows you to apply customizations to individual accounts, to all accounts, to accounts according to their OU, or to accounts selected according to tags.

Follow these three steps to re-invoke customizations for AFT-provisioned accounts.

**Step 1: Push changes to global or account customizations `git` repositories**

You can update your global and account customizations as needed and push changes back to your `git` repositories. At this point, nothing happens, The customizations pipeline must be invoked by an event source, as explained in the next two steps.

**Step 2: Start an AWS Step Function run for re-invoking customizations**

AFT provides an AWS Step Function called `aft-invoke-customizations` in the AFT management account. The purpose of that function is to re-invoke the customization pipeline for AFT-provisioned accounts.

Here is an example of an event schema (JSON format) you can create to pass input to the `aft-invoke-customizations` AWS Step Function.

```
{
  "include": [
    {
      "type": "all"
    },
    {
      "type": "ous",
      "target_value": [ "ou1","ou2"]
    },
    {
      "type": "tags",
      "target_value": [ {"key1": "value1"}, {"key2": "value2"}]
    },
    {
      "type": "accounts",
      "target_value": [ "acc1_ID","acc2_ID"]
    }
  ],

  "exclude": [
    {
      "type": "ous",
      "target_value": [ "ou1","ou2"]
    },
    {
      "type": "tags",
      "target_value": [ {"key1": "value1"}, {"key2": "value2"}]
    },
    {
      "type": "accounts",
      "target_value": [ "acc1_ID","acc2_ID"]
    }
  ]
}
```

 The example event schema shows that you can choose accounts to include or exclude from the re-invoke process. You can filter by organizational unit (OU), account tags, and account ID. If you don’t apply any filters and include the statement `"type":"all"`, the customization for all AFT-provisioned accounts is re-invoked. 

**Note**  
 If your version of AWS Control Tower Account Factory for Terraform (AFT) is 1.6.5 or later, you can target nested OUs with the syntax `OU Name (ou-id-1234`). For more information, see the following topic on [GitHub](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/issues/280). 

 After you fill out the event parameters, Step Functions runs and invokes the corresponding customizations. AFT can invoke a maximum of 5 customizations at a time. Step Functions waits and loops until all accounts matching the event criteria are complete. 

**Step 3: Monitor the AWS Step Function output and watch AWS CodePipeline running**
+ The resulting Step Function output contains account IDs that match the Step Function input event source.
+ Navigate to AWS CodePipeline under **Developer Tools** and view the corresponding customization pipelines for the account ID.

## Troubleshooting with AFT account customization request tracing
<a name="aft-customization-request"></a>

 Account customization workflows that are based on AWS Lambda emit logs containing target account and customization request IDs. AFT allows you to trace and troubleshoot customization requests with Amazon CloudWatch Logs by providing you with CloudWatch Logs Insights queries that you can use to filter CloudWatch Logs related to your customization request by your target account or customization request ID. For more information, see [Analyzing log data with Amazon CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html) in the *Amazon CloudWatch Logs User Guide*. 

**To use CloudWatch Logs Insights for AFT**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1.  From the navigation pane, choose **Logs**, and then choose **Logs insights**. 

1.  Choose **Queries**. 

1.  Under **Sample queries**, choose **Account Factory for Terraform**, and then select one of the following queries: 
   +  **Customization Logs by Account ID** 
**Note**  
 Make sure to replace *"YOUR-ACCOUNT-ID"* with your target account ID. 

     ```
     fields @timestamp, log_message.account_id as target_account_id, log_message.customization_request_id as customization_request_id, log_message.detail as detail, @logStream
     | sort @timestamp desc
     | filter log_message.account_id == "YOUR-ACCOUNT-ID" and @message like /customization_request_id/
     ```
   +  **Customization Logs by Customization Request ID** 
**Note**  
 Make sure to replace *"YOUR-CUSTOMIZATION-REQUEST-ID"* with your customization request ID. You can find your customization request ID in the output of the AFT account provisioning framework AWS Step Functions state machine. For more information about the AFT account provisioning framework, see [AFT account provisioning pipeline](https://docs.aws.amazon.com/controltower/latest/userguide/aft-provisioning-framework.html) 

     ```
     fields @timestamp, log_message.account_id as target_account_id, log_message.customization_request_id as customization_request_id, log_message.detail as detail, @logStream
     | sort @timestamp desc
     | filter log_message.customization_request_id == "YOUR-CUSTOMIZATION-REQUEST-ID"
     ```

1.  After you select a query, make sure to select a time interval, and then choose **Run query**. 

# Alternatives for version control of source code in AFT
<a name="aft-alternative-vcs"></a>

AFT uses AWS CodeCommit for a source code version control system (VCS), and it allows other [CodeConnections](https://docs.aws.amazon.com//dtconsole/latest/userguide/supported-versions-connections.html) that meet your business requirements or existing architecture.

If you're deploying AFT for the first time and you don't have an existing CodeCommit repository, you must specify an external VCS provider, as part of the AFT deployment prerequisites.

**AFT supports the following source code control alternatives:**
+ GitHub
+ GitHub Enterprise Server
+ BitBucket
+ GitLab
+ GitLab Self-managed

**Note**  
If you specify AWS CodeCommit as your VCS, no additional steps are required. AFT creates the necessary `git` repositories in your environment, with default names. However, you can override the default repository names for CodeCommit, as needed, to comply with your organizational standards.

## Set up an alternative source code version control system (custom VCS) with AFT
<a name="aft-alternate-vcs-steps"></a>

To set up an alternative source code version control system for your AFT deployment, follow these steps.

**Step 1: Create `git` repositories in a supported third-party version control system (VCS).**

If you are not using AWS CodeCommit, you must create `git` repositories in your AFT-supported, third-party VCS provider environment for the following items.
+ **AFT account requests.** [Sample code available](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-account-request) . For more information about AFT account requests, see [Provision a new account with AFT](aft-provision-account.md).
+ **AFT account provisioning customizations.** [Sample code available](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-account-provisioning-customizations) . For more information on AFT account provisioning customizations, see [Create your AFT account provisioning customizations state machine](aft-provisioning-framework.md#aft-create-customizations).
+ **AFT global customizations.** [Sample code available](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-global-customizations) . For more information on AFT global customizations, see [Account customizations](aft-account-customization-options.md).
+ **AFT account customizations.** [Sample code available](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-account-customizations) . For more information on AFT account customizations, see [Account customizations](aft-account-customization-options.md).

**Step 2: Specify the VCS configuration parameters required for AFT deployment**

The following input parameters are needed to configure your VCS provider as part of the AFT deployment.
+ **vcs\$1provider**: If you are not using AWS CodeCommit, specify the VCS provider as `"bitbucket"`, `"github"`, `"githubenterprise"`, or `"gitlab"`, based on your use case.
+ **github\$1enterprise\$1url**: For GitHub Enterprise customers only, specify the GitHub URL.
+ **account\$1request\$1repo\$1name**: For AWS CodeCommit users, this value is set to `aft-account-request`. In an AFT-supported, third-party VCS provider environment, update this input value with your actual repository name. For BitBucket, Github, GitHub Enterprise, GitLab, and GitLab Self-managed, the repository name must have the format `[Org]/[Repo]`.
+ **account\$1customizations\$1repo\$1name**: For AWS CodeCommit users, this value is set to `aft-account-customizations`. In an AFT-supported, third-party VCS provider environment, update this input value with your repository name. For BitBucket, Github, GitHub Enterprise, GitLab, and GitLab Self-managed, the repository name must have the format `[Org]/[Repo]`.
+ **account\$1provisioning\$1customizations\$1repo\$1name**: For AWS CodeCommit users, this value is set to `aft-account-provisioning-customizations`. In an AFT-supported, third-party VCS provider environment, update this input value with your repository name. For BitBucket, Github, GitHub Enterprise, GitLab, and GitLab Self-managed, the repository name must have the format `[Org]/[Repo]`.
+ **global\$1customizations\$1repo\$1name**: For AWS CodeCommit users, this value is set to `aft-global-customizations`. In an AFT-supported, third-party VCS provider environment, update this input value with your repository name. For BitBucket, Github, GitHub Enterprise, GitLab, and GitLab Self-managed, the repository name must have the format `[Org]/[Repo]`.
+ **account\$1request\$1repo\$1branch**: The branch is `main` by default, but the value can be overridden.

By default, AFT sources from the `main` branch of each `git` repository. You can override the branch name value with an additional input parameter. For more information about input parameters, refer to the README file in the [AFT Terraform module](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/blob/main/README.md#inputs).

**For existing AWS CodeCommit customers**  
 If you create a CodeCommit repository with a new name for AFT, you can update the repository name by updating the values for these input parameters.

**Step 3: Complete the AWS CodeCommit connection for third-party VCS providers**

When your deployment runs, AFT either creates the required AWS CodeCommit repositories, or it creates an AWS CodeCommit connection for your chosen third-party VCS provider. In case of the latter, you must manually sign in to the AFT management account’s console to complete the pending CodeCommit connection. See [the AWS CodeCommit documentation](https://docs.aws.amazon.com//dtconsole/latest/userguide/connections-update.html) for further instructions on completing the CodeCommit connection. 

# Move AFT from AWS CodeCommit to another VCS provider
<a name="move-a-vcs"></a>

This section provides an overview of how you can move AWS Control Tower Account Factory for Terraform (AFT) from AWS CodeCommit as your version control system (VCS) to another VCS provider.

**Step 1.** Set up new repositories in the VCS of your choice.

**Step 2.** Add these repositories as new remotes in `git`.

**Step 3.** Execute `git push` to the new VCS provider.

**Note**  
The repository structure that you create should be the same as in AWS CodeCommit. Changing the structure impedes the ability of AFT to execute the desired code.  
aft-account-request
 aft-account-customizations
 aft-global-customizations
aft-account-provisioning-customizations

**Step 4.** In your AWS Control Tower management account, update the Terraform module (bootstrap) to point to your VCS provider, as shown in the following example:

**Example: ** [GitLab with Terraform OSS](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/blob/main/examples/gitlab%2Btf_oss/main.tf)

– Perform `terraform plan` to preview changes, then `terraform apply`.

**Step 5.** Complete the steps to finish setting up the CodeConnection (formerly known as CodeStar): 

1. Sign in to your AFT management account

1. Locate and complete the pending AWS CodeConnections for the new VCS provider, as described in [Update a pending connection](https://docs.aws.amazon.com/dtconsole/latest/userguide/connections-update.html), or in the AWS console, [`https://us-east-1.console.aws.amazon.com/codesuite/settings/connections`].

1. Reference: [Post-deployment steps](https://docs.aws.amazon.com//controltower/latest/userguide/aft-post-deployment.html)

**Note**  
Account pipelines retain the previous source until `aft-invoke-customizations` *Step Functions* is invoked. This invocation can be done as part of the upgrade or as part of the next customizations invocations.

For more information, see this blog: [How to migrate your AWS CodeCommit repository to another Git provider](https://aws.amazon.com/blogs/devops/how-to-migrate-your-aws-codecommit-repository-to-another-git-provider).

# Data protection
<a name="aft-data-protection"></a>

The [AWS shared responsibility model](https://aws.amazon.com//compliance/shared-responsibility-model/) applies to data protection in AFT. For data protection purposes, we recommend the following best practices for security.
+ Follow the Data Protection guidelines provided by AWS Control Tower. For details, see [Data Protection in AWS Control Tower](controltower-console-encryption.md).
+ Preserve Terraform state configuration generated at the time of AFT deployment. For details, see [Deploy AWS Control Tower Account Factory for Terraform (AFT)](aft-getting-started.md).
+ Rotate sensitive credentials periodically as directed by your organization’s security policy. Examples of secrets are Terraform tokens, `git` tokens, and so forth.

 **Encryption at rest** 

AFT creates Amazon S3 buckets, Amazon SNS topics, Amazon SQS queues, and Amazon DynamoDB databases that are encrypted at rest with AWS Key Management Service keys. KMS keys created by AFT have yearly rotation enabled by default. If you choose the Terraform Cloud or Terraform Enterprise distributions of Terraform, AFT includes a AWS Systems Manager SecureString parameter to store Terraform token values that are sensitive.

AFT uses AWS services described in [Component services](aft-components.md) that are, by default, encrypted at rest. For details, see the AWS documentation for each component AWS service of AFT, and learn about the data protection practices followed by each service.

 **Encryption in transit** 

AFT relies upon AWS services described in [Component services](aft-components.md) that employ encryption in transit, by default. For details, see the AWS documentation for each component AWS service of AFT, and learn about the data protection practices followed by each service.

 For Terraform Cloud or Terraform Enterprise distributions, AFT calls an HTTPS endpoint API for access to your Terraform organization. If you choose a third-party VCS provider supported by AWS CodeStar connections, AFT calls an HTTPS endpoint API for access to your VCS provider organization.

# Remove an account from AFT
<a name="aft-remove-account"></a>

 This topic describes how to remove an account from AFT, so the AFT pipeline stops deploying and updating the account. 

**Important**  
 Removing an account from the AFT pipeline is irreversible and can result in a loss of state. 

 You might remove an account from AFT when you want to close an account for a retired application, isolate a compromised account, or move an account from one organization to another organization. 

**Note**  
 Removing an account from AFT is different than deleting an AWS Control Tower account or AWS account. When you remove an account from AFT, AWS Control Tower still manages the account. To delete an AWS Control Tower account or AWS account, see the following:   
 [Unmanage an account](https://docs.aws.amazon.com/controltower/latest/userguide/unmanage-account.html) in the *AWS Control Tower User Guide*. 
 [Closing an account](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/close-account.html) in the *AWS Billing User Guide*. 

**To remove an account from the AFT pipelines**

 The following procedure describes how to remove an account from AFT. 

1.  ** Remove account from `git` repository that stores account requests ** 

    In the `git` repository where you store account requests, delete the account request for the account you want to remove from AFT. 

    When you remove an account request from the account request repository, AFT deletes the customization pipeline and account metadata. For more information, see the [1.8.0 release notes](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/releases/tag/1.8.0) for AFT on GitHub. 

1.  ** Delete Terraform workspace (For Terraform Cloud and Terraform Enterprise customers only) ** 

    Delete the global customizations and account customizations workspaces for the account that you want to remove from AFT. 

1.  ** Delete Terraform state from Amazon S3 backend ** 

    In the AFT management account, delete all relevant folders inside of the Amazon S3 buckets for the account that you want to remove from AFT. 
**Tip**  
 In the following examples, replace `012345678901` with the AFT management account ID number. 

**Example: Terraform OSS**  
 When you choose Terraform OSS, you find 3 folders for each account in the `aft-backend-012345678901-primary-region` and `aft-backend-012345678901-secondary-region` Amazon S3 buckets. These folders are related to the *account customizations state*, *customizations pipeline state*, and *global customizations state* 

**Example: Terraform Cloud or Terraform Enterprise**  
 When you choose Terraform Cloud or Terraform Enterprise, you find a folder for each account in the `aft-backend-012345678901-primary-region` and `aft-backend-012345678901-secondary-region` Amazon S3 buckets. These folders are related to the *customizations pipeline state*. 

# Operational metrics
<a name="aft-operational-metrics"></a>

By default, *Account Factory for Terraform (AFT)* sends anonymous operational metrics to AWS. We use this data to understand how customers are using AFT so we can improve the quality and features of the solution. You can opt out of data collection by changing a parameter during AFT deployment. When collection is enabled, the following data is sent to AWS:
+ **Solution:** The AFT-specific identifier
+ **Version:** The version of AFT
+ **Universally Unique Identifier (UUID):** Randomly generated, unique identifier for each AFT deployment
+ **Timestamp:** Data-collection timestamp
+ **Data:** AFT configuration and actions taken by the customer

AWS owns the data collected. Data collection is subject to the [AWS Privacy Policy](https://aws.amazon.com/privacy/).

**Note**  
Versions of AFT prior to 1.6.0 do not report usage metrics to AWS.

To opt out of reporting metrics:
+ Set the input value of `aft_metrics_reporting` to `false` in your Terraform input configuration file, as shown in the example that follows, and redeploy AFT. This value is set to `true` by default, if you do not set it explicitly.

If you copy the example, remember to substitute your actual ID and Region values for the items given in strings with `x`.

```
    module "control_tower_account_factory" {
    source = "aws-ia/control_tower_account_factory/aws"
    
    # Required Vars
    ct_management_account_id    = "xxxxxxxxxxx"
    log_archive_account_id      = "xxxxxxxxxxx"
    audit_account_id            = "xxxxxxxxxxx"
    aft_management_account_id   = "xxxxxxxxxxx"
    ct_home_region              = "xx-xxxx-x"
    tf_backend_secondary_region = "xx-xxxx-x"
    
    # Optional Vars
    aft_metrics_reporting = false    # to opt out, set this value to false 
    }
```

# Account Factory for Terraform (AFT) troubleshooting guide
<a name="account-troubleshooting-guide"></a>

 This section can help you troubleshoot common issues that you might encounter when using Account Factory for Terraform (AFT). 

**Topics**
+ [General issues](#w2aac44c33c45b7)
+ [Issues related to account provisioning/registration](#w2aac44c33c45b9)
+ [Issues related to customizations invocation](#w2aac44c33c45c11)
+ [Issues related to the account customizations workflow](#w2aac44c33c45c13)

## General issues
<a name="w2aac44c33c45b7"></a>
+  **Exceeded AWS resource quotas** 

   If your log groups indicate that you exceeded AWS resource quotas, contact [AWS Support](https://aws.amazon.com/premiumsupport/). Account Factory uses AWS services with resource quotas that include AWS CodeBuild, AWS Organizations, and AWS Systems Manager. For more information, see the following: 
  +  [What is AWS CodeBuild?](https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html) in the *CodeBuild User Guide*. 
  +  [What is AWS Organizations?](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html) in the *Organizations User Guide*. 
  +  [What is AWS Systems Manager?](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html) in the *Systems Manager User Guide*. 
+  **Outdated version of Account Factory ** 

   If you encounter an issue and believe the issue is a bug, make sure that you have the latest version of Account Factory. For more information, see [Updating the Account Factory version](https://docs.aws.amazon.com/controltower/latest/userguide/update-aft-version.html). 
+  **Local changes were made to the Account Factory source code** 

   Account Factory is an open source project. AWS Control Tower supports the Account Factory core code. If you make a local change to the Account Factory core code, AWS Control Tower only supports your Account Factory deployment on a best-effort basis. 
+ ** Insufficient Account Factory role permissions ** 

   Account Factory creates IAM roles and policies to manage vended account deployments and customizations. If you change these roles or policies, the Account Factory pipeline may be unable to perform certain actions. For more information, see [Required roles](https://docs.aws.amazon.com/controltower/latest/userguide/aft-required-roles.html). 
+  **Account repositories not populated correctly ** 

   Make sure that you follow the [post-deployment steps](https://docs.aws.amazon.com/controltower/latest/userguide/aft-post-deployment.html) before provisioning accounts. 
+  **Not detecting drift after changing the OU manually** 
**Note**  
 AWS Control Tower detects drift automatically. For information about resolving drift, see [Detect and resolve drift in AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/drift.html#resolving-drift). 

   Drift isn't detected when the organizational unit (OU) is changed manually. This is due to the event-driven nature of Account Factory. When an account request is submitted, the resource that Terraform manages is an Amazon DynamoDB item, not a direct account. After an item is changed, the request is put in a queue, where AWS Control Tower processes them through Service Catalog (the service that manages account details). If you change the OU manually, drift isn't detected because the account request hasn't changed. 

## Issues related to account provisioning/registration
<a name="w2aac44c33c45b9"></a>
+  **Account request (email address/name) already exists** 

   The issue typically results in an Service Catalog product failure during provisioning or as `ConditionalCheckFailedException`. 

   You can find more information about the issue by doing one of the following: 
  +  Review your Terraform or CloudWatch Logs log groups. 
  +  Review the failures that are emitted to the Amazon SNS topic `aft-failure-notifications`. 
+  ** Malformed account request ** 

   Make sure that your account request follows the expected schema. For examples, see [terraform-aws-control\$1tower\$1account\$1factory](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/tree/main/sources/aft-customizations-repos/aft-account-request/examples) on GitHub. 
+  ** Exceeded AWS Organizations resource quotas** 

   Make sure that your account request doesn't exceed AWS Organizations resource quotas. For more information, see [Quotas for AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_reference_limits.html). 

## Issues related to customizations invocation
<a name="w2aac44c33c45c11"></a>
+  ** Target account not onboarded to Account Factory ** 

   Make sure all accounts that are included in a customization request have been onboarded to Account Factory. For more information, see [Update an existing account](https://docs.aws.amazon.com/controltower/latest/userguide/aft-update-account.html). 
+  **Account that customization request targets exists in the DynamoDB table `aft-request-metadata`, but not in account request repository ** 

   Format your customization invocation request to exclude the offending account by doing one of the following: 
  +  In the DynamoDB table `aft-request-metadata`, delete the entry referencing the account that's no longer in your account request repository. 
  +  Not using "all" as the target. 
  +  Not targeting the OU that the account belongs to. 
  +  Not targeting the account directly. 
+  ** Used incorrect token for Terraform Cloud ** 

   Make sure that you set up the correct token. Terraform Cloud only supports team-based tokens, not organization-based tokens. 
+  **Failed to create account before account customizations pipeline is created; can't customize account** 

   Make a change to the account specification in the account request repository. When you make a change, such as changing a tag value for an account, Account Factory follows the path that tries to create the pipeline, even if the pipeline doesn't exist. 

## Issues related to the account customizations workflow
<a name="w2aac44c33c45c13"></a>

 If you're experiencing issues related to the account customizations workflow, make sure that your version of AFT is 1.8.0 or higher, and that you delete all instances of account-related metadata from your DynamoDB request table. 

 For information about AFT version 1.8.0, see [Release 1.8.0](https://github.com/aws-ia/terraform-aws-control_tower_account_factory/releases/tag/1.8.0) on GitHub. 

 For information about how to check and update your version of AFT, see the following: 
+  [Check the AFT version](https://docs.aws.amazon.com/controltower/latest/userguide/check-aft-version.html) 
+  [Update the AFT version](https://docs.aws.amazon.com/controltower/latest/userguide/update-aft-version.html) 

 You can also trace and troubleshoot customization requests by using Amazon CloudWatch Logs Insights queries to filter logs containing your target account and customization request IDs. For more information, see [Troubleshooting with AFT account customization request tracing](https://docs.aws.amazon.com/controltower/latest/userguide/aft-account-customization-options.html). 