AWS Organizations and Control Tower¶
discover_organization(session, control_tower=True, home_region=None) (blocking, read-only):
sts:GetCallerIdentity(caller account),organizations:DescribeOrganization(ID, ARN, management account, feature set). Failure raisesRuntimeError: the caller is not in an organization or lacks access.ListRoots; for each root, a recursive walk withListAccountsForParentandListOrganizationalUnitsForParent, recording every account's parent and OU path.- Policies of each policy type enabled on the root (
ListPolicies,ListTargetsForPolicy). - Trusted service access (
ListAWSServiceAccessForOrganization) and delegated administrators for the security services (ListDelegatedAdministrators); an access denial stops that loop. - With
control_tower,discover_control_tower()probes regions in order (the hint, the session region, then the usual home regions) withcontroltower:ListLandingZones. On the first landing zone:GetLandingZone(the manifest is parsed for governed regions and shared accounts, both the 3.x and 4.x layouts, and then dropped),ListEnabledControls(falling back to per-OU queries on older API revisions) andListEnabledBaselines.
Account selection happens in OrganizationTopology.target_accounts(); the mapper wires it to
aws.organization (step 2). The map nodes come from
organization_assets.topology_assets()
(reference).
Permissions: run from the management account or a delegated administrator for Organizations
(organizations:Describe*, List*; controltower:List*, Get*). Member accounts need a role
cloudg can assume; the default AWSControlTowerExecution has administrator access, so the
recommended setup is a dedicated read-only role (SecurityAudit + ViewOnlyAccess) deployed
to every account with a service-managed StackSet and passed with --org-role.