Better than landingzones!
AWS Organization Formation is an Infrastructure as Code (IaC) tool for AWS Organizations.
AWS Organization Formation (also: org-formation
) has 3 main features:
Want more? here a list of 50+ features 😎😎😎
With npm installed, run
> npm install -g aws-organization-formation
You can now execute the command line program org-formation
. try:
> org-formation --help
If you choose, you can run org-formation in a docker container:
# Set the AWS_PROFILE environment variable and pass it to the container
> AWS_PROFILE=example
# Run the container
> docker run --rm -it -v $HOME/.aws:/root/.aws:ro -v $PWD:/workdir -w /workdir -e AWS_PROFILE orgformation/org-formation-cli
Optional: create an alias for the container:
> alias org-formation='docker run --rm -it -v $HOME/.aws:/root/.aws:ro -v $PWD:/workdir -w /workdir -e AWS_PROFILE orgformation/org-formation-cli'
💡Need help getting started? Get some on slack!
📖How to set up AWS Organizations? Off to a great start
🎧 Hear about org-formation in Real-World Serverless podcast #5
📺 See org-formation in Mastering AWS Organizations with Infrastructure-As-Code
To get started you first need an org-formation
template that describes all your Organization resources such as Accounts, OUs and SCPs.
After Installation you can generate this file using the following command:
> org-formation init organization.yml --region us-east-1 [--profile org-master-account]
yaml
AWSTemplateFormatVersion: '2010-09-09-OC'
Organization:
Root:
Type: OC::ORG::MasterAccount
Properties:
AccountName: My Organization Root
AccountId: '123123123123'
Tags:
budget-alarm-threshold: '2500'
account-owner-email: my@email.com
OrganizationRoot:
Type: OC::ORG::OrganizationRoot
Properties:
ServiceControlPolicies:
- !Ref RestrictUnusedRegionsSCP
ProductionAccount:
Type: OC::ORG::Account
Properties:
RootEmail: production@myorg.com
AccountName: Production Account
Tags:
budget-alarm-threshold: '2500'
account-owner-email: my@email.com
DevelopmentAccount:
Type: OC::ORG::Account
Properties:
RootEmail: development@myorg.com
AccountName: Development Account
Tags:
budget-alarm-threshold: '2500'
account-owner-email: my@email.com
DevelopmentOU:
Type: OC::ORG::OrganizationalUnit
Properties:
OrganizationalUnitName: development
Accounts:
- !Ref DevelopmentAccount
ProductionOU:
Type: OC::ORG::OrganizationalUnit
Properties:
OrganizationalUnitName: production
Accounts:
- !Ref ProductionAccount
RestrictUnusedRegionsSCP:
Type: OC::ORG::ServiceControlPolicy
Properties:
PolicyName: RestrictUnusedRegions
Description: Restrict Unused regions
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: DenyUnsupportedRegions
Effect: Deny
NotAction:
- 'cloudfront:*'
- 'iam:*'
- 'route53:*'
- 'support:*'
Resource: '*'
Condition:
StringNotEquals:
'aws:RequestedRegion':
- eu-west-1
- us-east-1
- eu-central-1
Note: If you prefer to set up CI/CD run org-formation init-pipeline
instead. It will create a CodeCommit repository and CodePipeline that will update your organization upon every commit!
You can make changes to the file you generated and update your organization using the update
command. Alternatively, you can run create-change-set
and update-change-set
. Read more in the cli reference
Once you got the hang of managing organization resources, use these organization resources to write smarter CloudFormation that allows you to provision resources across your organization. Read more about managing resources across accounts.
Just like with the resources within your AWS Account, managing AWS Organization resources as code allows you to apply changes automatically, reducing manual work, inconsistencies and mistakes.
If you are considering to use an account vending machine (e.g. AWS Control Tower) to create and manage new accounts within your organization: Do realize that the account vending machine allows you to quickly create organization resources but only has limited facilities when it comes to updating and maintaining these resources.
--max-concurrent-stacks 10
where 10 is the number of stacks to run in concurrently.--max-concurrent-tasks 10
. This, however, has the side-effect that the logging might be somewhat harder to relate to a specific task (as it might be out of order).MaxConcurrentTasks: 10
to the task directly; for example, for type registration, adding this to the Type: include
task called Types
will ensure multiple types can be registered in parallel.name@gmail.com
you will receive email send to name+awsaccount1@gmail.com
and name+awsaccount2@gmail.com
to your inbox.Org-formation
needs high privilege access to your master account. If you run org-formation
manually it is wise to set up MFA.~/.aws/credentials
and this looks like (might well be called default
):ini
[org-formation]
aws_access_key_id = AKIAxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxx
--profile org-formation
.MyOrgFormationRole
.org-formation-mfa
.org-formation describe-stacks --profile org-formation-mfa
.MyOrgFormationRole
.MyOrgFormationRole
Role (step #2) - execute with CloudFormationyaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
MyOrgFormationRole:
Type: AWS::IAM::Role
Properties:
RoleName: MyOrgFormationRole
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AdministratorAccess'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: sts:AssumeRole
Condition:
Bool:
aws:MultiFactorAuthPresent: 'true'
org-formation-mfa
(step #3) put in your ~/.aws/config
file.000000000000
with your master account id.mfa_serial
needs to be the value you got when setting up MFA for your userini
[profile org-formation-mfa]
role_arn = arn:aws:iam::000000000000:role/MyOrgFormationRole
source_profile = org-formation
mfa_serial = arn:aws:iam::000000000000:mfa/my-user
bash
\> org-formation describe-stacks --profile org-formation-mfa
👋 Enter MFA code for arn:aws:iam::000000000000:mfa/my-user:
XXXXXX # here you type in the put the MFA code
{ ...regular output } # if successful the command will execute
000000000000
with your master account id (or the complete ARN for your Role )yaml
Sid: 'AssumeMFARole'
Action: 'sts:AssumeRole'
Effect: 'Allow'
Resource: 'arn:aws:iam::000000000000:role/MyOrgFormationRole'
update
the account that is removed from the organization will not be able to be part of organization bindings.\> org-formation update ./examples/organization.yml --profile org-formation
OC::ORG::Account | Development4Account | Forget
OC::ORG::OrganizationalUnit | DevelopmentOU | Detach Account (Development4Account)
OC::ORG::OrganizationalUnit | DevelopmentOU | CommitHash
update-stacks
any stack that was deployed to this account using org-formation will be deleted from the target account. Stacks that have been created by other means will not be affected.update
and update-stacks
in the right sequence and you’re done!update
and update-stacks
(or perform-tasks
) and your account will participate in all bindings and the stacks will be re-deployed to the account.org-formation
will identify it by the RootEmail
(or AccountId
) attribute in the organization.ymlforget
it. Later it will discover the new same account by its new logical name and match it with the physical account that already exists in AWS. It will match the two thus completing the rename.Special thanks to the following companies:
Special thanks to the following individuals: