Field Notes: Enroll Existing AWS Accounts into AWS Control Tower
AWS Architecture BlogField Notes: Enroll Existing AWS Accounts into AWS Control Towerby Kishore Vinjam and Rick Wiggins | on26 FEB 2021| inArchitecture,AWS Control Tower,AWS Organizations,Technical How-to|Permalink|ShareOriginally published on April 21, 2020 to the Field Notes blog and updated in August 2020 with new prechecks to the account enrollment script.Updated April 8, 2021 to reflect changes in the AWS Organizations service.Last updated September 29, 2022: you can nowenroll an existing accountorregister an organizational unitfrom the AWS Control Tower console. This blog can be used for enrolling the account(s) programmatically.Since the launch ofAWS Control Tower, customers have been asking for the ability to deploy AWS Control Tower in their existing AWS Organizations and to extend governance to those accounts in their organization.We are happy that you can now deploy AWS Control Tower in your existing AWS Organizations. The accounts that you launched before deploying AWS Control Tower, what we refer to as unenrolled accounts, remain outside AWS Control Towers’ governance by default. These accounts must be enrolled in the AWS Control Tower explicitly.When you enroll an account into AWS Control Tower, it deploys baselines and additional guardrails to enable continuous governance on your existing AWS accounts. However, you must perform proper due diligence before enrolling in an account. Refer to the Things to Consider section below for additional information.In this blog, I show you how to enroll your existing AWS accounts and accounts within the unregistered OUs in your AWS organization under AWS Control Tower programmatically.BackgroundHere’s a quick review of some terms used in this post:The Python script provided in this post. This script interacts with multiple AWS services, to identify, validate, and enroll the existing unmanaged accounts into AWS Control Tower.An unregistered organizational unit (OU) is created through AWS Organizations. AWS Control Tower does not manage this OU.An unenrolled account is an existing AWS account that was created outside of AWS Control Tower. It is not managed by AWS Control Tower.A registered organizational unit (OU) is an OU that was created in the AWS Control Tower service. It is managed by AWS Control Tower.When an OU is registered with AWS Control Tower, it means that specific baselines and guardrails are applied to that OU and all of its accounts.AnAWS Account Factory accountis an AWS account provisioned using account factory in AWS Control Tower.Amazon Elastic Compute Cloud (Amazon EC2) is a web service that provides secure, resizable compute capacity in the cloud.AWS Service Catalogallows you to centrally manage commonly deployed IT services. In the context of this blog, account factory uses AWS Service Catalog to provision new AWS accounts.AWS Organizationshelps you centrally govern your environment as you grow and scale your workloads on AWS.AWS Single Sign-On(SSO) makes it easy to centrally manage access to multiple AWS accounts. It also provides users with single sign-on access to all their assigned accounts from one place.Things to ConsiderEnrolling an existing AWS account into AWS Control Towerinvolves moving an unenrolled account into a registered OU. The Python script provided in this blog allows you to enroll your existing AWS accounts into AWS Control Tower. However, it doesn’t have much context around what resources are running on these accounts. It assumes that you validated the account services before running this script to enroll the account.Some guidelines to check before you decide to enroll the accounts into AWS Control Tower.AnAWSControlTowerExecutionrole must be created in each account. If you are using the script provided in this solution, it creates the role automatically for you.If AWS Config was ever enabled on the account you enroll, adefaultconfig recorder and delivery channel were created.Delete the configuration-recorderanddelivery channelfor the account enrollment to work.Start with enrolling the dev/staging accounts to get a better understanding of any dependencies or impact of enrolling the accounts in your environment.Create a new Organizational Unit in AWS Control Tower and do not enable any additional guardrails until you enroll in the accounts. You can then enable guardrails one by one to check the impact of the guardrails in your environment.As an additional option, you can apply AWS Control Tower’s detective guardrails to an existing AWS account before moving them under AWS Control Tower governance. Instructions to apply the guardrails are discussed in detail inExtend AWS Control Tower governance using AWS Config Conformance Packsblog.PrerequisitesBefore you enroll your existing AWS account in to AWS Control Tower, check the prerequisites fromAWS Control Tower documentation.This Python script provided part of this blog, supports enrolling all accounts with in an unregistered OU in to AWS Control Tower. The script also supports enrolling a single account using both email address or account-id of an unenrolled account. Following are a few additional points to be aware of about this solution.Enable trust access with AWS OrganizationsforAWS CloudFormation StackSets.The email address associated with the AWS account is used as AWS SSO user name with default First NameAdminand Last NameUser.Accounts that are in the root of the AWS Organizations can be enrolled one at a time only.While enrolling an entire OU using this script, theAWSControlTowerExecutionrole is automatically created on all the accounts on this OU.You can enroll a single account with in an unregistered OU using the script. It checks forAWSControlTowerExecutionrole on the account. If the role doesn’t exist, the role is created on all accounts within the OU.By default, you are not allowed to enroll an account that is in the root of the organization. You must pass an additional flag to launch a role creation stack set across the organizationWhile enrolling a single account that is in the root of the organization, it prompts for additional flag to launch role creation stack set across the organization.The script uses CloudFormation Stack SetService-Managed Permissionsto create theAWSControlTowerExecutionrole in the unenrolled accounts.How it worksThe following diagram shows the overview of the solution.In your AWS Control Tower environment, access an Amazon EC2 instance running in the management account of the AWS Control Tower home Region.Get temporary credentials forAWSAdministratorAccessfrom AWS SSO login screenDownloadand execute theenroll_script.pyscriptThe script creates theAWSControlTowerExecutionrole on the target account usingAutomatic Deployments for a Stack Setfeature.On successful validation of role and organizational units that are given as input, the script launches a new product in Account Factory.The enrollment process creates an AWS SSO user using the same email address as the AWS account.Setting up the environmentIt takes up to 30 minutes to enroll each AWS account in to AWS Control Tower. The accounts can be enrolled only one at a time. Depending on number of accounts that you are migrating, you must keep the session open long enough. In this section, you see one way of keeping these long running jobs uninterrupted using Amazon EC2 using thescreentool.Optionally you may use your own compute environment where the session timeouts can be handled. If you go with your own environment, make sure you havepython3,screenand a latest version ofboto3installed.1. Prepare your compute environment:Log in to your AWS Control Tower with AWSAdministratorAccess role.Switch to the Region where you deployed your AWS Control Tower if needed.If necessary, launch a VPC using thestack hereand wait for the stack to COMPLETE.If necessary, launch an Amazon EC2 instance using thestack here. Wait for the stack to COMPLETE.While you are on management account,increase the session time durationfor AWS SSO as needed. Default is 1 hour and maximum is 12 hours.2. Connect to the compute environment (one-way):Go to theEC2 Dashboard, and chooseRunning Instances.Select the EC2 instance that you just created and chooseConnect.InConnect to your instancescreen, underConnection method, chooseEC2InstanceConnect (browser-based SSH connection)andConnectto open a session.Go to AWS Single Sign-On page in your browser. Click on your management account.Choosecommand line or programmatic accessnext toAWSAdministratorAccess.FromOption 1copy the environment variables and paste them in to your EC2 terminal screen in step 5 below.3. Install required packages and variables. You may skip this step, if you used the stack provided in step-1 to launch a new EC2 instance:Installpython3andboto3on your EC2 instance. You may have to update boto3, if you use your own environment.$ sudo yum install python3 -y$ sudo pip3 install boto3$ pip3 show boto3Name: boto3
Version: 1.12.39Change to home directory and download theenroll_account.pyscript.$ cd ~
$ wget https://raw.githubusercontent.com/aws-samples/aws-control-tower-reference-architectures/master/customizations/AccountFactory/EnrollAccount/enroll_account.pySet up your home Region on your EC2 terminal.export AWS_DEFAULT_REGION=<AWSControlTower-Home-Region>4. Start ascreensession in daemon mode. If your session gets timed out, you can open a new session and attach back to the screen.$ screen -dmS SAM$ screen -lsThere is a screen on:
        585.SAM (Detached)
