Setting up a Sandbox AWS Account
Sandbox accounts are created through CDK pull requests, not through the AWS console. Creating accounts by hand (Control Tower Account Factory / Service Catalog) causes drift against our IaC and has caused email collisions in the past — don't do it.
Two small PRs get you a sandbox:
| Step | Repo | What it does |
|---|---|---|
| 1 | aws-organization-management | Creates the account and assigns it to the Sandbox OU |
| 2 | aws-sso | Wires the account into SSO so you can actually sign in |
Step 1 must merge and deploy before step 2 — the aws-sso stack imports a CloudFormation export that step 1 publishes.
Conventions
- Account name:
sandbox-<username>-<n>, e.g.sandbox-bgiese-1. - Root email:
aws+<account-name>@adaction.com, e.g.aws+sandbox-bgiese-1@adaction.com. Always the sharedaws@alias with plus-addressing — never a personal email. AWS account emails are globally unique and are the root user's recovery channel; keeping them all on theaws+alias meansaccounts-stack.tsdoubles as an inventory of the addresses we've used. It isn't a global record, though — closed accounts and accounts outside our org won't appear there, so if AWS still reports a collision, pick a different-<n>suffix.
Step 1 — create the account (aws-organization-management)
Example PR: aws-organization-management#97
-
Add the account to
buildNewAccounts()insrc/stacks/accounts-stack.ts:{name: 'sandbox-bgiese-1',email: 'aws+sandbox-bgiese-1@adaction.com',}, -
Add the OU assignment to
ACCOUNT_OU_ASSIGNMENTSinsrc/stacks/accounts-ou-assignment-stack.ts:{ accountName: 'sandbox-bgiese-1', ouPath: 'Sandbox' }, -
If you're not already in the
SandboxUsersgroup, add yourself in the engineers stack (example: aws-organization-management#87). -
Update snapshots (
npx jest -u), open the PR with afeat:title (semantic-release only deploys onfeat:/fix:), and merge. The pipeline deploys the stack, creates the account, and publishes theadaction-<account-name>-AccountIdexport.
Step 2 — wire it into SSO (aws-sso)
Example PR: aws-sso#266
-
Add one line to
importAccounts()insrc/import-utils.ts:this.importAccount({ name: "sandbox-bgiese-1" }),The
sandbox-*name is picked up byisSandboxAccount(), which routes the assignments intoSandboxAssignmentStackautomatically. -
Update snapshots (
npx jest -u), open the PR with afeat:title, and merge after step 1 has deployed — otherwise the deploy fails on the missing export.
Accessing your sandbox
Once both PRs are deployed, the account appears in the
AWS access portal with the
SandboxAccess permission set (via the SandboxUsers group).
Bootstrapping the account
Once the account is ready, you will want to bootstrap the account using the AWS CDK.
First, log in to AWS SSO using the AWS CLI:
# First time
$ aws configure sso --profile sandbox
SSO start URL [None]: https://adgem.awsapps.com/start
SSO Region [None]: us-east-2
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
https://device.sso.us-east-2.amazonaws.com/
Then enter the code:
XXXX-XXXX
There are 3 AWS accounts available to you.
Using the account ID 012345678901
The only role available to you is: SandboxAccess
Using the role name "SandboxAccess"
CLI default client Region [None]:
CLI default output format [None]:
To use this profile, specify the profile name using --profile, as shown:
aws s3 ls --profile sandbox
- During the Attempting to automatically open the SSO authorization page... step, a browser will open. Click the Allow button.
- During the There are # AWS accounts available to you. step, you'll be prompted to choose the account you created earlier.
Note: The transcript above shows the device-code flow used by AWS CLI versions before 2.22. On AWS CLI 2.22+ the browser signs you in directly and there is no device URL or
XXXX-XXXXcode to enter — just click Allow in the browser. (You can force the old behavior withaws configure sso --use-device-code.)
Now bootstrap the account for use with the AWS CDK, using the account ID from
the previous steps (in this example, 012345678901):
cdk bootstrap aws://<sandbox account number>/us-east-2 --profile <profile name>
# example
cdk bootstrap aws://012345678901/us-east-2 --profile sandbox
Note: If you get a
command not found: cdkerror when running this, you can install aws-cdk globally by runningnpm install -g aws-cdk.
On subsequent sessions you only need to log in again:
# Every time after
aws sso login --profile sandbox
Troubleshooting
- "An AWS account with that email already exists" — the email is taken
by another AWS account, possibly one that isn't visible from our access
portal (a different org, or a closed account — AWS reserves closed-account
emails for ~90 days). Stick to the
aws+<account-name>@convention and pick the next-<n>suffix.accounts-stack.tslists the names our org has used, but it can't show closed accounts or accounts in other orgs — if the collision persists, keep bumping the suffix. - aws-sso deploy fails with a missing export — step 1 hasn't deployed yet. Wait for the aws-organization-management release to finish, then re-run the failed deploy.