AWS Cloud Operations & Migrations Blog

Migrate AWS Landing Zone solution to AWS Control Tower

Customers who wanted to quickly set up a secure, compliant, multi-account AWS environment had adopted AWS Landing Zone solution (ALZ). To reduce the burden of managing this ALZ, AWS has announced a managed service – AWS Control Tower (Control Tower).

AWS Control Tower creates your landing zone using AWS Organizations, thereby bringing together ongoing account management and governance, as well as implementation of best practices based on our experience of working with thousands of customers as they migrate to the cloud. AWS CT lets builders provision new AWS accounts in just a few clicks, while you have peace of mind knowing that your accounts conform to company-wide policies. AWS customers can implement AWS CT, extend governance into new or existing accounts, and quickly gain visibility into their compliance status.

ALZ is currently in long term support and will not receive any additional features. Therefore, it is recommended to migrate to the AWS Control Tower service from ALZ. In this post, we will go through different considerations for that migration and explain how you can plan a successful migration from ALZ to AWS CT.

Prerequisites and considerations:

  • New email addresses which have never been used in AWS Accounts:
    • 1 for Log Archive account
    • 1 for Audit/Security account
  • If you are using AWS SSO, then it must be in the same region where you are planning to deploy AWS CT.
  • The AWS management account can’t have trusted access enabled in the AWS Organization management account for either AWS Config or AWS CloudTrail. For information regarding how to disable trusted access, see the AWS Organizations documentation on how to enable or disable trusted access.
  • ALZ sets up Config recorder, delivery channel in member accounts, and you must remove these installations so that AWS CT can configure AWS Config on your behalf during landing zone setup.

Migration Process:

Step 1: Deploy AWS Control Tower

Before Control Tower sets up the landing zone (A landing zone is a well-architected, multi-account environment that’s based on security and compliance best practices), it automatically runs a series of pre-launch checks in your account that are mentioned here.

If AWS Single Sign-On (AWS SSO) is already enabled, then the AWS Control Tower must be deployed in the same region as AWS SSO. Control Tower will not delete an existing SSO configuration. If another directory (External Identity Provider, AWS SSO User Store, Active Directory) is set up, then Control Tower will not change the existing configuration. For more details, see Considerations for AWS Single Sign-On (AWS SSO) customers.

After making sure that you are in the same AWS region as AWS SSO, you can deploy AWS Control Tower in an existing AWS Organization as outlined in the AWS Control Tower User Guide, found at Getting Started, Step 2.

Step 2: Service Control Policies (SCP)

Control Tower comes out of the box with specific preventive guardrails to protect the Control Tower landing zone resources. Those mandatory guardrails will be applied on every organizational unit (OU) that will be registered by Control Tower.

External SCPs that are applied on the OU through AWS Organizations will co-exist along with Control Tower. However, you can’t see them or control them from the guardrails list as of today.

As there is a limit for SCPs in terms of size and number (maximum five policies per OU or account) of policies, Control Tower aggregate multiple SCPs in a single policy to be applied on the OU. Exceeding the maximum number of SCPs is not desired. Therefore, you must merge the policies to attach them to the OUs or accounts.

You must make sure that Control Tower roles has the rights to access and perform expected operations on the accounts and OUs. If you have applied very restrictive SCPs that might prevent Control Tower actions then we recommend removing it or excluding the AWS Control Tower roles from these SCP.

Step 3: AWS Config

ALZ enables AWS Config in every member account, which creates a config recorder and delivery channel in regions specified in the manifest.

There are two ways to handle your existing AWS Config deployment and you can opt to one of these options:

  1. Delete AWS Config from existing accounts: Identify the member accounts that you want to enroll into Control Tower and delete the configuration-recorder and delivery channel from every Control Tower supported region. To delete Config from existing accounts, go to your the management account and navigate to AWS CloudFormation StackSets in the CloudFormation console and delete the stack instances of AWS-Landing-Zone-Baseline-EnableConfig StackSet.

Note that EnableConfig StackSet deletion will stop resource change recording until the member account is enrolled into Control Tower. To minimize this time, plan this activity when there are fewer changes. Furthermore, try to enroll the account in Control Tower as soon as the prerequisites are met for the account.

Here are some example AWS Config CLI commands that you can use to determine the status of your configuration recorder and delivery channel. Replace the <aws-region> with the region you are working on. Run the following commands for every AWS member account and region where you have the deployed ALZ resources.

  • View commands (Optional):
aws configservice describe-delivery-channels --region <aws-region>
aws configservice describe-delivery-channel-status --region <aws-region>
aws configservice describe-configuration-recorders --region <aws-region>

If you have AWS Config enabled in an AWS region that is currently unsupported by Control Tower, then enable Config there later once the account is enrolled in Control Tower. You can use the methodology mentioned in this blog to extend Config Conformance Packs to newly enrolled accounts in Control Tower.

  1. Modify Config settings: Due to compliance requirements, if you don’t want to delete your existing Config deployment, then follow the steps outlined here to enroll AWS accounts in Control Tower that have existing AWS Config resources.

