AWS Cloud Operations & Migrations Blog

Delegate account factory creation to parts of your organization with AWS Control Tower

While working with many of our regulated industry customers, we have been posed the question: “How can we enable a local team to create AWS Control Tower managed accounts within their specific Organizational Units (OUs)?”
The customers want to leverage the guardrails and baselines put in place by AWS Control Tower so that:

  1. They could avoid additional overhead by routing requests to their central team
  2. They could allow the local team to create accounts that meet all of their governance requirements, and without having to write custom code or create additional workflows.

In this post, we will describe how you can delegate AWS Control Tower’s Account Factory to a specific part of your AWS estate. This enables and empowers local teams to create accounts while providing assurances that best practices and foundational baselines are adhered to. In addition, you can adapt the inputs provided by end users requesting accounts to meet your organization’s standards, further improving your environment setup and hygiene.


Before we get into how it works, let’s first review some key concepts:

  • An AWS Service Catalog product is a blueprint for building your AWS resources that you want to make available for deployment on AWS along with the configuration information.
  • A portfolio is a collection of products, together with the configuration information.
  • Constraints control the way that users can deploy a product. With launch constraints, you can specify a role that the AWS Service Catalog can assume to launch a product.

Solution overview

The solution that we’ll implement involves the use of AWS Service Catalog features, along with AWS Control Tower’s Account Factory.

Architecture diagram showing the final solution. The Management Account shares the Account Factory Product to Regional OU-X with pre-defined launch and template constraints. The Regional OU-X imports the Account Factory product shared by the Management Account.


We’ll perform the following steps:

  • Create a customized Account Factory Product
    • Adjust some of the input parameters to suit the requirements.
  • Attach a Launch Constraint to make sure that the appropriate permissions are available.
  • Share this customized Account Factory Product with a specific account (“Delegated Account Factory Account”).
  • And finally, we’ll provision an account from the “Delegated Account Factory Account”.

Set up

From the AWS Management Console

We can navigate to AWS Service Catalog, and then select products to access the AWS Control Tower Account Factory Product.

Note the Product ID (similar to prod-xxxx) and ID of the Active Product version (similar to pa-xxxxx) of AWS Control Tower Account Factory.

Picture showing Product ID (similar to prod-xxxx) and ID of the Active Product version (similar to pa-xxxxx) of AWS Control Tower Account Factory.

You can also use AWS CloudShell to get these values:

$ aws servicecatalog describe-product --name "AWS Control Tower Account Factory"|jq '.ProductViewSummary.ProductId, .ProvisioningArtifacts[].Id'

Now you can create an AWS Service Catalog portfolio and a product for every OU Administrator. For OU-X-Admin, we would create the ou-x-portfolio in AWS Service Catalog.

Now we can create a product ou-x-product and provide the ProductId and ProvisioningArtifactId of the AWS Control Tower Account Factory which we recorded earlier. We would also add parameters to select the different OUs.

The sample AWS CloudFormation template is as follows, and it contains the Product ID and the ID of the active provisioning artifact along with the parameters needed to provision the account.

AWSTemplateFormatVersion: 2010-09-09
Description: AWS Control Tower Account Factory Template for Regional IT
    Description: "Account name, the new managed Account will be created with this name."
    Type: String
    AllowedPattern : ".+"
    Description: "Account email, must be unique for each AWS Account."
    Type: String
    AllowedPattern : "[^\\s@]+@[^\\s@]+\\.[^\\s@]+"
    Description:  "SSO user first name."
    Type: String
    AllowedPattern : ".+"
    Description:  "SSO user last name."
    Type: String
    AllowedPattern : ".+"
    Description: "SSO user email. A new SSO user will be created for this email, if it does not exist. This SSO user will be associated with the new managed Account."
    Type: String
    AllowedPattern : "[^\\s@]+@[^\\s@]+\\.[^\\s@]+"
    Description: "Your account will be added to this registered organizational unit. The list includes top-level and nested OUs registered with AWS Control Tower. You can search for an OU by name or ID. To manage these OUs, go to AWS Control Tower."
    Type: String
      - "Sandbox (ou-3lmc-adi1jf23)"
      - "BusinessUnitX (ou-3lmc-f6w32h77)"
    Type: "AWS::ServiceCatalog::CloudFormationProvisionedProduct"
      ProductId: prod-4kukrlxf4bw74 
      ProvisioningArtifactId: pa-j6czyetl4upog 
          Key: AccountName
            Ref: pAccountName
          Key: AccountEmail
            Ref: pAccountEmail
          Key: SSOUserFirstName
            Ref: pSSOUserFirstName
          Key: SSOUserLastName
            Ref: pSSOUserLastName
          Key: SSOUserEmail
            Ref: pSSOUserEmail
          Key: ManagedOrganizationalUnit
            Ref: pManagedOrganizationalUnit

