Skip to content

aws-iam: OrganizationPrincipal Expected Organization ID must match regex pattern #33768

@coltenkrauter

Description

@coltenkrauter

Please add your +1 👍 to let us know you have encountered this

Status: IN-PROGRESS

Overview:

Describe the bug

Since version 2.182.0, when running cdk diff and cdk synth, the following error may be seen:

Error: Expected Organization ID must match regex pattern ^o-[a-z0-9]{10,32}$, received ${Token[Default.Id.1217]}
    at new OrganizationPrincipal (/home/runner/work/***/node_modules/aws-cdk-lib/aws-iam/lib/principals.js:1:10361)
    at new Organization (/home/runner/work/***/node_modules/@pepperize/cdk-organizations/src/organization.ts:172:22)
    at new OrganizationStack (/home/runner/work/***/lib/stacks/organization.ts:33:24)
    at new AccountManager (/home/runner/work/***/lib/account-manager.ts:35:3)
    at main (/home/runner/work/***/lib/app.ts:18:3)
    at <anonymous> (/home/runner/work/***/lib/app.ts:26:1)
    at ModuleJob.run (node:internal/modules/esm/module_job:271:25)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:578:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:116:5)

This applies to CDK applications that passes Tokens to new iam.OrganizationPrincipal(orgId). This also applies to CDK applications that uses @pepperize/cdk-organizations.

The error is introduced from #33555. While I understand the purpose for this check,

Workaround:

Please use CDK v2.181.1 as a temporary workaround while the problematic commit gets reverted.

Solution:

No solution yet. Will update when a patch is released.

Related Issues:

#32756


original issue description

Describe the bug

Since upgrading to version 2.183.0, I started seeing this error when running cdk diff. I am using @pepperize/cdk-organizations, but it seems that this is caused by aws-cdk-lib.aws_organizations.

Error: Expected Organization ID must match regex pattern ^o-[a-z0-9]{10,32}$, received ${Token[Default.Id.1217]}
    at new OrganizationPrincipal (/home/runner/work/***/node_modules/aws-cdk-lib/aws-iam/lib/principals.js:1:10361)
    at new Organization (/home/runner/work/***/node_modules/@pepperize/cdk-organizations/src/organization.ts:172:22)
    at new OrganizationStack (/home/runner/work/***/lib/stacks/organization.ts:33:24)
    at new AccountManager (/home/runner/work/***/lib/account-manager.ts:35:3)
    at main (/home/runner/work/***/lib/app.ts:18:3)
    at <anonymous> (/home/runner/work/***/lib/app.ts:26:1)
    at ModuleJob.run (node:internal/modules/esm/module_job:271:25)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:578:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:116:5)

The error appears to be caused by a recent change in AWS CDK that enforces a regex pattern on Organization IDs (#33555). While I understand the purpose for this check,

  1. Is it intended to break when synthesizing as is happening to me?
  2. That it would fail due to a value like ${Token[Default.Id.1217]}?

Let me know if you require more information. I would expect this to be happening to other folks... Unless there is something about my setup that is not ideal.

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Version

2.181.1

Expected Behavior

The recent changes to validating the format of orgId would not break synth or diff commands.

Current Behavior

Getting this error,

Error: Expected Organization ID must match regex pattern ^o-[a-z0-9]{10,32}$, received ${Token[Default.Id.1217]}
    at new OrganizationPrincipal (/home/runner/work/***/node_modules/aws-cdk-lib/aws-iam/lib/principals.js:1:10361)
    at new Organization (/home/runner/work/***/node_modules/@pepperize/cdk-organizations/src/organization.ts:172:22)
    at new OrganizationStack (/home/runner/work/***/lib/stacks/organization.ts:33:24)
    at new AccountManager (/home/runner/work/***/lib/account-manager.ts:35:3)
    at main (/home/runner/work/***/lib/app.ts:18:3)
    at <anonymous> (/home/runner/work/***/lib/app.ts:26:1)
    at ModuleJob.run (node:internal/modules/esm/module_job:271:25)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:578:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:116:5)

Reproduction Steps

If you want SSCCE, I can make a dedicated repo. Otherwise, here is the pertinent code.

import type { StackProps } from 'aws-cdk-lib'
import type { Construct } from 'constructs'

import { Stage } from '@krauters/structures'
import { Account, Organization, OrganizationalUnit } from '@pepperize/cdk-organizations'
import { Stack } from 'aws-cdk-lib'

import type { Organization as OrganizationConfig } from '../structures.js'

export class OrganizationStack extends Stack {
	/**
	 * @param scope The scope which the current resources should be put into.
	 * @param id The id of the parent scope entity.
	 * @param props Properties to configure constructs.
	 */
	constructor(scope: Construct, id: string, props: StackProps) {
		super(scope, id, props)

		const organizationConfig: OrganizationConfig[] = [
			{
				organizationalUnit: 'internal',
				projects: [
					{
						baseUrl: 'example-redacted.com',
						codename: 'example-redacted',
						environments: [Stage.Alpha, Stage.Beta, Stage.Gamma, Stage.Production],
					},
				],
			},
		]

		// Create organization
		const organization = new Organization(this, 'Organization', {})
		let previous: Construct = organization.root

		organizationConfig.forEach((ou) => {
			// Create an organizational unit (OU)
			const organizationUnit = new OrganizationalUnit(this, `OrganizationalUnit${ou.organizationalUnit}`, {
				organizationalUnitName: ou.organizationalUnit,
				parent: organization.root,
			})
			organizationUnit.node.addDependency(previous)
			previous = organizationUnit

			ou.projects.forEach((project) => {
				project.environments.forEach((environment) => {
					let name = `${project.codename}-${environment.toLowerCase()}`

					// eslint-disable-next-line @typescript-eslint/no-unused-expressions
					project.disambiguator && (name += `-${project.disambiguator}`)

					// Create an account
					const account = new Account(this, name, {
						accountName: name,
						email: `example-redacted+${name}@gmail.com`,
						parent: organizationUnit,
					})
					account.node.addDependency(previous)
					previous = account
				})
			})
		})
	}
}


}

Possible Solution

Would it be reasonable to not validate the orgId pattern if it is unresolved token?

Additional Information/Context

No response

CDK CLI Version

2.1003.0 (build b242c23)

Framework Version

2.183.0

Node.js Version

v22.13.1

OS

Mac M1 / Darwin 24.3.0 arm64

Language

TypeScript

Language Version

TypeScript (5.8.2)

Other information

No response

Metadata

Metadata

Assignees

Labels

aws-cdk-libRelated to the aws-cdk-lib packagebugThis issue is a bug.effort/smallSmall work item – less than a day of effortmanagement/trackingIssues that track a subject or multiple issuesp0potential-regressionMarking this issue as a potential regression to be checked by team member

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions