DEV Community

John  Ajera
John Ajera

Posted on

Unenroll a Control Tower sandbox member with the AWS CLI

Unenroll a Control Tower sandbox member with the AWS CLI

You enrolled a member account into AWS Control Tower (for example a sandbox workload account) and later want it not governed by the landing zone anymore. The console path is Organization then Unmanage. This article is the CLI path: terminate the Control Tower Service Catalog provisioned product that represents account enrollment, without closing the AWS account.


1. Overview

  • Goal: Unenroll (unmanage) one member account so Control Tower removes its controls and Service Catalog enrollment, while keeping the account open in AWS Organizations.
  • Mechanism: Terminate the CONTROL_TOWER_ACCOUNT provisioned product whose name looks like Enroll-Account-<12-digit-account-id>, with --retain-physical-resources so the account itself is not deleted.
  • Where it runs: Management account credentials with permission to Service Catalog APIs (and typically Organizations read if you verify parent OU afterward).
  • Region: Use your Control Tower home region (often where Account Factory and enrollment products live). Examples below use ap-southeast-2; substitute yours if different.

2. Prerequisites

  • Management account access (for example IAM Identity Center admin role on the org payer).
  • AWS CLI v2 configured for that account (aws sts get-caller-identity shows the management id).
  • The member account id you are unmanaging (12 digits).
  • Patience: termination is asynchronous; poll describe-record until SUCCEEDED or diagnose FAILED.

3. Confirm identity and region

3.1 Caller identity

export AWS_PROFILE=your-management-profile

aws sts get-caller-identity
Enter fullscreen mode Exit fullscreen mode

Confirm Account is the organization management account.

3.2 Control Tower home region

If you are unsure which region holds enrollment products, try the region where you normally open Control Tower and Account Factory, then continue in Section 4 using that --region.


4. Find the enrollment provisioned product

4.1 Scan provisioned products

scan-provisioned-products returns up to 20 items per call (use PageToken if you have many). Filter by eye or script for Enroll-Account-<your-member-id>.

REGION=ap-southeast-2

aws servicecatalog scan-provisioned-products \
  --region "$REGION" \
  --page-size 20 \
  --output json
Enter fullscreen mode Exit fullscreen mode

4.2 Identify the fields you need

From the matching object, note:

  • Id — the provisioned product id (example shape: pp-xxxxxxxxxxxxx).
  • Name — often Enroll-Account-405087531484 style.
  • Type — should include CONTROL_TOWER_ACCOUNT for the enrollment product you want to end.

If nothing appears in the first page, paginate with --page-token from the response, or confirm region and that the account was enrolled through Control Tower (not only moved under an OU in Organizations without enrollment).


5. Terminate the provisioned product (unenroll)

Use a unique --terminate-token per attempt (idempotency). --retain-physical-resources keeps the AWS account; Control Tower still tears down CT-managed resources it owns for that enrollment.

REGION=ap-southeast-2
PP_ID=pp-jxuf4ldvkwxxc

aws servicecatalog terminate-provisioned-product \
  --region "$REGION" \
  --provisioned-product-id "$PP_ID" \
  --terminate-token "unenroll-$(date +%s)" \
  --retain-physical-resources \
  --output json
Enter fullscreen mode Exit fullscreen mode

The response includes RecordDetail.RecordId (example shape: rec-xxxxxxxxxxxxx).


6. Wait for the record to finish

describe-record uses --id set to the record id (not --record-id on the CLI).

REGION=ap-southeast-2
RECORD_ID=rec-tupynci5numpi

aws servicecatalog describe-record \
  --region "$REGION" \
  --id "$RECORD_ID" \
  --query 'RecordDetail.{Status:Status,Errors:RecordErrors}' \
  --output json
Enter fullscreen mode Exit fullscreen mode

Poll until Status is SUCCEEDED. If FAILED, read RecordErrors and fix permissions or open an AWS Support case for Service Catalog / Control Tower as appropriate.


7. Verify organization placement

After a successful unmanage, the account usually moves under the organization root (no longer under a Control Tower-registered OU for that enrollment). Confirm with Organizations:

MEMBER_ID=405087531484

aws organizations list-parents --child-id "$MEMBER_ID"
Enter fullscreen mode Exit fullscreen mode

Expect Type ROOT for the parent you care about when the account has been moved out of Control Tower-managed OUs per product behavior.

Also expect: Control Tower removes AWSControlTowerExecution from the member when it cleans up. If you manage that role elsewhere (for example Terraform in a factory repo), run your pipeline again so intent matches reality.


8. Console alternative

If you prefer the UI: Unenroll an accountControl Tower console, Organization, expand the OU, select the account, Unmanage, wait until status shows Not enrolled.


9. Summary: Copy-paste

Replace REGION, PP_ID, AWS_PROFILE, and optionally MEMBER_ID for checks.

export AWS_PROFILE=your-management-profile
REGION=ap-southeast-2

aws sts get-caller-identity

aws servicecatalog scan-provisioned-products \
  --region "$REGION" \
  --page-size 20 \
  --output table

PP_ID=pp-REPLACE_ME
aws servicecatalog terminate-provisioned-product \
  --region "$REGION" \
  --provisioned-product-id "$PP_ID" \
  --terminate-token "unenroll-$(date +%s)" \
  --retain-physical-resources \
  --output json

RECORD_ID=rec-REPLACE_ME
aws servicecatalog describe-record \
  --region "$REGION" \
  --id "$RECORD_ID" \
  --output json

MEMBER_ID=405087531484
aws organizations list-parents --child-id "$MEMBER_ID"
Enter fullscreen mode Exit fullscreen mode

10. Troubleshooting

Issue What to try
scan-provisioned-products returns no Enroll-Account-… Wrong REGION; use Control Tower home region. Or the account was never enrolled via Control Tower (only placed in an OU with Organizations).
terminate-provisioned-product access denied Principal lacks Service Catalog terminate permissions in the management account.
describe-record FAILED Read RecordErrors; may be Control Tower internal constraint, SCP, or account state.
ParamValidation on describe-record Use --id, not --record-id, for record-id style values.
Account should stay in a specific OU after unenroll Unmanage moves the account to root per AWS docs; move it again with aws organizations move-account if your org design requires a different OU.

11. References

Top comments (0)