Note that Config is enabled using AWS-Landing-Zone-Baseline-EnableConfig CloudFormation StackSet, and the Config IAM role is deployed with the AWS-Landing-Zone-Baseline-ConfigRole StackSet. Therefore, to modify Config in every account, you must modify both the CloudFormation templates (aws-landing-zone-enable-config.template & aws-landing-zone-enable-config-role.template) as per the change in Config resources outlined in the documentation referred here and then update the StackSet. For the Config aggregation authorization (Step# 5c- from previous link), you will also need to run the AWS CLI command as outlined in that step.

Please follow method #2 only in case you don’t want to stop Config recording, otherwise it’s better to adopt method #1 that deletes the existing Config StackSet and let Control Tower deploy it again for you.

Step 4: Enrolling accounts and OUs

There are two ways to register accounts and OU to become managed by Control Tower. This is done either by relying on the native functionality from Control Tower to register an OU with every account under that OU, or by enrolling account by account.

In general if you are using the standard Account Vending Machine (AVM) and there are no customizations to it, then we recommend using the Register OU process described below.

In this section, we will explain both mechanisms and when to use each one.

  1. Register OU:

This is the efficient way to extend the governance of multiple existing accounts within an OU under Control Tower. When you register an OU, its member accounts are enrolled into the Control Tower landing zone.

The two considerations to ensure with this mechanism are:

  • If you have nested OUs, then you need to register the parent OU first and the child next as per the hierarchy.
  • The OU should not exceed 300 accounts.

For more information on how to proceed with registering OUs from the Control Tower console, review the documentation.

When registering an OU, note that it takes time to register each account. Therefore, we recommend scheduling a maintenance window for registering OUs even if that doesn’t affect the running workload within the account.

Currently, there are two limitations you should be aware of while OU registration is in progress:

  • It’s not possible to create a new account via Account factory.
  • Creation or registration of another OU is not possible.
  1. Enroll account by account:

Control Tower leverages AWS Service Catalog for account creation by using the “AWS Control Tower Account Factory” which is a Service Catalog Product.

⚠️If you have customized the AVM CloudFormation template for creating accounts (For example chaining within same service catalog product or customization related directly within account vending resource), then you might want to keep the existing AWS Service Catalog Product as well as the Provisioned product. You must update the section that trigger account provisioning with a new one for Control Tower Account Factory for example:

AccountVending:
    Type: AWS::ServiceCatalog::CloudFormationProvisionedProduct
    Properties:
      ProductName: "AWS Control Tower Account Factory"
      ProvisionedProductName: !Ref AccountName
      ProvisioningArtifactName: "AWS Control Tower Account Factory"
      ProvisioningParameters: 
        - Key: SSOUserEmail
          Value: !Ref SSOUserEmail
        - Key: AccountEmail
          Value: !Ref AccountEmail
        - Key: SSOUserFirstName
          Value: !Ref SSOUserFirstName
        - Key: SSOUserLastName
          Value: !Ref SSOUserLastName
        - Key: ManagedOrganizationalUnit
          Value: !Ref ManagedOrganizationalUnit
        - Key: AccountName
          Value: !Ref AccountName

The two caveats to consider for this mechanism are:

  • Don’t update or change the Control Tower Service Catalog Portfolio or Product. These are managed by Control Tower and they will be reverted back to their original configuration.
  • Currently account enrollment or creation is single threaded (one account enrollment per time).

Step 5: Security, Shared Services, and log-archive accounts

Security Account:
Control Tower creates new member accounts called Audit/Security accounts that provide functionality similar to the Security account in an ALZ. You can’t retain or select an existing ALZ Security account when deploying Control Tower. If you have deployed any additional services, such as GuardDuty, Security Hub, and/or any third-party installations in the Security account then consider migrating them to the new Control Tower Audit account. Also, if you have configured any paging or alerting system for security notifications from a Amazon Simple Notification Service (SNS) topic in the Security account, then move that to the Audit account as well.

Log Archive Account:
Control Tower creates a new member account called a Log Archive account that is similar to the ALZ’s Log Archive account. You can’t retain or select existing ALZ Log Archive accounts while deploying Control Tower. Therefore, if you want to retain the logs from the ALZ log bucket, you can copy the existing logs from the ALZ log archive Amazon Simple Storage Service (S3) bucket (aws-landing-zone-*) to a new S3 bucket in the Control Tower Log Archive account. However, you can’t put these logs in the Control Tower Log Archive’s log bucket due to access restrictions. Furthermore, if you have setup any log analytics solutions to fetch the logs from the ALZ Log Archive S3 bucket, then they must be migrated to the new Control Tower Log Archive account. If you don’t want to bring the old logs from ALZ to Control Tower, then you can ignore this step and, in that case, you can just empty the ALZ S3 logs bucket and delete it later.

Shared Services Account:
Unlike in an ALZ, Control Tower doesn’t create a Shared Services account. You can choose to retain this account as-is in Control Tower. In that case, you will need to enroll this account in Control Tower using Account factory.

Step 6: Decommission ALZ

Before decommissioning ALZ resources, make sure that you have moved all your required resources from ALZ to the Control Tower environment.

From the management account, disable the transition between the source stage and build stage for the ALZ’s AWS CodePipeline pipeline. This will prevent inadvertent updates from source files from initiating a pipeline run and redeploying resources that you are trying to remove.

⚠️Attention 

If you have deployed Landing Zone Add On products, please don’t terminate the associated AWS Service Catalog provisioned products.

Do not remove the CloudFormation stacks or StackSets, which are used to deploy the base line infrastructure in your accounts, such as VPC or IAM roles if they’re being used.

  • Delete Provisioned Products from the Service Catalog
    • If they are not in use by your workloads, then terminate the following prefixed Provisioned Products by clicking the three dots next to the product.
lz_core_*
  • Remove Products from Portfolios in the Service Catalog
  • For each portfolio in “Portfolios List”, i.e., “AWS Landing Zone – Baseline”, “AWS Landing Zone - Core” (ALZ 1.0) or “AWS Landing Zone - Add-On Products” (ALZ 2.0)

Remove all Constraints
Remove all Users and Groups
Remove the product from the portfolio
Navigate to the Portfolios List
Delete the portfolio

  • Delete Products from Service Catalog
    • For each product in “Products List”, i.e., “AWS-Landing-Zone-Account-Vending-Machine” and any other non-provisioned product with AWS-Landing-Zone-* select and delete them
  • Manually delete any remaining CloudFormation AVM Stacks with “(SO0045)” in the Description (there may be none if Service Catalog cleaned up correctly).
  • Delete any other Landing Zone CloudFormation Stacks EXCEPT the initiation template (SO0044) manually. Make sure you are not deleting any baseline infrastructure critical to your running workload.
  • If resources from below StackSets are not in use by your workloads, then delete them
        AWS-Landing-Zone-Baseline-EnableCloudTrail
        AWS-Landing-Zone-Baseline-EnableConfig
        AWS-Landing-Zone-Baseline-EnableConfigRules
        AWS-Landing-Zone-Baseline-ConfigRole
        AWS-Landing-Zone-Baseline-EnableConfigRulesGlobal
        AWS-Landing-Zone-Baseline-EnableNotifications
        AWS-Landing-Zone-Baseline-IamPasswordPolicy
        AWS-Landing-Zone-Baseline-SecurityRoles
        AWS-Landing-Zone-Baseline-PrimaryVPC
  • For the remaining unused StackSets which may still have stack instances, you may need to Manage those StackSets. Identify the accounts and enter the account numbers, regions, and delete the stack instances. Make sure that these StackSets don’t have the infrastructure currently in use by your workloads. After confirmation, if there are no Stack Instances, then you can simply delete the StackSet.
  • Delete the Logging Buckets in the Logging Account.
    • If you already copied the existing logs to a new AWS CT Log Archive account bucket, then delete the ALZ log bucket aws-landing-zone-*
  • Delete the following S3 buckets in the Master Account:
        aws-landing-zone-configuration-*
        landingzone-landingzonepipelineartifacts*
  • Delete the Landing Zone initiation template
    • Delete the CloudFormation stack (you likely have to “Change termination protection” to allow deletion). If there are issues with the deletion of resources, then delete them manually and retry the stack deletion until successful. If retaining any resources from ALZ StackSets, then retain this IAM role “AWSCloudformationStacksetExecution”.
  • Clean up Organizations
    • Delete the core OU created by ALZ. Don’t delete any other OU which is created by AWS CT.
    • Go to the Policies tab to delete the Service Control Policy. Select the protect-cloudtrail-config, and select “Delete Policy”.
  • Delete all of the Landing Zone SSM Parameters
    • Navigate to Systems Manager -> Parameter Store, and delete all of the landing zone related parameters.
  • Make sure that the Landing Zone KMS Keys have been deleted
    • Navigate to IAM -> Encryption Keys, and Confirm that there are no keys.
    • If the key exists, then delete the alias using the CLI:
aws kms delete-alias --alias-name alias/AwsLandingZoneKMSKey
  • Terminate the ALZ Log Archive and Security account
    • Once you migrate the logs and the required settings to the newly created AWS CT accounts, then you may close these accounts.

Conclusion

In this post, we have outlined steps and best practices for migrating from the AWS Landing Zone (ALZ) solution to AWS Control Tower. Control Tower lets customers provision new AWS accounts with just a few clicks from the console while providing you with the peace of mind of that your new accounts will conform to company-wide policies. A reporting dashboard also quickly provides you visibility into your account’s compliance status.

About the authors

Firas Yahia

Firas is Control Services Specialist at AWS, works closely with customers and partners within the area of management, governance, migration and modernization. He loves building and designing new architecture solutions where he can take the norm and break it.

Rohit Turambekar

Rohit likes to deep dive with customers and partners to work on their business cases especially in areas like AWS multi account management, resource provisioning automation and overall cloud migration strategy. In his previous role, he worked as a C++ developer, Technical program manager & Cloud Consultant.