1 Socket in /var/run/screen/S-ssm-user.$ screen -dr 585.SAM5. On the screen terminal, paste the environmental variable that you noted down in step 2.6. Identify the accounts or the unregistered OUs to migrate and run the Python script provide with below mentioned options.Python script usage:usage: enroll_account.py -o -u|-e|-i -cEnroll existing accounts to AWS Control Tower.

optional arguments:
  -h, --help            show this help message and exit
  -o OU, --ou OU        Target Registered OU
  -u UNOU, --unou UNOU  Origin UnRegistered OU
  -e EMAIL, --email EMAIL
                        AWS account email address to enroll in to AWS Control Tower
  -i AID, --aid AID     AWS account ID to enroll in to AWS Control Tower
  -c, --create_role     Create Roles on Root LevelEnroll all the accounts from an unregistered OU to a registered OU$ python3 enroll_account.py -o MigrateToRegisteredOU -u FromUnregisteredOU 
Creating cross-account role on 222233334444, wait 30 sec: RUNNING 
Executing on AWS Account: 570395911111, USER+SCADMINT1@amazon.com 
Launching Enroll-Account-vinjak-unmgd3 
Status: UNDER_CHANGE. Waiting for 6.0 min to check back the Status 
Status: UNDER_CHANGE. Waiting for 5.0 min to check back the Status 
. . 
Status: UNDER_CHANGE. Waiting for 1.0 min to check back the Status 
SUCCESS: 111122223333 updated Launching Enroll-Account-vinjakSCchild 
Status: UNDER_CHANGE. Waiting for 6.0 min to check back the Status 
ERROR: 444455556666 
Launching Enroll-Account-Vinjak-Unmgd2 
Status: UNDER_CHANGE. Waiting for 6.0 min to check back the Status 
. . 
Status: UNDER_CHANGE. Waiting for 1.0 min to check back the Status 
SUCCESS: 777788889999 updatedUse AWS account ID to enroll a single account that is part of an unregistered OU.$ python3 enroll_account.py -o MigrateToRegisteredOU -i 111122223333Use AWS account email address to enroll a single account from an unregistered OU.$ python3 enroll_account.py -o MigrateToRegisteredOU -e JohnDoe+outside-ct-ou@amazon.comYou are not allowed by default to enroll an AWS account that is in the root of the organization. The script checks for theAWSControlTowerExecutionrole in the account. If role doesn’t exist, you are prompted to use-c | --create-role. Using-cflag adds the stack instance to the parent organization root. Which means anAWSControlTowerExecutionrole is created in all the accounts with in the organization.Note:Ensure installingAWSControlTowerExecutionrole in all your accounts in the organization, is acceptable in your organization before using-cflag.If you are unsure about this, follow the instructions in thedocumentationand create theAWSControlTowerExecutionrole manually in each account you want to migrate. Rerun the script.Use AWS account ID to enroll a single account that is in root OU (need -c flag).$ python3 enroll_account.py -o MigrateToRegisteredOU -i 111122223333 -cUse AWS account email address to enroll a single account that is in root OU (need -c flag).$ python3 enroll_account.py -o MigrateToRegisteredOU -e JohnDoe+in-the-root@amazon.com -cCleanup stepsOn successful completion of enrolling all the accounts into your AWS Control Tower environment, you could clean up the below resources used for this solution.If you have used templates provided in this blog to launch VPC and EC2 instance, delete the EC2 CloudFormation stack and then VPC template.ConclusionNow you can deploy AWS Control Tower in an existing AWS Organization. In this post, I have shown you how to enroll your existing AWS accounts in your AWS Organization into AWS Control Tower environment. By using the procedure in this post, you can programmatically enroll a single account or all the accounts within an organizational unit into an AWS Control Tower environment.Now that governance has been extended to these accounts, you can also provision new AWS accounts in just a few clicks and have your accounts conform to your company-wide policies.Additionally, you can useCustomizations for AWS Control Towerto apply custom templates and policies to your accounts. With custom templates, you can deploy new resources or apply additional custom policies to the existing and new accounts. This solution integrates with AWS Control Tower lifecycle events to ensure that resource deployments stay in sync with your landing zone. For example, when a new account is created using the AWS Control Tower account factory, the solution ensures that all resources attached to the account’s OUs are automatically deployed.Field Notes provides hands-on technical guidance from AWS Solutions Architects, consultants, and technical account managers, based on their experiences in the field solving real-world business problems for customers.TAGS:AWS Control Tower,AWS Organizations,Field NotesKishore VinjamKishore Vinjam is a partner solutions architect focusing on AWS Service Catalog, AWS Control Tower, and AWS Marketplace. He is passionate about working in cloud technologies, and working with customers and building solutions for them. When not working, he likes to spend time with his family, hike, and play volleyball and ping-pong.Rick WigginsRick Wiggins is a Senior Consultant with AWS Professional Services. His specialty is in Migrations and Multi-Account Architecture for large Enterprise customers in the US Government. His passion is building and automating Infrastructure and Operations to allow customers to focus more on their business. In his spare time, he can be found hanging out with his wife and three kids or tinkering with some new Alexa skill.
Originally published on April 21, 2020 to the Field Notes blog and updated in August 2020 with new prechecks to the account enrollment script. Updated April 8, 2021 to reflect changes in the AWS Organizations service.  Last updated September 29, 2022: you can now enroll an existing account or register an organizational unit  from the […]
Kishore Vinjam
Architecture AWS Control Tower AWS Organizations Technical How-to