Onboarding

AWS - multi-account (Organizations)

If your company uses AWS Organizations, you can onboard every member account in one deployment. CloudFormation StackSets creates the LevelFour cross-account role in every account under your deployment target - your organization's root (every account) or a specific OU (a subset) - including accounts that join later.

If you only have a handful of accounts or you don't use AWS Organizations, see the single-account path instead.

The whole flow runs from the LevelFour dashboard without an onboarding contact in the loop. Go to Connect Accounts → AWS in the dashboard (https://dashboard.levelfour.ai/connect-accounts/aws), switch the tab to AWS Organization, paste your AWS Organizations root ID (r-...) or an OU ID (ou-...-...) into the input, then click Connect via AWS Console. The dashboard opens AWS Console with the v2 StackSet wrapper template fully pre-filled (handshake, per-click integration ID, pingback ARN, and the target ID are all populated). One click on Create stack kicks off the deploy. Once the wrapper stack finishes in your management account, LevelFour's pingback handler verifies the role, enumerates every active member account via AWS Organizations, and registers them. The dashboard flips to Connected with the full discovered list within ~30 seconds.

You don't need to run the preflight script for this path. The dashboard collects the one piece of information the AWS Console can't pre-fill itself (your Root or OU ID). The Find this → link in the dashboard input opens the AWS Organizations console where the Root ID is shown at the top of the accounts tree.

The manual steps below are still here as a fallback when you prefer to deploy via the AWS CLI/IaC or cannot reach the dashboard from the management account.

How it works

You deploy a small wrapper template in your management account. The wrapper contains a AWS::CloudFormation::StackSet resource that references the standard LevelFour onboarding template and fans it out to every account under the deployment target you specify (root or OU).

  • One deploy, one approval - the customer-facing experience is identical to the single-account Launch Stack flow
  • Auto-deployment is enabled by default - when a new account joins your target, it automatically gets the LevelFour role
  • LevelFour discovers all your accounts via AWS Organizations after deployment; you don't copy any role ARNs back to LevelFour

Prerequisites

Before you click Launch Stack, four things need to be true. Walk through them in order.

AWS Organizations is in "all features" mode

Open the AWS Organizations console → Settings. The "Feature set" must show All features. If it shows "Consolidated billing," click Begin process to enable all features and have every member account accept the invitation before continuing.

Trusted access for CloudFormation StackSets is enabled

This is a two-sided toggle. Service-managed StackSets need permission from both Organizations and CloudFormation, and these are activated separately.

Organizations side - Open the AWS Organizations console → Services. Find CloudFormation StackSets and confirm Trusted access is Enabled. If it's disabled:

aws organizations enable-aws-service-access \
  --service-principal=member.org.stacksets.cloudformation.amazonaws.com

CloudFormation side - Activate Organizations access on the CloudFormation StackSets service itself (this is a separate toggle that's NOT enabled by default and is per-region):

aws cloudformation activate-organizations-access --region us-east-1

You can confirm it's on with:

aws cloudformation describe-organizations-access --region us-east-1
# Expected: {"Status": "ENABLED"}

If you skip the CloudFormation-side activation, the StackSet deploys with the misleading error "You must enable organizations access to operate a service managed stack set" - the preflight script catches this for you.

You're signed in to the management account

The Launch Stack link must be opened in the AWS Organizations management account (or in a delegated CloudFormation StackSets admin account). The top-right account selector in the AWS console must match.

No SCP blocks IAM role creation in the target OU

If your organization uses Service Control Policies, none of the SCPs attached to the OU you'll target may deny iam:CreateRole, iam:AttachRolePolicy, or iam:PutRolePolicy for roles named LevelFourCrossAccountRole. If you're not sure, run the preflight script below - it can't check SCPs directly, but a dry-run deploy against one account in the OU will surface any block.

Step 1 - Run the preflight check

In AWS CloudShell signed in to your management account, run:

curl -fsSL https://cf-templates-1bsphth8u70q9-us-east-1.s3.amazonaws.com/onboarding/v1/levelfour-preflight.sh | bash

You'll see only the actual results, one line per check:

Running LevelFour onboarding preflight...

[OK]   Organizations in all-features mode
[OK]   Organizations trusted access for StackSets enabled
[OK]   CloudFormation Organizations access activated
[OK]   Running from management account (123456789012)

Available deployment targets (pick one as TargetOUId in the next step):

  Root: r-abcd  (Root)  -> onboards EVERY account in the organization
  No OUs configured. Use the root ID above to onboard every account.

Preflight complete.

Prefer to inspect the script before running it? Download and review:

curl -fsSL https://cf-templates-1bsphth8u70q9-us-east-1.s3.amazonaws.com/onboarding/v1/levelfour-preflight.sh -o preflight.sh
less preflight.sh
bash preflight.sh

Pick a target ID from the output:

  • The root ID (e.g. r-abcd) onboards every account in your organization in one shot. Use this for the simplest rollout.
  • An OU ID (e.g. ou-abcd-12345678) scopes the rollout to a subset (e.g. start with Non-Production, add Production later by re-running with a different OU).

Step 2 - Deploy the StackSet

Three ways to deploy, in order of friction. Pick the one that fits.

This is the equivalent of the single-account Launch Stack link but deploys a StackSet. Sign in to your management account, then click:

https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/quickcreate?templateURL=https://cf-templates-1bsphth8u70q9-us-east-1.s3.amazonaws.com/onboarding/v1/onboarding-levelfour-stackset-wrapper.template.json&stackName=LevelFour-Onboarding&param_LevelFourHandshakeID=&param_TargetOUId=

Enter the two parameters:

  • LevelFourHandshakeID - the value LevelFour provided
  • TargetOUId - the root ID or OU ID from the preflight output

At the bottom of the page, tick:

I acknowledge that AWS CloudFormation might create IAM resources with custom names.

Click Create stack. CloudFormation provisions the StackSet, which deploys the role to every account under the target. Status reaches CREATE_COMPLETE once all per-account stacks succeed - typically 2–5 minutes for a small target, longer for larger ones.

CloudFormation StackSets console

Use this if you want to see and confirm every StackSet option before clicking Create.

Heads-up - this path covers member accounts only. Creating the StackSet directly from the console (instead of via the Launch Stack wrapper template) deploys the role only to accounts under your target OU/root. AWS Organizations excludes the management account from SERVICE_MANAGED StackSet targeting, and there's no inline role to fill that gap on this path. To complete onboarding, you'll need to also run the single-account flow once in the management account, using the same handshake ID. If you'd rather have everything in one deploy, use the Launch Stack flow.

  1. Console → CloudFormationStackSetsCreate StackSet

  2. PermissionsPermission model: Service-managed permissions

  3. Prerequisite - Prepare templatePrepare template: Template is ready

  4. Specify templateTemplate source: Amazon S3 URL → paste:

    https://cf-templates-1bsphth8u70q9-us-east-1.s3.amazonaws.com/onboarding/v1/onboarding-levelfour-cloudformation-template.json

    Click Next.

  5. Specify StackSet details:

    • StackSet name: LevelFour-Onboarding
    • Parameters → LevelFourHandshakeID: your handshake value

    Click Next.

  6. Configure StackSet options:

    • Tags: leave empty (optional)
    • Execution configuration → Managed execution: leave Inactive (default - fine for a one-shot onboarding deploy; "Active" only matters if you'll run concurrent StackSet operations)
    • Capabilities: tick I acknowledge that AWS CloudFormation might create IAM resources with custom names

    Click Next.

  7. Set deployment options:

    • Add stacks to stack set: Deploy new stacks (default)
    • Deployment targets:
      • If you're onboarding the whole organization, pick Deploy to organization. No OU ID input needed - AWS targets every member account under the root.
      • If you're scoping to a specific OU, pick Deploy to organizational units (OUs) and paste the OU ID from the preflight.
    • Auto-deployment options:
      • Automatic deployment: Activated
      • Account removal behavior: Delete stacks
      • Stack set dependencies: leave empty
    • Specify Regions: from the dropdown, add US East (N. Virginia) us-east-1 only. IAM is global, so one region is enough.
    • Deployment options: leave the defaults (Maximum concurrent accounts = 1, Failure tolerance = 0, Region concurrency = Sequential, Concurrency mode = Strict failure tolerance). For orgs with 100+ accounts where the rollout takes long, you can raise concurrency here - but the defaults are safest.

    Click Next.

  8. Review: scan everything for sanity, then click Submit.

  9. Deploy the role to the management account - go through the single-account flow once in the management account with the same handshake ID. Skip this only if you don't need LevelFour to call organizations:ListAccounts from your management account (rare).

AWS CLI

For IaC-first teams.

Same heads-up as the console path. The commands below only cover member accounts. To onboard the management account, deploy the per-account template once there with the same handshake - either via the single-account flow or with aws cloudformation create-stack against the same TemplateURL. Or use the Launch Stack wrapper, which handles both in one deploy.

aws cloudformation create-stack-set \
  --stack-set-name LevelFour-Onboarding \
  --template-url https://cf-templates-1bsphth8u70q9-us-east-1.s3.amazonaws.com/onboarding/v1/onboarding-levelfour-cloudformation-template.json \
  --permission-model SERVICE_MANAGED \
  --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters ParameterKey=LevelFourHandshakeID,ParameterValue=<YOUR_HANDSHAKE_ID>

aws cloudformation create-stack-instances \
  --stack-set-name LevelFour-Onboarding \
  --deployment-targets OrganizationalUnitIds=<YOUR_ROOT_OR_OU_ID> \
  --regions us-east-1

aws cloudformation create-stack \
  --stack-name LevelFour-ManagementAccount \
  --template-url https://cf-templates-1bsphth8u70q9-us-east-1.s3.amazonaws.com/onboarding/v1/onboarding-levelfour-cloudformation-template.json \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters ParameterKey=LevelFourHandshakeID,ParameterValue=<YOUR_HANDSHAKE_ID> \
  --region us-east-1

Step 3 - Tell LevelFour you're done

Send your LevelFour onboarding contact your management account ID. LevelFour already has your handshake; it uses that to assume the role in your account, enumerates every active member account via AWS Organizations, synthesizes the deterministic role ARN (arn:aws:iam::<account_id>:role/LevelFourCrossAccountRole) for each, verifies the role works, and populates your tenant. You don't need to copy ARNs back to us.

Three ways to grab the info you need, in order of friction.

In AWS CloudShell signed in to your management account:

curl -fsSL https://cf-templates-1bsphth8u70q9-us-east-1.s3.amazonaws.com/onboarding/v1/levelfour-handoff.sh | bash

It auto-detects your wrapper stack, prints the stack outputs, and then a single combined table of every active organization account with its LevelFour role status - so you can copy the whole picture into your reply:

Wrapper stack outputs:
-----------------------------------------------------------
| Output                | Value                           |
|-----------------------|---------------------------------|
| ManagementAccountId   | 123456789012                    |
| DeploymentTarget      | r-abcd                          |
| StackSetName          | LevelFour-Onboarding            |
| RoleNameInEachAccount | LevelFourCrossAccountRole       |
-----------------------------------------------------------

Active organization accounts and their LevelFour role status:

  Account ID      Name                              Role Status
  --------------  --------------------------------  ---------------
  123456789012    Org (management)                  CURRENT
  234567890123    Prod                              CURRENT
  345678901234    Staging                           CURRENT
  456789012345    Dev                               CURRENT

================ Send this to LevelFour ================
  ManagementAccountId : 123456789012
  Active accounts     : 4
  Role deployed to    : 4 of 4
========================================================

If any account isn't CURRENT, the script flags it and explains the common causes (management account missing on older deploys, SCP block).

CloudFormation console

The console doesn't surface the full account list in one place - CloudFormation outputs are stack-level only, and aggregating AWS Organizations data would require a custom Lambda resource we deliberately don't ship. You'll need three short stops:

Stop 1 - Wrapper stack outputs. Open the wrapper stack (LevelFour-Onboarding) → Outputs tab:

OutputWhat it is
ManagementAccountIdYour AWS Organizations management account ID - this is the value to send LevelFour
DeploymentTargetThe root ID or OU ID you deployed to (root = every account)
StackSetNameLevelFour-Onboarding - useful if you ever need to manage the StackSet later
RoleNameInEachAccountLevelFourCrossAccountRole - the deterministic role name in every targeted account

Stop 2 - Member account rollout status. CloudFormation → StackSetsLevelFour-OnboardingStack instances tab. One row per member account. Every row should show Status: CURRENT. (The management account is not in this table - it's covered by the inline LevelFourCrossAccountRole resource on the wrapper stack itself, which is already in CREATE_COMPLETE if you got this far.)

Stop 3 - All organization accounts. AWS Organizations console → Accounts. Cross-reference these with the StackSet's Stack instances table - every active account should be either a row in Stop 2 (member, rolled out via StackSet) or the management account (covered by the wrapper).

If you want the combined view in one place - wrapper outputs + every account joined with role status, with an explicit "Send this to LevelFour" summary - use the Handoff one-liner instead. It does Stops 1-3 in a single command.

AWS CLI (raw)

Three commands give you the same data the handoff script consolidates:

aws cloudformation describe-stacks \
  --stack-name LevelFour-Onboarding \
  --region us-east-1 \
  --query 'Stacks[0].Outputs[].[OutputKey,OutputValue]' \
  --output table

aws cloudformation list-stack-instances \
  --stack-set-name LevelFour-Onboarding \
  --region us-east-1 \
  --query 'Summaries[].[Account,Region,Status]' \
  --output table

aws organizations list-accounts \
  --query 'Accounts[?Status==`ACTIVE`].[Id,Name]' \
  --output table
  • The first command prints the wrapper stack outputs (your ManagementAccountId lives there).
  • The second prints per-member-account rollout status from the StackSet - every row should show Status: CURRENT. Any account in a FAILED or INOPERABLE state needs a per-account look (usually an SCP block; see Troubleshooting below).
  • The third prints every active account in your organization, including the management account which is never in the StackSet's stack-instance list (it's covered by the inline LevelFourCrossAccountRole resource on the wrapper stack itself, which is already in CREATE_COMPLETE).

To recover the unified view that the handoff script prints automatically, cross-reference the second and third tables: every active account ID from the third table should appear in the second table with Status: CURRENT, except the management account ID - which is "deployed" by virtue of the wrapper stack being in CREATE_COMPLETE.

Verifying a specific account

Each member account's CloudFormation console shows its own stack with Outputs.RoleArn exposed - the same Outputs you'd see on the single-account path. If you want to manually confirm an account was reached, sign into that account, open CloudFormation → Stacks, find the stack named StackSet-LevelFour-Onboarding-..., and check its Outputs.

What happens when new accounts join your organization

Because AutoDeployment is enabled, CloudFormation automatically deploys the role to any new account that joins your target. LevelFour runs a periodic re-sync (typically daily) to pick up these new accounts and add them to your tenant.

Removing access

To revoke LevelFour's access across all accounts, delete the wrapper stack from the management account. CloudFormation will tear down the StackSet, which removes the role from every member account.

aws cloudformation delete-stack --stack-name LevelFour-Onboarding

To remove access from a single account, move that account out of the targeted OU - CloudFormation auto-removes the role when the account leaves.

Troubleshooting

StackSet OPERATION_FAILED for one account, others succeeded Open the StackSet → Operations → click the failed operation → review the per-instance error. Most common causes:

  • An SCP on that account's OU denies iam:CreateRole
  • The account is suspended (Status != ACTIVE in Organizations)
  • A role named LevelFourCrossAccountRole already exists in that account from a previous single-account deploy - delete the old role, then retry

Deploy fails with "You must enable organizations access to operate a service managed stack set" You enabled Organizations-side trusted access but not the CloudFormation-side toggle. These are separate per-region settings. Run aws cloudformation activate-organizations-access --region us-east-1 and retry the StackSet deployment. Re-running the preflight script will confirm both sides are on.

Upgrading from an older wrapper (management account shows NOT_DEPLOYED) Wrapper templates published before May 2026 didn't create the LevelFour role in your AWS Organizations management account - they only covered member accounts via the StackSet. If your handoff script shows the management account row as NOT_DEPLOYED and every other row is CURRENT, you're on an older wrapper.

To upgrade in place:

  1. Open the CloudFormation console → Stacks → click your wrapper stack (default name LevelFour-Onboarding)
  2. Stack actionsUpdate stack
  3. Replace current templateAmazon S3 URL, paste:
    https://cf-templates-1bsphth8u70q9-us-east-1.s3.amazonaws.com/onboarding/v1/onboarding-levelfour-stackset-wrapper.template.json
  4. Click through. Your existing parameters carry over - leave them as is.
  5. Tick the IAM acknowledgement → Update stack

The update is non-destructive for member accounts (the StackSet is untouched). It just adds the inline IAM role for the management account. After UPDATE_COMPLETE, re-run the handoff script - the management account row should show CURRENT.

Trusted access keeps showing as disabled even after I enabled it Wait 30 seconds for the change to propagate and refresh the page. If it still shows disabled, you may have enabled it in a different organization - confirm the account selector matches your management account.

The Launch Stack link opens but the parameters are blank That's expected - the URL leaves LevelFourHandshakeID and TargetOUId blank for you to fill in. Paste the handshake LevelFour provided and the target ID (root or OU) from the preflight output.

New accounts aren't getting the role Confirm the new account is in the OU you targeted (not the root, unless you targeted the root). It can take a few minutes for AWS to propagate. If still missing after 30 minutes, check the StackSet's Stack instances tab for the account ID.

LevelFour says it can't find an account I know I onboarded The account is likely suspended in Organizations, which causes organizations:ListAccounts to skip it. Re-activate the account and let LevelFour's re-sync pick it up - typically within 24 hours, or ask your LevelFour contact to trigger a manual sync.