Skip to content

Sample solution that leverages AWS Control Tower Account Factory Terraform (AFT) to streamline the account closure and suspension process. The solution aims to provide a reliable, efficient, and fast way to manage the decommissioning of AWS accounts from organizations.

License

Notifications You must be signed in to change notification settings

aws-samples/aft-account-suspend-close-solution

Govern Multi Account Account Closure and Suspension using custom solutions for Account Factory for Terraform (AFT)

The primary goal of this APG is to introduce a solution that leverages AWS Control Tower Account Factory Terraform (AFT) to streamline the account closure and suspension process. The solution aims to provide a reliable, efficient, and fast way to manage the decommissioning of AWS accounts from organizations.

The APG will highlight the integration of account closure and suspension custom solution with AFT to automate the account decommissioning process, eliminating the need for manual interventions. This approach will enhance the overall operational efficiency and ensure a standardized, secure, and consistent decommissioning process for AWS Control Tower.

By automating the account decommissioning using AWS Lambda function, the solution addresses the crucial need for rapid and secure decommissioning of AWS accounts at scale, without compromising on security standards.

AFT (Account Factory for Terraform) Overview

As per documentation here, AFT sets up a Terraform pipeline that helps you provision and customize your accounts in AWS Control Tower. AFT follows a GitOps model to automate the processes of account provisioning in AWS Control Tower. You'll create an account request Terraform file, commit to repository, which provides the necessary input that triggers the AFT workflow for account provisioning. After account provisioning is complete, AFT can run additional customization steps, automatically.

Solution Architecture

acc close

The above architecture workflow digram illustrates both AWS Account creation as well as account closure workflow. This custom solution discussed here is for the account closure or suspension workflow because account closure and/or suspension is not part of standard AFT product. This custom solution enables that facility by creating an AWS Lambda Function which gets triggered by Amazon DynamoDB Streams to close an existing AWS account created/imported by AFT (Account Factory for Terraform) and then finally moves the closed account to a designated Suspended OU . Step by step solution workflow is as below -

The initial request to close an AWS Account can be initiated as soon as an account is fully created by AFT or imported by AFT.

The Operator initiates account closure request using AFT repository aft-account-request. This is the repository informs AFT about all the metadata Operator has provided for account creation and/or closure. The Account metadata in aft-request-metadata DynamoDB table. This table contains all the metadata operator has provided in the account-requests.tf table.

User pushes Terraform Code (Operator removes specific account module (module "account_request" {} from account-requests.tf) which then informs AFT to remove an AWS account from AFT management control and finally close and move the account to an designated Suspended OU to Git repository (for example GitHub, Amazon CodeCommit etc).

The above operation triggers AFT to record account removal request in the aft-request-audit DynamoDB table. This table has a DynamoDB stream (All AFT DynamoDB tables have streams enabled) already enabled which thereby triggers an AWS Lambda Function aft_suspend_account_ou.

This Lambda function aft_suspend_account_ou ( which resides in the AFT Management Account ) now fetches below account metadata from aft-request-audit using new images of DDB streams -

	     AccName = newImage['control_tower_parameters']['M']['AccountName']['S']    # Account Name (required)
		AccEmail = newImage['control_tower_parameters']['M']['AccountEmail']['S']  # Account Email (required)
		SSOEmail = newImage['control_tower_parameters']['M']['SSOUserEmail']['S']  # SSO registration Email (optional)
		SSOFirstName = newImage['control_tower_parameters']['M']['SSOUserFirstName']['S'] # SSO registration First Name (optional)
		SSOLastName = newImage['control_tower_parameters']['M']['SSOUserLastName']['S']  # SSO registration Last Name (optional)
		DDEvent = newImage['ddb_event_name']['S'] # DDB Event Name (required)
		SourceOU = newImage['control_tower_parameters']['M']['ManagedOrganizationalUnit']['S']	# Parent OU information (required)

If Lambda function finds the value as REMOVE for the DDEvent parameter value, it fetches the relevant Account ID by using the email value from the aft-request-metadata DynamoDB table and matching with AccEmail parameter fetched from the aft-account-request to confirm the Account to be closed/suspended.

At this stage Lambda Function knows the right combination of Account ID and the ParentOU under which the Account is placed.

The Lambda Function now performs cross-account jump from AFT Management Account to the AWS Control Tower Account to perform AWS Organisation BOTO3 Calls to close the Account first and then finally move the account to a designation Suspended OU.

Requirements

Name Version
terraform >= 0.15.0
aws >= 3.15

Providers

Name Version
archive n/a
aws >= 3.15

Modules

No modules.

Resources

Name Type
aws_cloudwatch_log_group.aft_suspend_account_ou_lambda_log resource
aws_iam_policy.lambda_assume_acc_close_policy resource
aws_iam_role.iam_for_account_suspend_lambda resource
aws_iam_role_policy.dynamodb_lambda_policy resource
aws_iam_role_policy_attachment.assume_policy_attach_acc_close resource
aws_kms_alias.aft_kms_alias resource
aws_kms_key.aft_kms_key resource
aws_lambda_code_signing_config.this resource
aws_lambda_event_source_mapping.lambda_dynamodb resource
aws_lambda_function.aft_suspend_account_ou_lambda resource
aws_signer_signing_profile.this resource
aws_sqs_queue.aftlambdadlq resource
archive_file.aft_suspend_account data source
aws_arn.aft_to_ct_cross_account_role_arn data source
aws_caller_identity.aft_management_id data source
aws_iam_policy.AmazonSQSFullAccess data source
aws_iam_policy.CloudWatchFullAccess data source
aws_iam_policy_document.assume_role_policy data source
aws_iam_policy_document.dynamodb_lambda_policy data source
aws_iam_policy_document.key_initial data source
aws_iam_policy_document.lambda_assume_acc_close_policy data source
aws_region.aft_management_region data source

Inputs

Name Description Type Default Required
aft-request-audit-table-encrption-key-id DynamoDB table aft-request-audit table stream ARN string "" no
aft-request-audit-table-stream-arn DynamoDB table aft-request-audit table stream ARN string "" no
aft_to_ct_cross_account_role_name AFT Cross Account Role string "AFTCrossAccountRole" no
cloudwatch_log_group_retention Lambda CloudWatch log group retention period string "0" no
ct_account_id AFT Account ID string "" no
ct_destination_ou Destination OU into which Account will be moved string "" no
ct_root_ou_id CT Account Root OU ID string "" no
default_tags Default tags for the module map(string)
{
"CostCenter": "ACME",
"Environment": "AFT",
"Owner": "ACME Corp",
"Project": "ACME Project"
}
no
private1_subnet_id Private Subnet 1 string "" no
private2_subnet_id Private Subnet 2 string "" no
private_sg_id Private Subnet Security Group string "" no
region Default Region string "us-west-2" no

Outputs

Name Description
aft_alternate_sso_extract_lambda_arn aft-alternate-sso-extract Lambda ARN

About

Sample solution that leverages AWS Control Tower Account Factory Terraform (AFT) to streamline the account closure and suspension process. The solution aims to provide a reliable, efficient, and fast way to manage the decommissioning of AWS accounts from organizations.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published