The fifth account request this month sits in a Slack thread. Someone with management account access will click through the console, and the new account's baseline will differ slightly from the last one. If you're a CTO or platform lead at a growing SaaS company, that's when you start looking for an AWS account vending machine.
The choice is easy to get wrong because its cost arrives later, in day-2 baseline changes and on the day you close an account. I build multi-account landing zones for B2B SaaS teams, and I judge a vending machine on those two days. You'll get five approaches compared, a decision flow, a reviewed pull-request example, and the current closure quotas.
What is an AWS account vending machine?
An AWS account vending machine is an automated pipeline that creates a new AWS account on request, places it in the right organizational unit, and applies your security baseline before anyone uses it. AWS Control Tower's Account Factory is the AWS-built version; many teams build their own with Terraform, Step Functions, or AWS CDK.
AWS uses the term itself: the Control Tower terminology page says Account Factory "is referred to informally as a 'vending machine' for accounts".
Whatever the tool, the machine does four jobs:
- Create the account with the asynchronous AWS Organizations
CreateAccountAPI. - Place it in an organizational unit (OU), which sets the policies that apply.
- Baseline it with roles, guardrails, logging and security services.
- Hand over access through the administrator role
CreateAccountcreates:OrganizationAccountAccessRoleby default,AWSControlTowerExecutionunder Control Tower.
A vending machine isn't a landing zone. The landing zone is the foundation of organization, core accounts and guardrails; the vending machine is how workload accounts join it.
When does creating accounts by hand stop working?
Manual creation breaks once accounts become your unit of isolation, one per environment, team or customer. Requests wait on the one person with management account access, and accounts created a month apart end up with different baselines.
Every approach below hits the same AWS Organizations quotas:
- 10 accounts by default, raised through Service Quotas up to 50,000 based on qualification.
- 5 account creations in progress at once.
CreateAccountthrottled to 0.1 requests per second, with a burst of 3.1.
At one new account a quarter, I'd keep a runbook to add or remove member accounts by hand. Once requests repeat monthly or baselines diverge, automate.
Five ways to vend AWS accounts
The first three approaches run on Control Tower. The last two need only AWS Organizations.
Control Tower Account Factory
Requests come through the Account Factory console, the Service Catalog console, or the ProvisionProduct API. Service Catalog calls Control Tower, which calls CreateAccount and applies blueprints and controls, with up to 5 account operations at once (Control Tower limits).
Service Catalog controls who can launch the product, not who approves each launch. AWS's own example adds approval in ServiceNow through the AWS Service Management Connector.
Service Catalog, and with it Account Factory, is missing from seven Regions, including ca-west-1 and eusc-de-east-1. Since November 2025, CreateAccount plus MoveAccount into a registered OU auto-enrolls an account without the form. It needs landing zone 3.1 or later and an opt-in, and enrollment "typically takes a few minutes, up to several hours".
Account Factory for Terraform (AFT)
AFT turns a request into a Terraform file. Pushing an aft-account-request module call triggers a pipeline that queues requests in an SQS FIFO queue and feeds them to the same Account Factory backend, one at a time.
It needs a Control Tower landing zone plus a dedicated AFT management account, which takes up to 30 minutes to provision. AFT has no AWS charge, but its default PrivateLink endpoints and NAT gateway for CodeBuild drive the running cost. AWS defines no approval gate; review is whatever branch protection guards the request repository.
On day 2, customization changes don't re-run on existing accounts until you trigger the aft-invoke-customizations state machine. AFT 1.22.0, announced in October 2026, added plan-only runs that work as drift checks. Here's how AFT compares with a CDK landing zone.
Account Factory Customization and CfCT
Both sit on top of Account Factory. They handle the baseline, while the request still goes through Account Factory.
Account Factory Customization (AFC) attaches one blueprint, a Service Catalog product in a hub account, when you create or enroll an account. It deploys to the home Region or to all governed Regions, Terraform blueprints reach a single Region, and it's unavailable wherever Service Catalog isn't.
Customizations for AWS Control Tower (CfCT) is a manifest.yaml package that CodePipeline deploys as StackSets and SCPs. Control Tower lifecycle events trigger it, so new accounts receive your resources automatically, and the AWS Architecture Blog shows an optional manual approval stage.
A custom Step Functions or Lambda vending machine
The do-it-yourself version is a state machine that calls CreateAccount, polls DescribeCreateAccountStatus, assumes OrganizationAccountAccessRole in the new account, and applies the baseline. It needs neither Control Tower nor Service Catalog.
The AWS bill is negligible: Step Functions Standard includes 4,000 free state transitions a month, then $0.000025 each in the us-east-1 pricing example. The code is the real cost. The AWS sample, aws-samples/aws-account-vending-machine, was archived on June 17, 2024, so you own every line.
Existing scripts should read the account State field, not Status, which AWS kept alongside it only until September 9, 2026. Ephemeral sandbox pools are a variant that hands out pre-created accounts.
Infrastructure as code with the Organizations API and StackSets
Accounts are AWS::Organizations::Account resources (CfnAccount in AWS CDK), and the baseline lives in service-managed StackSets: one CloudFormation template deployed to many accounts, with Organizations handling permissions. With auto-deployment, a stack instance lands in every account that joins a target OU. A request becomes a code change, reviewed as a pull request with a diff.
Our AWS CDK Landing Zone packages this approach: accounts, OUs and SCPs change through pull requests with the cdk diff posted for review, and StackSets baseline each new account.
Two behaviors of the account resource need planning: its default DeletionPolicy is Retain, so removing it doesn't close the account unless you set Delete, and AccountName, Email and RoleName can't be updated. The CloudFormation resource properties reference lists the rest.
Other options here include Landing Zone Accelerator and OrgFormation.
How the five approaches compare on speed, cost, drift and closure
Every path ends in the same CreateAccount call, so time to account barely separates them. Day-2 changes and closing are where they diverge.
| Approach | Time to usable account | AWS cost driver | Day-2 baseline change | Drift |
|---|---|---|---|---|
| Account Factory | "A few minutes" (AWS docs); older AWS blogs: about 23 to 35 min | Service Catalog calls past 1,000 free a month; Config and CloudTrail | Update account or re-register OU | Detected automatically, fixed by hand |
| AFT | Account Factory backend, one request at a time | PrivateLink endpoints, NAT gateway | Re-run customizations state machine | Plan-only runs |
| AFC / CfCT | Account Factory plus blueprint or pipeline run | Pipeline and StackSets resources | AFC: one blueprint; CfCT: manifest change | CfCT redeploys the manifest |
| Custom build | Async CreateAccount, "a few minutes" | State transitions | You build it | You build it |
| IaC + StackSets | Async CreateAccount; baseline follows | Resources the baseline deploys | Edit the StackSet template | StackSets drift detection |
| Approach | Closing | Approval and review | Lock-in |
|---|---|---|---|
| Account Factory | Terminating doesn't close; unmanage, then CloseAccount | Whoever can launch the product; no change preview | Control Tower; not in seven Regions |
| AFT | Unmanage, then CloseAccount | Your Git workflow; no AWS gate | Control Tower, AFT account, Terraform |
| AFC / CfCT | As Account Factory | CfCT: optional approval stage | Control Tower; AFC Region options |
| Custom build | Your own CloseAccount call | You build it | All your code |
| IaC + StackSets | Default Retain: deleting code doesn't close | Pull request with cdk diff | Your code; CloudFormation, CDK |
See what Control Tower's Config and CloudTrail cost.
Which AWS account vending machine fits your team?
Three facts decide it: whether you run Control Tower, whether your Region has Service Catalog, and where account requests get reviewed.
I'd settle the review question first. With a console form, review happens upstream in a ticket, and nothing checks that the account matches what was approved. With a pull request, the reviewer reads the exact change the pipeline will make.
Worked example: an account request as a pull request
A product team needs a production account for a new Payments service. With our AWS CDK Landing Zone, that AWS account vending request is one pull request.
The pull request adds four lines under ProductionOU in src/config/organization-structure.ts. The root email must never have been used for any AWS account, and plus-addressing generates unique addresses under one domain:
ProductionOU: {
name: 'workload-prod-ou',
accounts: {
// existing accounts
PaymentsAccount: {
name: 'Payments',
email: 'aws+payments-prod@example.com',
},
},
},
The github-actions bot comments with the cdk diff (locally, pnpm run organization:diff): one new AWS::Organizations::Account in LandingZoneOrganizationStack, and no differences in the landing-zone phase. The reviewer checks the OU, the email, and any optional budget or policies; name and email matter most, since CloudFormation can't update them later.
Merging deploys it. The generated GitHub Actions workflow signs in through OIDC, with no long-lived AWS keys in GitHub, and on every merge to main the organization phase creates the account in its OU.
No StackSet code changes: the StackSets target OUs, so Organizations auto-deploys their stack instances as the account joins:
AccountSecurityStackSet: secure defaults in every member account.ResourceExplorerStackSet: a Resource Explorer index in every active Region.CdkBootstrapStackSet: CDK toolkit resources for Development and Production OU accounts.ServiceQuotasStackSet: your service quota requests for Development, Production and Security OU accounts.
Alternate contacts and the marketing email opt-out apply automatically, and the GuardDuty, Security Hub, Inspector and Macie services you enabled enroll it org-wide. Confirm the account exists:
aws organizations list-accounts --query 'Accounts[?Name==`Payments`]'
Then check that its StackSet instances reach CURRENT.
In my experience the account is ready for workloads within minutes. If you build this yourself, chain several accounts in one CloudFormation template with DependsOn so Organizations creates them in sequence.
This flow suits teams that already review infrastructure in GitHub pull requests and are comfortable with AWS CDK in TypeScript; a team that wants a console form for non-engineers to request accounts is better served by Account Factory.
Closing accounts: the part most vending machines skip
No create path closes an account by default. Terminating an Account Factory product removes the account from its OU and landing zone but leaves it open; you unmanage it, then close it through Organizations. With CloudFormation's Retain default, deleting code changes nothing either.
CloseAccount is asynchronous: the account's State moves from PENDING_CLOSURE to CLOSED. A 90-day post-closure period follows in which only AWS Support can reopen it. After that, remaining resources are deleted, and a bill can still arrive (Close an AWS account).
Closures are capped per rolling 30 days, the quota isn't adjustable, and at most 3 can be in progress:
| Member accounts | Closures per rolling 30 days |
|---|---|
| Under 1,250 | 250 |
| 1,250 to 5,000 | 20% of member accounts |
| Over 5,000 | 1,000 |
A runbook still planning around 10% or 200 closures needs updating. Also plan for these:
- A closed account counts toward your account quota for the 90 days unless you remove it from the organization first.
- The email at closure can't become another account's primary email, so change it beforehand if you want to reuse it.
RetainStacksOnAccountRemovaldecides whether StackSet baseline stacks are deleted when the account leaves a target OU.
The CDK Landing Zone keeps closing in the same file as creating. Moving an entry under SuspendedOU applies the lockdownSuspendedAccountsSCP, which quarantines the account while security services keep running. Moving it under the nested CloseAccountOU makes the organization phase close its active accounts every 8 hours and retry failed closures on the next run. Each move is a pull request with a diff, like the request that created the account.
Frequently Asked Questions
Is an account vending machine worth it with five accounts?
Is Control Tower Account Factory free?
Do I need Control Tower to vend AWS accounts?
How many AWS accounts can one organization have?
Pick the vending machine you can review and close
- Every AWS account vending machine shares the same Organizations quotas.
- Account Factory gives you a request form; review has to live elsewhere, such as ServiceNow.
- Day-2 baseline changes and closing separate the approaches more than time to account.
- No create path closes an account by default, so plan
CloseAccountand its 30-day quota up front.
For the wider trade-off, compare Control Tower versus a CDK landing zone. To see every step of that pull request, from picking the OU and a unique root email to checking that the StackSet instance reaches CURRENT, read the add-an-account guide.
Next step