Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md

AWS Control Tower Account Factory for Terraform

AWS Control Tower Account Factory for Terraform (AFT) follows a GitOps model to automate the processes of account provisioning and account updating in AWS Control Tower. You'll create an account request Terraform file, which provides the necessary input that triggers the AFT workflow for account provisioning.

For more information on AFT, see Overview of AWS Control Tower Account Factory for Terraform

Getting started

This guide is intended for administrators of AWS Control Tower environments who wish to set up Account Factory for Terraform (AFT) in their environment. It describes how to set up an Account Factory for Terraform (AFT) environment with a new, dedicated AFT management account. This guide follows the deployment steps outlined in Deploy AWS Control Tower Account Factory for Terraform (AFT)

Configure and launch your AWS Control Tower Account Factory for Terraform

Five steps are required to configure and launch your AFT environment.

Step 1: Launch your AWS Control Tower landing zone

Before launching AFT, you must have a working AWS Control Tower landing zone in your AWS account. You will configure and launch AFT from the AWS Control Tower management account.

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

We recommend that you create a separate OU in your AWS Organization, where you will deploy the AFT management account. Create an OU through your AWS Control Tower management account. For instructions on how to create an OU, refer to Create an organization in the AWS Organizations User Guide.

Step 3: Provision the AFT management account

AFT requires a separate AWS account to manage and orchestrate its own requests. From the AWS Control Tower management account that's associated with your AWS Control Tower landing zone, you'll provision this account for AFT.

To provision the AFT management account, see Provisioning Account Factory Accounts With AWS Service Catalog. When specifying an OU, be sure to select the OU you created in Step 2. When specifying a name, use "AFT-Management".

Note: It can take up to 30 minutes for the account to be fully provisioned. Validate that you have access to the AFT management account.

Step 4: Ensure that the Terraform environment is available for deployment

This step assumes that you are experienced with Terraform, and that you have procedures in place for executing Terraform. AFT supports Terraform Version 0.15.x or later.

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

The Account Factory for Terraform module must be called while you are authenticated with AdministratorAccess credentials in your AWS Control Tower management account.

AWS Control Tower, through the AWS Control Tower management account, vends a Terraform module that establishes all infrastructure necessary to orchestrate your AWS Control Tower account factory requests. You can view that module in the AFT repository.

Refer to the module’s README file for information about the input required to run the module and deploy AFT.

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

Note: The AFT Terraform module does not manage a backend Terraform state. Be sure to preserve the Terraform state file that’s generated, after applying the module, or set up a Terraform backend using Amazon S3 and DynamoDB.

Certain input variables may contain sensitive values, such as a private ssh key or Terraform token. These values may be viewable as plain text in Terraform state file, depending on your deployment method. It is your responsibility to protect the Terraform state file, which may contain sensitive data. See the Terraform documentation

for more information.

Note: Deploying AFT through the Terraform module requires several minutes. Initial deployment may require up to 30 minutes. As a best practice, use AWS Security Token Service (STS) credentials and ensure that the credentials have a timeout sufficient for a full deployment, because a timeout causes the deployment to fail. The minimum timeout for AWS STS credentials is 60 minutes or more. Alternatively, you can leverage any IAM user that has AdministratorAccess permissions in the AWS Control Tower management account.

Next Steps:

Now that you have configured and deployed AWS Control Tower Account Factory for Terraform, follow the steps outlined in Post-deployment steps and Provision accounts with AWS Control Tower Account Factory for Terraform to begin using your environment.

Collection of Operational Metrics

As of version 1.6.0, AFT collects anonymous operational metrics to help AWS improve the quality and features of the solution. For more information, including how to disable this capability, please see the documentation here.

Security Considerations

HCP Terraform / Terraform Enterprise OIDC Workspace Governance

When you enable the HCP Terraform or Terraform Enterprise OIDC integration (terraform_oidc_integration = true), AFT configures the AWSAFTAdmin IAM role with a trust policy that allows any workspace within your configured TFC/TFE organization and project to assume the role via OIDC. The trust policy uses a sub claim condition scoped to your organization, project, and audience, but uses a wildcard (workspace:*) for the workspace name.

Existing mitigations:

  • The trust policy is scoped to your specific TFC/TFE organization, project, and audience — only workspaces within the configured project can obtain credentials.
  • The AWSAFTAdmin role is limited to sts:AssumeRole permissions only (to assume AWSAFTExecution and AWSAFTService roles). It has no direct permissions to access or modify AWS resources.