Once the product is created, we can add it to our ou-x-portfolio. We would add two constraints on newly created portfolios to restrict them to AWS Identity and Access Management (IAM) roles and OUs.

IAM Role

Picture showing creation of IAM role. The trusted entity type is AWS Service and Service Catalog has been selected to access AWS resources on your behalf.

Add the Admin Permissions to it.

Picture showing adding AdministratorAccess IAM Policy to the IAM Role and selecting Service Catalog as a Trusted Entity.

Now we can add this IAM Role to AWS Control Tower Account Factory Portfolio so that AWS Service Catalog can launch the AWS Control Tower Account Factory product. Then, it will be added as the Launch Constraint for our ou-x-portfolio.

The launch constraint limits which IAM Role the AWS Service Catalog product runs in the Management Account with when launched from OU-X.

The template constraint limits showing in which OU the account be create. In this picture, its limited to OU-X only. The launch constraint limits which IAM role can be used to launch this template.

The template constraint limits which OU can be created in this Account. In this example, the following limits it to OU-X only.

In this picture, A Template constraint has been created which limits the account creation only to OU-X, an optional description has been entered and product version has been selected from available versions.

The template constraint limits which OU can be created in this Account. In this picture, it has limited only to OU-X.

You can also use text editor to add the same constraint.

  "Rules": {
    "LimitOUX": {
      "Assertions": [
          "Assert": {
            "Fn::Contains": [
                "BusinessUnitX (ou-z319-w9a1x7c5)"
                "Ref": "pManagedOrganizationalUnit"
          "AssertDescription": ""

The following image shows the two constraints for ou-x-portfolio.

The image shows the Launch and Template constraints for ou-x-portfolio. Launch constraint limits which IAM role can be used and template constraint in this example limits which OU account can be created in.

Now you can share the portfolio to the account responsible for OU-X Administration, and then provide the product ID so that the admin for OU-X can import it in the next steps.

Picture showing sharing of the portfolio to the account responsible for OU-X Administration. The product ID would then be provided to Admin of OU-X so that the admin for OU-X can import it.

At this point, the Administrator for OU-X can launch the Account Factory product from the AWS Service Catalog and provision accounts in OU-X (as limited by constraints).

You can provide the AWS Single Sign-On (AWS SSO) User Portal URL to your OU-X Admin so that they can log in using AWS SSO and provision AWS accounts in their OU. The AWS SSO User Portal URL is available at the AWS SSO Dashboard page under Settings Summary.

Provisioning accounts as OU-X admin

The following procedure describes how to provision accounts as an AWS SSO end user, through AWS Service Catalog. This procedure is also referred to as advanced account provisioning. We recommend using the Enroll account capability whenever possible.

To provision accounts in Account Factory as an OU-X Admin

  1. By this time, you should have been provided with a specific sign-in URL to the user portal by an administrator or help desk employee. Once you have this, you can proceed with the following steps to sign in to the portal. Sign in from your user portal URL. Your user should have the necessary permissions to access the admin account for OU-X and launch the AWS Control Tower Account Factory. For the purpose of this post, we assigned AWSAdministratorAccess as the permission set to our admin user of OU-X.
  2. From Your applications, choose AWS Account.
  3. From the list of accounts, choose the account ID for your management account. This ID may also have a label, for example (ou-x-admin).
  4. From AWSAdministratorAccess, choose Management console. This opens the AWS Management Console for this user in this account.
  5. Make sure that you’ve selected the correct AWS Region for provisioning accounts, which should be your AWS Control Tower home Region.
  6. Search for and choose Service Catalog to open the AWS Service Catalog console.
  7. From the navigation pane, choose Portfolios, and then select Imported.
  8. Select Actions, select Import Portfolio, and choose the “AWS Account”, then enter the portfolio ID which we shared before to import it in the ou-x-admin account.
  9. Select Groups, Roles, and users for portfolio (e.g ou-x-portfolio), and add the AWSReservedSSO_AWSAdministratorAccess_xxxxx role to the local portfolio so you can launch the product.
  10. Now you can select Products in the left pane and confirm that ou-x-product is available.
  11. Select ou-x-product product, and select Launch Product.
  12. Select “generate name” to generate the provisioned product name.
  13. Enter the parameter values, such as AccountEmail (must be unique for each AWS Account), AccountName, SSOUserEmail, SSOUserFirstName, and SSOUserLastName.
  14. Note that the parameter ManagedOrganizationalUnit is locked to BusinessUnitX due to constraints initially placed on the product. This would make sure that the account is provisioned only in BusinessUnitX
  15. Finally, select Launch product.
  16. [Optional] If you navigate to Provisioned products in the OU-X-admin account now, then you would see that a product is being provisioned and its status is under change.
  17. [Optional] You can also log in to the AWS Control Tower Management Account and confirm that your account is now being provisioned in BusinessUnitX. It can take a few minutes to complete. You can refresh the page to update the displayed status information.

Note that only one account can be provisioned at a time.

Best practices

Consider adapting the parameters of the Delegated Product

Many of the customers we’ve worked with have clear guidelines for creating accounts – a format for email addresses, naming conventions, etc. As you’re creating your own unique product, you can also control the parameters with which accounts are created.

A common approach is to use a shared-mailbox and/or format for email addresses, typically using subaddressing. This means that you could have a central AWS mailbox for all of the root accounts, say and aws-team@example.corp. Using subaddressing, you could make sure that it’s used for newly vended accounts. For example, taking the account name and appending it, so that if we created an account named dans-sandbox then the email address would be automatically set to aws-team+dans-sandbox@example.corp.

Track AWS Service Catalog product deployments statistics

You can easily query this for your entire AWS Service Catalog (only existing, not deleted), and create a view/report on this. You can also output that to a JSON file and visualize it using Amazon QuickSight, or your favorite tool.

The following is an example query (remember to query the Aggregator) in the Audit Account in AWS Control Tower which will show you the deployment statistics:

SELECT count(resourceId),accountId,configuration.productId,configuration.provisioningArtifactId WHERE resourceType = 'AWS::ServiceCatalog::CloudFormationProvisionedProduct' GROUP BY accountId,configuration.productId,configuration.provisioningArtifactId


In this post, we demonstrated how you can enable teams to create accounts in their OUs which will meet all of the governance requirements. This will be accomplished without writing any custom code or additional workflows. Furthermore, this means that customers can safely delegate account creation to regional or specific teams, OU administrators, and simplify their workflow to achieve operational efficiency.

You can read more about AWS Control Tower Account Factory in the documentation.


Raphael Sack

Raphael is a technical business development manager for Service Catalog & Control Tower. He enjoys tinkering with automation and code and active member of the management tools community.

Chris Scott

Chris is a Global Solutions Architect responsible for helping customers in the HCLS industry build secure, scalable, and innovative solutions on AWS. He has over 25 years of experience working with technology, within in operations, solution, and enterprise architecture roles across various industry sectors.

Anshu Sharma

Anshu is an Enterprise Solutions Architect at AWS and loves to work with customers to achieve business outcomes. He is passionate about Media and Entertainment. In his free time, he likes to spend time with his family and learn more about everything Cloud.