{"id":13602704,"url":"https://github.com/org-formation/org-formation-cli","last_synced_at":"2025-05-13T22:06:36.712Z","repository":{"id":37101140,"uuid":"203860656","full_name":"org-formation/org-formation-cli","owner":"org-formation","description":"Better than landingzones!","archived":false,"fork":false,"pushed_at":"2025-03-15T10:55:47.000Z","size":37086,"stargazers_count":1458,"open_issues_count":96,"forks_count":134,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-05-07T00:03:58.480Z","etag":null,"topics":["aws","best-practices","cli","cloudformation","controltower","devops","hacktoberfest","landing-zone","organizations","patterns","tool"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/org-formation.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-22T19:35:41.000Z","updated_at":"2025-05-04T14:45:49.000Z","dependencies_parsed_at":"2024-08-29T11:33:04.242Z","dependency_job_id":"afd7e92d-d63b-45da-b86b-adc8b19acc83","html_url":"https://github.com/org-formation/org-formation-cli","commit_stats":{"total_commits":958,"total_committers":38,"mean_commits":"25.210526315789473","dds":"0.20876826722338204","last_synced_commit":"8c572d005e38a82547481cea39c3598a3213f67b"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/org-formation%2Forg-formation-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/org-formation%2Forg-formation-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/org-formation%2Forg-formation-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/org-formation%2Forg-formation-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/org-formation","download_url":"https://codeload.github.com/org-formation/org-formation-cli/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253919635,"owners_count":21984264,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","best-practices","cli","cloudformation","controltower","devops","hacktoberfest","landing-zone","organizations","patterns","tool"],"created_at":"2024-08-01T18:01:34.606Z","updated_at":"2025-05-13T22:06:31.701Z","avatar_url":"https://github.com/org-formation.png","language":"TypeScript","readme":"# AWS Organization Formation\n\nAWS Organization Formation is an Infrastructure as Code (IaC) tool for AWS Organizations.\n\n## Features\n\nAWS Organization Formation (also: ``org-formation``) has 3 main features:\n\n1. Infrastructure as Code for AWS Organizations:\n[![Infrastructure as Code for AWS Organizations](docs/img/feature-1-update-org.png)](docs/organization-resources.md)\n[Organization resources reference](docs/organization-resources.md) | [Example organization file](examples/organization.yml) | [CLI Reference](docs/cli-reference.md)\n\n\n\u0026nbsp;\n\n2. CloudFormation annotations to provision resources cross account:\n[![CloudFormation annotations to provision resources cross account](docs/img/feature-2-update-stacks.png)](docs/cloudformation-resources.md)\n[Annotated CloudFormation reference](docs/cloudformation-resources.md) | [Examples](examples/) | [CLI Reference](docs/cli-reference.md)\n\n\n\n\u0026nbsp;\n\n\n3. Automation of account creation and resource provisioning:\n[![Automation of account creation and resource provisioning](docs/img/feature-3-perform-tasks.png)](docs/task-files.md)\n[Automation task file reference](docs/task-files.md) | [Example tasks file](examples/organization-tasks.yml) | [CLI Reference](docs/cli-reference.md)\n\n\nWant more? here a [list of 50+ features](docs/features.pdf) 😎😎😎\n\n## Installation\nWith [npm](https://npmjs.org/) installed, run\n```\n\u003e npm install -g aws-organization-formation\n```\n\nYou can now execute the command line program `org-formation`. try:\n\n```\n\u003e org-formation --help\n```\n\n### Docker\n\nIf you choose, you can run org-formation in a docker container:\n\n```sh\n# Set the AWS_PROFILE environment variable and pass it to the container\n\u003e AWS_PROFILE=example\n# Run the container\n\u003e docker run --rm -it -v $HOME/.aws:/root/.aws:ro -v $PWD:/workdir -w /workdir -e AWS_PROFILE orgformation/org-formation-cli\n```\n\nOptional: create an alias for the container:\n\n```sh\n\u003e 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'\n```\n\n## Getting started\n\n💡Need help getting started? [Get some on slack!](https://join.slack.com/t/org-formation/shared_invite/enQtOTA5NjM3Mzc4ODUwLTMxZjYxYzljZTE5YWUzODE2MTNmYjM5NTY5Nzc3MzljNjVlZGQ1ODEzZDgyMWVkMDg3Mzk1ZjQ1ZjM4MDhlOGM)\n\n📖How to set up AWS Organizations? [Off to a great start](./docs/articles/aws-organizations.md)\n\n🎧 Hear about org-formation in [Real-World Serverless podcast #5](https://open.spotify.com/episode/0VPwObFeQ68oImfqW3lIge?si=VNluO9ZaTc-p3cpps6IBQg)\n\n📺 See org-formation in [Mastering AWS Organizations with Infrastructure-As-Code](https://www.youtube.com/watch?v=mLAGHzidHJ0)\n\n\nTo get started you first need an ``org-formation`` template that describes all your Organization resources such as [Accounts](./docs/organization-resources.md#account), [OUs](./docs/organization-resources.md#organizationalunit) and [SCPs](docs/organization-resources.md#servicecontrolpolicy).\n\nAfter [Installation](#installation) you can generate this file using the following command:\n\n```\n\u003e org-formation init organization.yml  --region us-east-1 [--profile org-master-account]\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\nexample output organization.yml file\n\u003c/summary\u003e\n\n```yaml\nAWSTemplateFormatVersion: '2010-09-09-OC'\n\nOrganization:\n  Root:\n    Type: OC::ORG::MasterAccount\n    Properties:\n      AccountName: My Organization Root\n      AccountId: '123123123123'\n      Tags:\n        budget-alarm-threshold: '2500'\n        account-owner-email: my@email.com\n\n  OrganizationRoot:\n    Type: OC::ORG::OrganizationRoot\n    Properties:\n      ServiceControlPolicies:\n        - !Ref RestrictUnusedRegionsSCP\n\n  ProductionAccount:\n    Type: OC::ORG::Account\n    Properties:\n      RootEmail: production@myorg.com\n      AccountName: Production Account\n      Tags:\n        budget-alarm-threshold: '2500'\n        account-owner-email: my@email.com\n\n  DevelopmentAccount:\n    Type: OC::ORG::Account\n    Properties:\n      RootEmail: development@myorg.com\n      AccountName: Development Account\n      Tags:\n        budget-alarm-threshold: '2500'\n        account-owner-email: my@email.com\n\n  DevelopmentOU:\n    Type: OC::ORG::OrganizationalUnit\n    Properties:\n      OrganizationalUnitName: development\n      Accounts:\n        - !Ref DevelopmentAccount\n\n  ProductionOU:\n    Type: OC::ORG::OrganizationalUnit\n    Properties:\n      OrganizationalUnitName: production\n      Accounts:\n        - !Ref ProductionAccount\n\n  RestrictUnusedRegionsSCP:\n    Type: OC::ORG::ServiceControlPolicy\n    Properties:\n      PolicyName: RestrictUnusedRegions\n      Description: Restrict Unused regions\n      PolicyDocument:\n        Version: '2012-10-17'\n        Statement:\n          - Sid: DenyUnsupportedRegions\n            Effect: Deny\n            NotAction:\n              - 'cloudfront:*'\n              - 'iam:*'\n              - 'route53:*'\n              - 'support:*'\n            Resource: '*'\n            Condition:\n              StringNotEquals:\n                'aws:RequestedRegion':\n                  - eu-west-1\n                  - us-east-1\n                  - eu-central-1\n```\n\n\u003c/details\u003e\n\n**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!\n\nYou 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](docs/cli-reference.md)\n\nOnce 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](docs/cloudformation-resources.md).\n\n## Why is this important?\n\nJust 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.\n\nIf you are considering to use an account vending machine (e.g. [AWS Control Tower](https://aws.amazon.com/controltower/)) 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.\n\n\n## Questions and Answers\n\n\u003cdetails\u003e\n\u003csummary\u003e\nMy operation takes a long time to complete / is slow.\n\u003c/summary\u003e\n\u0026nbsp;\n\nEspecially if you have a lot of accounts this can happen.\n\nAn easy way to speed things up is by specifying the command-line argument `--max-concurrent-stacks 10` where 10 is the number of stacks to run in concurrently.\n\nAnother way to speed things up is to run tasks in parallel this can be done with the argument `--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).\n\nOne can add `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.\n\n\u0026nbsp;\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\nIs there a way around having to create new email accounts per account?\n\u003c/summary\u003e\n\u0026nbsp;\n\nEvery AWS account needs a unique root email address, there is no way around this...\n\nWhat you **can do** is to check whether your mail server allows you to append a '+' (plus sign) and another secondary name to your account to create new unique email addresses.\n\nEmail to there addresses will end up in the mailbox assigned to the alias before the plus sign and this will still be considered a valid and unique email address when creating a new AWS Account.\n\n**Example:**\nIf your email address is `name@gmail.com` you will receive email send to `name+awsaccount1@gmail.com` and `name+awsaccount2@gmail.com` to your inbox.\n\nMail servers that support this are gmail, aws workmail and hotmail.\n\n\u0026nbsp;\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\nHow do i set up MFA for the account used by org-formation?\n\u003c/summary\u003e\n\u0026nbsp;\n\n`Org-formation` needs high privilege access to your master account. If you run `org-formation` manually it is wise to set up MFA.\n\nI assume you have credentials set up in `~/.aws/credentials` and this looks like (might well be called `default`):\n``` ini\n[org-formation]\naws_access_key_id = AKIAxxxxxxxxx\naws_secret_access_key = xxxxxxxxxxxxxxxxx\n```\n\nThis allows org-formation to assume the IAM User that corresponds to the access key and secret using the option `--profile org-formation`.\n\nTo enforce MFA you need to do the following:\n1) Assign an MFA device to the IAM User in the console.\n2) Create a role in your master account that has high privileged access and enforces the use of MFA. We call this `MyOrgFormationRole`.\n3) Create a profile that refers to the MyOrgFormation. We call this profile `org-formation-mfa`.\n4) Test whether MFA has been setup correctly by running `org-formation describe-stacks --profile org-formation-mfa`.\n5) If step #4 was successful you can strip the IAM user you use from permissions other than the once it needs to assume `MyOrgFormationRole`.\n\nCode snippets below:\n\n1) Creating the `MyOrgFormationRole` Role (step #2) - execute with CloudFormation\n``` yaml\nAWSTemplateFormatVersion: '2010-09-09'\n\nResources:\n  MyOrgFormationRole:\n    Type: AWS::IAM::Role\n    Properties:\n      RoleName: MyOrgFormationRole\n      ManagedPolicyArns:\n      - 'arn:aws:iam::aws:policy/AdministratorAccess'\n      AssumeRolePolicyDocument:\n        Version: '2012-10-17'\n        Statement:\n        - Effect: Allow\n          Principal:\n            AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'\n          Action: sts:AssumeRole\n          Condition:\n            Bool:\n              aws:MultiFactorAuthPresent: 'true'\n```\n\n2) Creating the profile `org-formation-mfa` (step #3) put in your `~/.aws/config` file.\nReplace `000000000000` with your master account id.\nThe value for `mfa_serial` needs to be the value you got when setting up MFA for your user\n\n``` ini\n[profile org-formation-mfa]\nrole_arn = arn:aws:iam::000000000000:role/MyOrgFormationRole\nsource_profile = org-formation\nmfa_serial = arn:aws:iam::000000000000:mfa/my-user\n```\n\n3) Expected output when executing a command that requires MFA (step 4):\n\n``` bash\n\\\u003e org-formation describe-stacks --profile org-formation-mfa\n👋 Enter MFA code for arn:aws:iam::000000000000:mfa/my-user:\nXXXXXX # here you type in the  put the MFA code\n{ ...regular output } # if successful the command will execute\n```\n\n4) The minimum set of permissions for your user\nReplace `000000000000` with your master account id (or the complete ARN for your Role )\n\n``` yaml\nSid: 'AssumeMFARole'\nAction: 'sts:AssumeRole'\nEffect: 'Allow'\nResource: 'arn:aws:iam::000000000000:role/MyOrgFormationRole'\n```\n\nHope this helps\n\n\u0026nbsp;\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\nWhat is the password of the root user for newly created accounts?\n\u003c/summary\u003e\n\u0026nbsp;\n\nAccounts that are created have a root user but **no password**.\n\nYou can create a password using the 'Forgot password' process using the root email.\n\n**Note:** Once you have created a password and used it consider throwing the password away. You are not supposed to log in using root anyway and storing your password somewhere could only lead to losing it. As we just figured out above you didn't need it in the first place.\n\n**Do bind** an MFA on your root user! Find info under the [IAM service section of the console](https://console.aws.amazon.com/iam/home?/security_credentials#/home)\n\n**Needless to add?** don't use a virtual MFA on the same device that has access to the email account used as RootEmail... this reduces your 'multi-factor' authentication to a single factor 🤔🤣\n\n\u0026nbsp;\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\nWhat happens when I remove an account from the organization.yml?\n\u003c/summary\u003e\n\u0026nbsp;\n\nIf you remove an account from the organization it will not be deleted. Deleting accounts using API calls is not supported by AWS.\n\nAfter running `update` the account that is removed from the organization will not be able to be part of organization bindings.\n\n```\n\\\u003e org-formation update ./examples/organization.yml --profile org-formation\nOC::ORG::Account              | Development4Account           | Forget\nOC::ORG::OrganizationalUnit   | DevelopmentOU                 | Detach Account (Development4Account)\nOC::ORG::OrganizationalUnit   | DevelopmentOU                 | CommitHash\n```\n\nAfter running `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.\n\nObviously: having a task file will do both `update` and `update-stacks` in the right sequence and you're done!\n\nIf you removed and account and want to re-add it:\nJust add it back to the organization.yml. Make sure you run `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.\n\nAs long as the account was not deleted in full `org-formation` will identify it by the `RootEmail` (or `AccountId`) attribute in the organization.yml\n\n\u0026nbsp;\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\nWhat happens when I rename an account (AccountName attribute) in org-formation?\n\u003c/summary\u003e\n\u0026nbsp;\n\nRenaming accounts is not possible using API's. You will have to log into the account as root to change the account name in AWS.\n\nIf you change the AccountName attribute in org-formation this will warn you about the above and will, when resolving references to the account, use the account name from the organization.yml file.\n\n\u0026nbsp;\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\nWhat happens when I rename an account (logical name) in org-formation?\n\u003c/summary\u003e\n\u0026nbsp;\n\nThe logical name, just like with CloudFormation is how you refer to the account from within your templates. The logical account is also used as an identifier within org-formation.\n\nIf you rename an account, by its logical name, org-formation will first notice that the resource by the old logical name has gone and `forget` 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.\n\n\u0026nbsp;\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\nWhy is XYZ not supported?\n\u003c/summary\u003e\n\u0026nbsp;\n\nNo reason other than not running into this use-case so far.\n\nReally happy to implement this based on someone elses use-case.\n\n\u0026nbsp;\n\u003c/details\u003e\n\n\n\n\n## More docs\n\n- [Examples](examples/)\n- [List of 50+ features](docs/features.pdf)\n- [Managing AWS Organizations as code](docs/organization-resources.md)\n- [Organization Annotated CloudFormation](docs/cloudformation-resources.md)\n- [Automating deployments](docs/task-files.md)\n- [Custom Account Creation Workflow](examples/automation/create-account/readme.md)\n- [CLI reference](docs/cli-reference.md)\n- [Changelog](CHANGELOG.md)\n- [Contributing](CONTRIBUTING.md)\n\n## Sponsors \u0026 collaborators\n\nSpecial thanks to the following companies:\n\n\n[![Stedi](./docs/img/stedi.png)](https://www.stedi.com)\n\n[![Moneyou](./docs/img/moneyou.svg)](https://www.moneyou.nl)\n\n[![ChainSlayer](./docs/img/chainslayer.png)](https://www.chainslayer.io/)\n\nSpecial thanks to the following individuals:\n- [Tjerk Stroband](https://github.com/tstroband)\n- [Yan Cui](http://theburningmonk.com)\n- [Eduardo Rodrigues](https://github.com/eduardomourar)\n- [Rene Mulder](https://github.com/rene84)\n- [Khai Do](https://github.com/zaro0508)\n","funding_links":[],"categories":["TypeScript","cli"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forg-formation%2Forg-formation-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forg-formation%2Forg-formation-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forg-formation%2Forg-formation-cli/lists"}