Customer responsibility:

Important: Workspace governance within your configured TFC/TFE project is your responsibility. Any workspace created within the project specified by terraform_project_name can assume the AWSAFTAdmin role via OIDC. You should take the following steps to secure your environment:

  • Restrict workspace creation: Limit who can create new workspaces within the TFC/TFE project used by AFT. Use TFC/TFE team permissions to control workspace management access.
  • Audit workspace access: Regularly review the workspaces in your AFT project to ensure only authorized workspaces exist.
  • Use a dedicated project: Use a dedicated TFC/TFE project exclusively for AFT workspaces. Avoid sharing the project with unrelated workspaces.
  • Consider workspace-specific scoping (optional): For additional security, after deployment you can manually modify the AWSAFTAdmin trust policy to replace the workspace:* wildcard with explicit workspace names (e.g., workspace:my-aft-workspace). Note that this customization must be maintained outside of AFT and re-applied after AFT updates.

Known Limitations

Customization Triggers Concurrency

When aft_customization_triggers is configured with ["account_move"], customization re-executions triggered by account moves bypass the maximum_concurrent_customizations throttle. Each account move generates a separate Control Tower event that invokes the provisioning framework independently. Moving many accounts between OUs simultaneously (e.g., a bulk reorganization) may result in concurrent customization executions exceeding the configured maximum. For environments where bulk account moves are expected, consider staggering the moves or implementing EventBridge-layer throttling.

Customization Triggers Supported Event Paths

Customization triggers are detected from AWS Control Tower UpdateManagedAccount events only. When an account is moved to a different OU through Account Factory, the account_move trigger fires. This includes AFT-mediated moves, where you change the ManagedOrganizationalUnit value in an account request file.

The following paths do not emit an UpdateManagedAccount event and therefore do not trigger customization re-execution:

  • Moving an account directly in AWS Organizations (outside Account Factory). This also places the account out of sync with Control Tower governance until it is re-enrolled.
  • Enrolling an existing account via Auto Enroll (registering an OU that contains existing accounts). Enrollment is not an account move; accounts onboarded this way receive customizations through the normal AFT account request flow, not through account_move.

If an account reaches its target OU through one of these paths, re-run customizations manually via the aft-invoke-customizations Step Function.

Requirements

NameVersion
terraform>= 1.6.1, < 2.0.0
aws>= 6.0.0, < 7.0.0

Providers

NameVersion
aws>= 6.0.0, < 7.0.0
localn/a

Modules

NameSourceVersion
aft_account_provisioning_framework./modules/aft-account-provisioning-frameworkn/a
aft_account_request_framework./modules/aft-account-request-frameworkn/a
aft_backend./modules/aft-backendn/a
aft_code_repositories./modules/aft-code-repositoriesn/a
aft_customizations./modules/aft-customizationsn/a
aft_feature_options./modules/aft-feature-optionsn/a
aft_iam_roles./modules/aft-iam-rolesn/a
aft_lambda_layer./modules/aft-lambda-layern/a
aft_ssm_parameters./modules/aft-ssm-parametersn/a
packaging./modules/aft-archivesn/a

Resources

NameType
aws_partition.currentdata source
aws_service.home_region_validationdata source
local_file.python_versiondata source
local_file.versiondata source

Inputs

