Package: pepperize.cdk-organizations
CDK OrganizationsManage AWS organizations, organizational units (OU), accounts and service control policies (SCP).Features:OrganizationOrganizational Unit (OU)AccountDelegated AdministratorTrusted ServicePolicies,PolicyTypes,PolicyAttachmentTaggingInstallTypeScriptnpminstall@pepperize/cdk-organizationsoryarnadd@pepperize/cdk-organizationsPythonpipinstallpepperize.cdk-organizationsC# / .Netdotnet add package Pepperize.CDK.OrganizationsJava<dependency><groupId>com.pepperize</groupId><artifactId>cdk-organizations</artifactId><version>${cdkOrganizations.version}</version></dependency>ContributingContributions of all kinds are welcome :rocket: Check out ourcontributor's guide.For a quick start,check outa development environment:gitclonegit@github.com:pepperize/cdk-organizationscdcdk-organizations# install dependenciesyarn# build with projenyarnbuildGetting StartedCreate a new accountSignup for AWSPrepare an IAM User withAdministratorAccessTo deploy your new organization, you have to create an Administrator with an AccessKeyCreating your first IAM admin user and user groupManaging access keys for IAM usersCreate a new CDK TypeScript App project withprojenmkdirmy-projectcdmy-project
gitinit-bmain
npxprojennewawscdk-app-tsAdd@pepperize/cdk-organizationsto your dependencies in.projenrc.jsconstproject=newawscdk.AwsCdkTypeScriptApp({//...deps:["@pepperize/cdk-organizations"],});Install the dependencynpxprojenCreate a stackimport{Account,Organization,OrganizationalUnit}from"@pepperize/cdk-organizations";import{Stack}from"aws-cdk-lib";exportclassOrganizationStackextendsStack{constructor(scope:Construct,id:string,props:StackProps={}){super(scope,id,props);//Createyourorganizationconstorganization=newOrganization(stack,"Organization",{});//Createanorganizationalunit(OU)constorganizationUnit=newOrganizationalUnit(stack,"OrganizationalUnit",{organizationalUnitName:"MyFirstOU",parent:organization.root,});//Createanaccountconstaccount=newAccount(stack,"Account",{accountName:"MyFirstAccount",email:"<your email for the member account>",parent:organizationUnit,});}}Configure your AWS CLI to deployConfiguring the AWS CLIAWSumeThe easiest is to export your access keyexportAWS_ACCESS_KEY_ID=<yourcreatedaccesskeyid>exportAWS_SECRET_ACCESS_KEY=<yourcreatedsecretaccesskey>Deploy your first AWS organizationexportCDK_DEFAULT_REGION=<yourAWSregion>exportCDK_DEFAULT_ACCOUNT=<yourAWSaccountid>yarndeployUsageOrganizationTo create a new organization or import an existing organization, add the following construct to your stack:constorganization=newOrganization(stack,"Organization",{featureSet:FeatureSet.ALL,//(default)requiredlaterontoenableSCPs,enableAWSservicesordelegateanadministratoraccount});organization.root;//Theorganization's root is automatically createdFeatureSet.ALLis required for advanced features like Service Control Policies (SCP) and is thepreferred way to work with AWS OrganizationsThe account which deploys the stack, will automatically become the management account of the new organization.If an organization already exists, it will be imported automatically. You can disable this behaviour by passingimportOnDuplicate: falsein the props.If the construct is removed from the stack, the organization will remain and must be deleted manually. For deletion of an organization you must previously remove all the member accounts, OUs, and policies from the organization.Deleting the organization by removing the management accountAn organization root is automatically created for you when you create the new organization.SeeIOrganizationOrganization PrincipalTo retrieve the AWS IAM organization principal in a member account, add the following to any construct:const organization = Organization.of(scope, "Organization");
organization.principal; // The AWS IAM organization principalThis helper construct can be used in any member account in the organization.SeeAWS Organization API Reference - DescribeOrganizationOrganizational Unit (OU)To create a new organizational unit (OU), add the following construct to your stack:constorganizationUnit=newOrganizationalUnit(stack,"Organization",{organizationalUnitName:"Project2",parent:organization.root,});The parent of an organizational unit (OU) can be either the organization's root or another OU within the organization.An organizational unit (OU) can't be moved. You have to create a new OU first, move all the accounts and then delete the old OU.For deletion of an organizational unit (OU) you must first move all accounts out of the OU and any child OUs, and then you can delete the child OUs.Deleting an organizational unitSeeIOrganizationalUnitOrganizational Unit (OU) PropertiesimportOnDuplicateIf an organizational unit (OU) with the name exists in the parent, it will be imported.removalPolicyDefaultRemovalPolicy.RetainIf you setremovalPolicytoRemovalPolicy.destroy, the organizational unit (OU) will be deleted on Cloudformation delete event.SeeOrganizationalUnitPropsAccountTo create a new account, add the following construct to your stack:newAccount(stack,"Account",{accountName:"MyAccount",email:"info@pepperize.com",parent:organization.root,});The email address must not already be associated with another AWS account. You may suffix the email address, i.e.info+account-123456789012@pepperize.com.The AWS Organizations supports only a one account creationIN_PROGRESS. Ensure account creation by usingaccount2.node.addDependency(account1)dependency relationship.An account will be created and moved to the parent, if the parent is an organizational unit (OU).An account can only be created from within the management account.SeeIAccountAccount PropertiesimportOnDuplicateIf an account with the same email address exists in the organization, it will be imported.removalPolicyDefaultRemovalPolicy.RetainIf you setremovalPolicytoRemovalPolicy.destroy, the account will be closed.Closing an AWS accountiamUserAccessToBillingDefaultIamUserAccessToBilling.ALLOWIf you setiamUserAccessToBillingtoALLOW, IAM users and roles that have appropriate permissions can view billing information for the account.roleNameDefaultOrganizationAccountAccessRoleis preconfigures in the newly created account and grants users in the management account administrator permissions in the new member account.SeeAccountPropsDelegated AdministratorA compatible AWS service (trusted service) can register an AWS member account in the organization as an administrator in the organization on your behalf. To enable an AWS account as administrator of that trusted in your organization calldelegateAdministratoron your account:constaccount=newAccount(stack,"Account",{accountName:"StackSetsDelegatedAdministrator",email:"info@pepperize.com",});account.delegateAdministrator("stacksets.amazonaws.com");AWS services that support Delegated AdministratorTo be able to use Delegated Administrator, your organization must haveall featuresenabled.SeeDelegatedAdministratorEnable an AWS Service (trusted service)To enable trusted access for a supported AWS service (trusted service), which performs tasks in your organization and its accounts on your behalf, callenableAwsServiceon your organization:constorganization=newOrganization(stack,"Organization",{featureSet:FeatureSet.ALL,//(default)theorganizationmustbecreatedwithallfeaturesenabled});organization.enableAwsServiceAccess("ssm.amazonaws.com");To enable trusted access, you must haveall featuresenabled.It's recommended to use only the trusted service's consoleHow to enable or disable trusted accessAWS services that you can use with AWS OrganizationsSeeEnableAwsServiceAccessEnable a Policy TypeTo enable a policy type callenablePolicyTypeon your organization.constorganization=newOrganization(stack,"Organization",{featureSet:FeatureSet.ALL,//(default)theorganizationmustbecreatedwithallfeaturesenabled});organization.enablePolicyType(PolicyType.SERVICE_CONTROL_POLICY);organization.enablePolicyType(PolicyType.TAG_POLICY);organization.enablePolicyType(PolicyType.BACKUP_POLICY);organization.enablePolicyType(PolicyType.AISERVICES_OPT_OUT_POLICY);To create or attach policies later on, you have toenable all featuresand thepolicy type.SeeEnablePolicyType,PolicyType.PolicyTo create a new policy add the following construct to your stack:newPolicy(stack,"Policy",{content:'{\n"Version":"2012-10-17","Statement":{\n"Effect":"Allow","Action":"s3:*"\n}\n}',description:"Enables admins of attached accounts to delegate all S3 permissions",policyName:"AllowAllS3Actions",policyType:PolicyType.SERVICE_CONTROL_POLICY,});To create or attach policies, you must haveall featuresand thepolicy typeenabled.TheSCP Syntaxis quite similar to IAM policies, but way more limited.SeePolicyPolicyAttachmentTo attach a policy to a root, an organizational unit (OU), or an individual account callattachPolicywith the policy to attach:organization.enablePolicyType(PolicyType.TAG_POLICY);constpolicy=newPolicy(stack,"Policy",{content:'{\n"tags":{\n"CostCenter":{\n"tag_key":{\n"@@assign":"CostCenter"\n}\n}\n}\n}',description:"Defines the CostCenter tag key",policyName:"CostCenterTag",policyType:PolicyType.TAG_POLICY,});organization.attachPolicy(policy);organizationalUnit.attachPolicy(policy);account.attachPolicy(policy);To create or attach policies, you must haveall featuresand thepolicy typeenabled.Tagging resourcesTo tag a resource you may follow theAWS CDK Developer Guide - Tagging:You can add one or more tags to the following resources in AWS Organizations.AccountOrganization rootOrganizational unit (OU)PolicySeeTagging AWS Organizations resources,ITaggableResourceTagging an organization's rootimport{Tags}from"aws-cdk-lib";constorganization=newOrganization();Tags.of(organization.root).add("key","value");Tagging an organizational unit (OU)import{Tags}from"aws-cdk-lib";constorganizationalUnit=newOrganizationalUnit();Tags.of(organizationalUnit).add("key","value");Tagging an accountimport{Tags}from"aws-cdk-lib";constaccount=newAccount();Tags.of(account).add("key","value");Tagging a policyimport{Tags}from"aws-cdk-lib";constpolicy=newPolicy();Tags.of(policy).add("key","value");LimitationsAWS Organizations has some limitations:The stack's account must be the management account of an existing organization.The stack's account becomes the management account of the new organization.An account belongs to only one organization within a single root.Quotas for AWS OrganizationsAWS Organizations is a global service with service endpoints inus-east-1,us-gov-west-1andcn-northwest-1. Read alsoEndpoint to call When using the AWS CLI or the AWS SDK.
Currently all custom resources of this library are hard set to useus-east-1.ExampleSeeexampleimport{App,Stack}from"aws-cdk-lib/core";import{Account,DelegatedAdministrator,EnableAwsServiceAccess,EnablePolicyType,FeatureSet,IamUserAccessToBilling,Organization,OrganizationalUnit,Policy,PolicyAttachment,PolicyType,}from"@pepperize/cdk-organizations";constapp=newApp();conststack=newStack(app);//Createanorganizationconstorganization=newOrganization(stack,"Organization",{featureSet:FeatureSet.ALL,});//EnableAWSServiceAccess(requiresFeatureSet:ALL)organization.enableAwsServiceAccess("service-abbreviation.amazonaws.com");//Createanaccountconstaccount1=newAccount(stack,"SharedAccount",{accountName:"SharedAccount",email:"info+shared-account@pepperize.com",roleName:"OrganizationAccountAccessRole",iamUserAccessToBilling:IamUserAccessToBilling.ALLOW,parent:organization.root,});//Enableadelegatedadminaccountaccount1.delegateAdministrator("service-abbreviation.amazonaws.com");//CreateanOUinthecurrentorganizationsrootconstprojects=newOrganizationalUnit(stack,"ProjectsOU",{organizationalUnitName:"Projects",parent:organization.root,});constaccount2=newAccount(stack,"Project1Account",{accountName:"SharedAccount",email:"info+project1@pepperize.com",parent:projects,});account2.node.addDependency(account1);//CreateanestedOUandattachtwoaccountsconstproject2=newOrganizationalUnit(stack,"Project2OU",{organizationalUnitName:"Project2",parent:projects,});constaccount3=newAccount(stack,"Project2DevAccount",{accountName:"Project 2 Dev",email:"info+project2-dev@pepperize.com",parent:project2,});account3.node.addDependency(account2);constaccount4=newAccount(stack,"Project2ProdAccount",{accountName:"Project 2 Prod",email:"info+project2-prod@pepperize.com",parent:project2,});account4.node.addDependency(account3);//Enabletheservicecontrolpolicy(SCP)typewithintheorganizationorganization.enablePolicyType(PolicyType.SERVICE_CONTROL_POLICY);//CreateandattachandServiceControlPolicy(SCP)constpolicy=newPolicy(stack,"Policy",{content:'{\n"Version":"2012-10-17","Statement":{\n"Effect":"Allow","Action":"s3:*"\n}\n}',description:"Enables admins of attached accounts to delegate all S3 permissions",policyName:"AllowAllS3Actions",policyType:PolicyType.SERVICE_CONTROL_POLICY,});organization.attachPolicy(policy);//TaggingAWSorganizationresourcesofthisstackTags.of(stack).add("tagKey","tagValue");ReferencesCDK Organizations API ReferenceAWS Account Management Reference GuideAWS Organizations User GuideAWS API ReferenceAWS CDK Custom ResourcesAlternativesAWS Bootstrap KitTerraform AWS ProviderAWS Deployment Framework (ADF)AWS Organization FormationAWS Control Tower Account Factory for Terraform (ATF)