NameDescriptionTypeDefaultRequired
account_customizations_repo_branchBranch to source account customizations repo fromstring"main"no
account_customizations_repo_nameRepository name for the account customizations files. For non-CodeCommit repos, name should be in the format of Org/Repostring"aft-account-customizations"no
account_provisioning_customizations_repo_branchBranch to source account provisioning customization filesstring"main"no
account_provisioning_customizations_repo_nameRepository name for the account provisioning customizations files. For non-CodeCommit repos, name should be in the format of Org/Repostring"aft-account-provisioning-customizations"no
account_provisioning_customizations_workspace_nameWorkspace name to use for the account provisioning customizations operation in Terraform Cloud or Enterprise. Note: changing this value for an existing deployment creates a new workspace and orphans the old one - it is not an in-place rename.string"ct-aft-account-provisioning-customizations"no
account_request_repo_branchBranch to source account request repo fromstring"main"no
account_request_repo_nameRepository name for the account request files. For non-CodeCommit repos, name should be in the format of Org/Repostring"aft-account-request"no
account_request_workspace_nameWorkspace name to use for the account request operation in Terraform Cloud or Enterprise. Note: changing this value for an existing deployment creates a new workspace and orphans the old one - it is not an in-place rename.string"ct-aft-account-request"no
aft_backend_bucket_access_logs_object_expiration_daysAmount of days to keep the objects stored in the access logs bucket for AFT backend bucketsnumber365no
aft_codebuild_compute_typeThe CodeBuild compute type that build projects will use.string"BUILD_GENERAL1_MEDIUM"no
aft_customer_private_subnetsA list of private subnets to deploy AFT resources in, if customer is providing an existing VPC. Only supported for new deployments.list(string)[]no
aft_customer_vpc_idThe VPC ID to deploy AFT resources in, if customer is providing an existing VPC. Only supported for new deployments.stringnullno
aft_customization_triggersList of customization trigger tokens. When non-empty, matching events trigger customization re-execution with provisioning bypass. Valid tokens: account_move. Per-account opt-out via account_skip_customization_triggers attribute in aft-request.list(string)[]no
aft_enable_vpcFlag turning use of VPC on/off for AFTbooltrueno
aft_feature_cloudtrail_data_eventsFeature flag toggling CloudTrail data events on/offboolfalseno
aft_feature_delete_default_vpcs_enabledFeature flag toggling deletion of default VPCs on/offboolfalseno
aft_feature_enterprise_supportFeature flag toggling Enterprise Support enrollment on/offboolfalseno
aft_framework_repo_git_refGit branch from which the AFT framework should be sourced fromstringnullno
aft_framework_repo_urlGit repo URL where the AFT framework should be sourced fromstring"https://github.com/aws-ia/terraform-aws-control_tower_account_factory.git"no
aft_management_account_idAFT Management Account IDstringn/ayes
aft_metrics_reportingFlag toggling reporting of operational metricsbooltrueno
aft_vpc_cidrCIDR Block to allocate to the AFT VPCstring"192.168.0.0/22"no
aft_vpc_endpointsFlag turning VPC endpoints on/off for AFT VPCbooltrueno
aft_vpc_private_subnet_01_cidrCIDR Block to allocate to the Private Subnet 01string"192.168.0.0/24"no
aft_vpc_private_subnet_02_cidrCIDR Block to allocate to the Private Subnet 02string"192.168.1.0/24"no
aft_vpc_public_subnet_01_cidrCIDR Block to allocate to the Public Subnet 01string"192.168.2.0/25"no
aft_vpc_public_subnet_02_cidrCIDR Block to allocate to the Public Subnet 02string"192.168.2.128/25"no
audit_account_idAudit Account Idstringn/ayes
backup_recovery_point_retentionNumber of days to keep backup recovery points in AFT DynamoDB tables. Default = Never Expirenumbernullno
backup_scheduleCron expression for the DynamoDB backup schedule. Default = hourlystring"cron(0 * * * ? *)"no
cloudwatch_log_group_enable_cmk_encryptionFlag toggling CloudWatch Log Groups encryption by using the AFT customer managed key stored in KMS. Additional charges apply. Otherwise, logs will use CloudWatch managed server-side encryption.boolfalseno
cloudwatch_log_group_retentionAmount of days to keep CloudWatch Log Groups for Lambda functions. 0 = Never Expirestring"0"no
concurrent_account_factory_actionsMaximum number of accounts that can be provisioned in parallel.number5no
ct_home_regionThe region from which this module will be executed. This MUST be the same region as Control Tower is deployed.stringn/ayes
ct_management_account_idControl Tower Management Account Idstringn/ayes
github_enterprise_urlGitHub enterprise URL, if GitHub Enterprise is being usedstring"null"no
gitlab_selfmanaged_urlGitLab SelfManaged URL, if GitLab SelfManaged is being usedstring"null"no
global_codebuild_timeoutCodebuild build timeoutnumber60no
global_customizations_repo_branchBranch to source global customizations repo fromstring"main"no
global_customizations_repo_nameRepository name for the global customization files. For non-CodeCommit repos, name should be in the format of Org/Repostring"aft-global-customizations"no
log_archive_account_idLog Archive Account Idstringn/ayes
log_archive_bucket_object_expiration_daysAmount of days to keep the objects stored in the AFT logging bucketnumber365no
maximum_concurrent_customizationsMaximum number of customizations/pipelines to run at oncenumber5no
sfn_s3_bucket_object_expiration_daysAmount of days to keep the objects stored in the CodePipeline bucket for AFT Step Functionsnumber90no
sns_topic_enable_cmk_encryptionFlag toggling SNS topics encryption by using the AFT Customer managed key stored in KMS. Additional charges apply. Otherwise the SNS topics are encrypted using the AWS-managed KMS key.boolfalseno
tagsMap of tags to apply to resources deployed by AFT.map(any)nullno
terraform_api_endpointAPI Endpoint for Terraform. Must be in the format of https://xxx.xxx.string"https://app.terraform.io/api/v2/"no
terraform_distributionTerraform distribution being used for AFT - valid values are oss, tfc, or tfestring"oss"no
terraform_oidc_aws_audienceThe audience value to use in run identity tokens for HCP dynamic credentials (OIDC). var.aft_feature_hcp_oidc must be set to true to enable OIDC.string"aws.workload.identity"no
terraform_oidc_hostnameThe hostname of the TFC or TFE instance to use with AWS when configuring dynamic credentials (OIDC). var.aft_feature_hcp_oidc must be set to true to enable OIDC.string"app.terraform.io"no
terraform_oidc_integrationEnable HCP Terraform’s native OpenID Connect integration with AWS to get dynamic credentials for the AWS provider in your HCP Terraform runsboolfalseno
terraform_org_nameOrganization name for Terraform Cloud or Enterprisestring"null"no
terraform_project_nameProject name for Terraform Cloud or Enterprise - project must exist before deploymentstring"Default Project"no
terraform_tokenTerraform token for Cloud or Enterprisestring"null"no
terraform_versionTerraform version being used for AFTstring"1.6.1"no
tf_backend_secondary_regionAFT creates a backend for state tracking for its own state as well as OSS cases. The backend's primary region is the same as the AFT region, but this defines the secondary region to replicate to.string""no
vcs_providerCustomer VCS Provider - valid inputs are codecommit, bitbucket, github, githubenterprise, gitlab, or gitLab self-managedstring"codecommit"no

Outputs

NameDescription
account_customizations_repo_branchn/a
account_customizations_repo_namen/a
account_provisioning_customizations_repo_branchn/a
account_provisioning_customizations_repo_namen/a
account_request_repo_branchn/a
account_request_repo_namen/a
aft_access_logs_primary_backend_bucket_idn/a
aft_account_provisioning_framework_step_function_arnn/a
aft_admin_role_arnn/a
aft_audit_exec_role_arnn/a
aft_backend_lock_table_namen/a
aft_backend_primary_kms_key_alias_arnn/a
aft_backend_primary_kms_key_idn/a
aft_backend_secondary_kms_key_alias_arnn/a
aft_backend_secondary_kms_key_idn/a
aft_controltower_events_table_namen/a
aft_ct_management_exec_role_arnn/a
aft_customization_triggersn/a
aft_exec_role_arnn/a
aft_failure_sns_topic_arnn/a
aft_feature_cloudtrail_data_eventsn/a
aft_feature_delete_default_vpcs_enabledn/a
aft_feature_enterprise_supportn/a
aft_features_step_function_arnn/a
aft_invoke_customizations_step_function_arnn/a
aft_kms_key_alias_arnn/a
aft_kms_key_idn/a
aft_log_archive_exec_role_arnn/a
aft_management_account_idn/a
aft_primary_backend_bucket_idn/a
aft_request_audit_table_namen/a
aft_request_metadata_table_namen/a
aft_request_table_namen/a
aft_secondary_backend_bucket_idn/a
aft_sns_topic_arnn/a
aft_vpc_cidrn/a
aft_vpc_private_subnet_01_cidrn/a
aft_vpc_private_subnet_02_cidrn/a
aft_vpc_public_subnet_01_cidrn/a
aft_vpc_public_subnet_02_cidrn/a
audit_account_idn/a
backup_recovery_point_retentionn/a
cloudwatch_log_group_retentionn/a
ct_home_regionn/a
ct_management_account_idn/a
github_enterprise_urln/a
gitlab_selfmanaged_urln/a
global_customizations_repo_branchn/a
global_customizations_repo_namen/a
log_archive_account_idn/a
maximum_concurrent_customizationsn/a
terraform_api_endpointn/a
terraform_distributionn/a
terraform_org_namen/a
terraform_versionn/a
tf_backend_secondary_regionn/a
vcs_providern/a

关于 About

AWS Control Tower Account Factory
control-tower-service-team-ownedrepo-does-not-accept-pull-requests

语言 Languages

HCL50.4%
Python35.8%
Smarty12.1%
Shell0.9%
Jinja0.7%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
11
Total Commits
峰值: 2次/周
Less
More

核心贡献者 Contributors