├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .pre-commit-config.yaml ├── LICENSE ├── README.md ├── TALK.md ├── acme-master ├── .envrc ├── common.tfvars ├── eu-central-1 │ ├── ecr-repositories │ │ ├── acme-api │ │ │ └── terragrunt.hcl │ │ └── acme-launcher │ │ │ └── terragrunt.hcl │ └── regional.tfvars ├── eu-west-1 │ ├── regional.tfvars │ └── s3-bucket-artifacts │ │ └── terragrunt.hcl ├── global │ ├── iam-account │ │ └── terragrunt.hcl │ ├── organizations │ │ └── terragrunt.hcl │ └── regional.tfvars └── terragrunt.hcl ├── acme-prod ├── .envrc ├── common.tfvars ├── eu-central-1 │ ├── acm │ │ └── terragrunt.hcl │ ├── alb-security-group │ │ └── terragrunt.hcl │ ├── alb │ │ └── terragrunt.hcl │ ├── aws-data │ │ └── terragrunt.hcl │ ├── regional.tfvars │ └── vpc │ │ └── terragrunt.hcl ├── global │ ├── iam-account │ │ └── terragrunt.hcl │ ├── iam-assumable-roles │ │ └── terragrunt.hcl │ └── regional.tfvars ├── terragrunt.hcl └── us-east-1 │ ├── acm │ └── terragrunt.hcl │ └── regional.tfvars ├── acme-serverless ├── README.md ├── api-gateway │ ├── _extra.tf │ ├── output.txt │ └── terragrunt.hcl ├── lambda │ └── terragrunt.hcl ├── src │ ├── go-function │ │ └── main.go │ └── python-function │ │ └── index.py ├── terragrunt.hcl └── tmp │ ├── api_gateway.tf │ ├── deploy.tf │ ├── lambda_python.tf │ ├── main.tf │ ├── outputs.tf │ └── s3_bucket.tf ├── acme-staging └── README.md └── modules ├── aws-data ├── README.md ├── main.tf └── outputs.tf └── organizations ├── README.md └── main.tf /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | # Uses editorconfig to maintain consistent coding styles 3 | 4 | # top-most EditorConfig file 5 | root = true 6 | 7 | # Unix-style newlines with a newline ending every file 8 | [*] 9 | charset = utf-8 10 | end_of_line = lf 11 | indent_size = 2 12 | indent_style = space 13 | insert_final_newline = true 14 | max_line_length = 80 15 | trim_trailing_whitespace = true 16 | 17 | [*.{tf,tfvars}] 18 | indent_size = 2 19 | indent_style = space 20 | 21 | [*.md] 22 | max_line_length = 0 23 | trim_trailing_whitespace = false 24 | 25 | [Makefile] 26 | tab_width = 2 27 | indent_style = tab 28 | 29 | [COMMIT_EDITMSG] 30 | max_line_length = 0 31 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [antonbabenko] 2 | custom: https://www.paypal.me/antonbabenko 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Terraform 2 | .terraform 3 | .terragrunt-cache 4 | *.tfstate* 5 | crash.log 6 | 7 | # Secrets are not allowed in general 8 | *.key 9 | *.pem 10 | 11 | # Secrets are encrypted using git-crypt 12 | !secrets/* 13 | 14 | # OS X 15 | .history 16 | .DS_Store 17 | 18 | # IntelliJ 19 | .idea_modules 20 | *.iml 21 | *.iws 22 | *.ipr 23 | .idea/ 24 | build/ 25 | */build/ 26 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: git://github.com/antonbabenko/pre-commit-terraform 3 | rev: v1.30.0 4 | hooks: 5 | - id: terraform_fmt 6 | - id: terragrunt_fmt 7 | - id: terraform_docs 8 | - repo: git://github.com/pre-commit/pre-commit-hooks 9 | rev: v2.5.0 10 | hooks: 11 | - id: check-merge-conflict 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Anton Babenko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Acme's Infrastructure - Terragrunt Reference Architecture (updated: May 2020) 2 | 3 | This repository contains rather complete infrastructure configurations where [Terragrunt](https://github.com/gruntwork-io/terragrunt) is used to manage infrastructure for [Acme Corporation](https://en.wikipedia.org/wiki/Acme_Corporation). 4 | 5 | 6 | ### By the way! 7 | 8 | This code is very close to the one produced by [modules.tf](https://modules.tf/) - [open-source](https://github.com/antonbabenko/modules.tf-lambda) infrastructure as code generator from visual diagrams created with [Cloudcraft.co](https://cloudcraft.co/app). See it yourself in [modules.tf-demo](https://github.com/antonbabenko/modules.tf-demo)! 9 | 10 | 11 | ## Introduction 12 | 13 | Acme has several environments (prod, staging and dev) entirely separated by AWS accounts. 14 | 15 | Infrastructure in each environment consists of multiple layers (autoscaling, alb, vpc, ...) where each layer is configured using one of [Terraform AWS modules](https://github.com/terraform-aws-modules/) with arguments specified in `terragrunt.hcl` in layer's directory. 16 | 17 | [Terragrunt](https://github.com/gruntwork-io/terragrunt) is used to work with Terraform configurations which allows orchestrating of dependent layers, update arguments dynamically and keep configurations [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). 18 | 19 | 20 | ## Environments 21 | 22 | Primary AWS region for all environments is `eu-central-1 (Frankfurt)`: 23 | 24 | - `acme-prod` - Production configurations (AWS account - 111111111111) 25 | - `acme-staging` - Staging configurations (AWS account - 444444444444) 26 | - `acme-master` - Master AWS account (333333333333) contains: 27 | 28 | - AWS Organizations 29 | - IAM entities (users, groups) 30 | - ECR repositories 31 | - Route53 zones 32 | 33 | 34 | ## Pre-requirements 35 | 36 | - [Terraform 0.12](https://www.terraform.io/intro/getting-started/install.html) 37 | - [Terragrunt 0.22 or newer](https://terragrunt.gruntwork.io/docs/getting-started/install/) 38 | - [Terraform Docs](https://github.com/segmentio/terraform-docs) 39 | - [pre-commit hooks](http://pre-commit.com) to keep Terraform formatting and documentation up-to-date 40 | - [direnv](https://github.com/direnv/direnv#setup) to automatically set correct environment variables per AWS account as specified in `.envrc` (optional) 41 | 42 | If you are using macOS you can install all dependencies using [Homebrew](https://brew.sh/): 43 | 44 | $ brew install terraform terragrunt pre-commit 45 | 46 | 47 | ## Configure access to AWS account 48 | 49 | Acme has dedicated AWS account where IAM users, groups and roles managed. This AWS account is a jump account, where IAM users logged in, and then they assume role in other AWS account. 50 | 51 | The recommended way to configure access credentials to AWS account is using environment variables: 52 | 53 | ``` 54 | $ export AWS_DEFAULT_REGION=eu-west-1 55 | $ export AWS_ACCESS_KEY_ID=... 56 | $ export AWS_SECRET_ACCESS_KEY=... 57 | ``` 58 | 59 | Alternatively, you can edit `terragrunt.hcl` and use another authentication mechanism as described in [AWS provider documentation](https://www.terraform.io/docs/providers/aws/index.html#authentication). 60 | 61 | 62 | [aws-vault](https://github.com/99designs/aws-vault), [vaulted](https://github.com/miquella/vaulted), [awsp](https://github.com/antonbabenko/awsp) or other tool can be used to manage your AWS credentials securely locally and switch roles. 63 | 64 | 65 | ## Create and manage your infrastructure 66 | 67 | Infrastructure consists of multiple layers (vpc, alb, ...) where each layer is described using one [Terraform module](https://www.terraform.io/docs/configuration/modules.html) with `inputs` arguments specified in `terragrunt.hcl` in respective layer's directory. 68 | 69 | Navigate through layers to review and customize values inside `inputs` block. 70 | 71 | There are two ways to manage infrastructure (slower&complete, or faster&granular): 72 | - **Region as a whole (slower&complete).** Run this command to create infrastructure in all layers in a single region: 73 | 74 | ``` 75 | $ cd acme-prod/eu-central-1 76 | $ terragrunt apply-all 77 | ``` 78 | 79 | - **As a single layer (faster&granular).** Run this command to create infrastructure in a single layer (eg, `vpc`): 80 | 81 | ``` 82 | $ cd acme-prod/eu-central-1/vpc 83 | $ terragrunt apply 84 | ``` 85 | 86 | After you confirm the creation of the infrastructure should succeed. 87 | 88 | If you want to suppress irrelevant output produced by Terragrunt, you can install this alias in your shell ([source to gist](https://gist.github.com/antonbabenko/675049186e54b770b4789886d2056639)): 89 | 90 | terragrunt () { 91 | local action=$1 92 | shift 1 93 | command terragrunt $action "$@" 2>&1 | sed -E "s|$(dirname $(pwd))/||g;s|^\[terragrunt\]( [0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})* ||g;s|(\[.*\]) [0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}|\1|g" 94 | } 95 | 96 | 97 | ## References 98 | 99 | * [Terraform documentation](https://www.terraform.io/docs/) and [Terragrunt documentation](https://terragrunt.gruntwork.io/docs/) for all available commands and features. 100 | * [Terraform AWS modules](https://github.com/terraform-aws-modules/). 101 | * [Terraform modules registry](https://registry.terraform.io/). 102 | 103 | 104 | ## Author 105 | 106 | This project is created and maintained by [Anton Babenko](https://github.com/antonbabenko). 107 | 108 | [![Maintained by Anton Babenko](https://img.shields.io/badge/maintained%20by-@antonbabenko-%235c4ee5.svg)](https://github.com/antonbabenko) [![@antonbabenko](https://img.shields.io/twitter/follow/antonbabenko.svg?style=social&label=Follow%20@antonbabenko%20on%20Twitter)](https://twitter.com/antonbabenko) 109 | 110 | 111 | ## License 112 | 113 | All content, including [Terraform AWS modules](https://github.com/terraform-aws-modules/) used in these configurations, is released under the MIT License. 114 | 115 | Copyright (c) 2019-2020 Anton Babenko 116 | -------------------------------------------------------------------------------- /TALK.md: -------------------------------------------------------------------------------- 1 | # Plan for Terragrunt talk 2 | 3 | 0. Infrastructure as code == Terraform 4 | 1. Intro and use cases - https://github.com/gruntwork-io/terragrunt 5 | 2. Demo: 6 | - sample repos: 7 | - https://github.com/terraform-aws-modules/meta 8 | - https://github.com/antonbabenko/terragrunt-reference-architecture 9 | - https://github.com/antonbabenko/modules.tf-demo 10 | - code structure 11 | - group by logical provider's mental model (AWS = account/region/env/proj) 12 | - group by working area (eg, all AWS Lambda functions inside "lambdas" folder) 13 | - service-provider oriented VS application-oriented approach 14 | 15 | - IAM roles (direnv) 16 | - Terragrunt hooks ( https://github.com/terraform-aws-modules/meta/blob/master/github/terragrunt.hcl#L6 ) 17 | - dependencies 18 | - dependency 19 | - apply-all, plan-all, validate-all 20 | - atlantis / makefile 21 | - pre-commit, terraform-docs 22 | - patterns: 23 | - include files (hierarchy, internal (specific) + high-level (general)) 24 | - modules (local => PR to origin => external repo) 25 | - extend Terragrunt with Terraform (workaround for passing providers or other limits, terraform does not support CLI for providers, for eg) 26 | - use module placeholder to get remote_state benefits 27 | - tfvars = static, but `inputs` in terragrunt.hcl has full support for expressions and functions 28 | - `depends_on` with modules = native `dependency` output with TG 29 | - complains & limitations: 30 | - verbosity in outputs 31 | - multiple providers (possible, but hard) 32 | - for_each with modules 33 | - circular dependencies between modules (eg, AWS Lambda + API Gateway + Permissions) 34 | - lots of various issues and bugs when doing complex things 35 | - terragrunt state 36 | 3. modules.tf 37 | -------------------------------------------------------------------------------- /acme-master/.envrc: -------------------------------------------------------------------------------- 1 | # export TERRAGRUNT_IAM_ROLE="arn:aws:iam::333333333333:role/admin" 2 | -------------------------------------------------------------------------------- /acme-master/common.tfvars: -------------------------------------------------------------------------------- 1 | allowed_account_ids = ["333333333333"] 2 | 3 | common_parameters = { 4 | 5 | domain = "master-domain-for-this-aws-account.com" 6 | 7 | } 8 | -------------------------------------------------------------------------------- /acme-master/eu-central-1/ecr-repositories/acme-api/terragrunt.hcl: -------------------------------------------------------------------------------- 1 | terraform { 2 | source = "git::git@github.com:doingcloudright/terraform-aws-ecr-cross-account.git?ref=1.0.1" 3 | } 4 | 5 | include { 6 | path = find_in_parent_folders() 7 | } 8 | 9 | inputs = { 10 | 11 | use_namespaces = false 12 | 13 | namespace = "" 14 | 15 | name = "acme-api" 16 | 17 | allowed_read_principals = [ 18 | "arn:aws:iam::111111111111:root", # prod 19 | "arn:aws:iam::222222222222:root", # dev 20 | "arn:aws:iam::333333333333:root", # master 21 | "arn:aws:iam::444444444444:root", # staging 22 | ] 23 | 24 | allowed_write_principals = [ 25 | "arn:aws:iam::111111111111:root", # prod 26 | "arn:aws:iam::222222222222:root", # dev 27 | "arn:aws:iam::333333333333:root", # master 28 | "arn:aws:iam::444444444444:root", # staging 29 | ] 30 | 31 | } 32 | -------------------------------------------------------------------------------- /acme-master/eu-central-1/ecr-repositories/acme-launcher/terragrunt.hcl: -------------------------------------------------------------------------------- 1 | terraform { 2 | source = "git::git@github.com:doingcloudright/terraform-aws-ecr-cross-account.git?ref=1.0.1" 3 | } 4 | 5 | include { 6 | path = find_in_parent_folders() 7 | } 8 | 9 | inputs = { 10 | 11 | use_namespaces = false 12 | 13 | namespace = "" 14 | 15 | name = "acme-launcher" 16 | 17 | allowed_read_principals = [ 18 | "arn:aws:iam::111111111111:root", # prod 19 | "arn:aws:iam::222222222222:root", # dev 20 | "arn:aws:iam::333333333333:root", # master 21 | "arn:aws:iam::444444444444:root", # staging 22 | ] 23 | 24 | allowed_write_principals = [ 25 | "arn:aws:iam::111111111111:root", # prod 26 | "arn:aws:iam::222222222222:root", # dev 27 | "arn:aws:iam::333333333333:root", # master 28 | "arn:aws:iam::444444444444:root", # staging 29 | ] 30 | 31 | } 32 | -------------------------------------------------------------------------------- /acme-master/eu-central-1/regional.tfvars: -------------------------------------------------------------------------------- 1 | aws_region = "eu-central-1" 2 | -------------------------------------------------------------------------------- /acme-master/eu-west-1/regional.tfvars: -------------------------------------------------------------------------------- 1 | aws_region = "eu-west-1" 2 | -------------------------------------------------------------------------------- /acme-master/eu-west-1/s3-bucket-artifacts/terragrunt.hcl: -------------------------------------------------------------------------------- 1 | terraform { 2 | source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git?ref=v1.6.0" 3 | } 4 | 5 | include { 6 | path = find_in_parent_folders() 7 | } 8 | 9 | ########################################################### 10 | # View all available inputs for this module: 11 | # https://registry.terraform.io/modules/terraform-aws-modules/s3-bucket/aws/1.6.0?tab=inputs 12 | ########################################################### 13 | inputs = { 14 | 15 | bucket = "main-bucket" 16 | acl = "private" 17 | force_destroy = true 18 | block_public_policy = true 19 | 20 | cors_rule = { 21 | allowed_methods = ["GET"] 22 | allowed_origins = ["*"] 23 | allowed_headers = ["*"] 24 | max_age_seconds = 3000 25 | } 26 | 27 | lifecycle_rule = [ 28 | { 29 | id = "delete-all-ancient" 30 | enabled = true 31 | 32 | expiration = { 33 | days = 365 34 | } 35 | } 36 | ] 37 | 38 | } 39 | -------------------------------------------------------------------------------- /acme-master/global/iam-account/terragrunt.hcl: -------------------------------------------------------------------------------- 1 | terraform { 2 | source = "git::git@github.com:terraform-aws-modules/terraform-aws-iam.git//modules/iam-account?ref=v2.9.0" 3 | } 4 | 5 | include { 6 | path = find_in_parent_folders() 7 | } 8 | 9 | ########################################################### 10 | # View all available inputs for this module: 11 | # https://registry.terraform.io/modules/terraform-aws-modules/iam/aws/2.9.0/submodules/iam-account?tab=inputs 12 | ########################################################### 13 | inputs = { 14 | 15 | account_alias = "acme-master" 16 | 17 | minimum_password_length = 10 18 | 19 | password_reuse_prevention = false 20 | 21 | require_symbols = false 22 | 23 | } 24 | -------------------------------------------------------------------------------- /acme-master/global/organizations/terragrunt.hcl: -------------------------------------------------------------------------------- 1 | terraform { 2 | source = "${get_parent_terragrunt_dir()}/../../modules/organizations" 3 | } 4 | 5 | include { 6 | path = find_in_parent_folders() 7 | } 8 | 9 | 10 | inputs = { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /acme-master/global/regional.tfvars: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /acme-master/terragrunt.hcl: -------------------------------------------------------------------------------- 1 | terraform { 2 | extra_arguments "common_vars" { 3 | commands = get_terraform_commands_that_need_vars() 4 | 5 | required_var_files = [ 6 | find_in_parent_folders("common.tfvars"), 7 | ] 8 | 9 | optional_var_files = [ 10 | find_in_parent_folders("regional.tfvars"), 11 | ] 12 | 13 | } 14 | 15 | extra_arguments "disable_input" { 16 | commands = get_terraform_commands_that_need_input() 17 | arguments = ["-input=false"] 18 | } 19 | } 20 | 21 | generate "main_providers" { 22 | path = "main_providers.tf" 23 | if_exists = "overwrite" 24 | contents = < 6 | ## Requirements 7 | 8 | No requirements. 9 | 10 | ## Providers 11 | 12 | | Name | Version | 13 | |------|---------| 14 | | aws | n/a | 15 | 16 | ## Inputs 17 | 18 | No input. 19 | 20 | ## Outputs 21 | 22 | | Name | Description | 23 | |------|-------------| 24 | | amazon\_linux2\_aws\_ami\_id | AMI ID of Amazon Linux 2 | 25 | | available\_aws\_availability\_zones\_names | A list of the Availability Zone names available to the account | 26 | | available\_aws\_availability\_zones\_zone\_ids | A list of the Availability Zone IDs available to the account | 27 | | aws\_region | Details about selected AWS region | 28 | | ubuntu\_1804\_aws\_ami\_id | AMI ID of Ubuntu 18.04 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /modules/aws-data/main.tf: -------------------------------------------------------------------------------- 1 | data "aws_region" "selected" {} 2 | 3 | data "aws_availability_zones" "available" {} 4 | 5 | data "aws_ami" "ubuntu_1804" { 6 | most_recent = true 7 | owners = ["099720109477"] 8 | 9 | filter { 10 | name = "name" 11 | values = ["ubuntu-minimal/images/*/ubuntu-bionic-18.04-*"] 12 | } 13 | 14 | filter { 15 | name = "virtualization-type" 16 | values = ["hvm"] 17 | } 18 | 19 | filter { 20 | name = "root-device-type" 21 | values = ["ebs"] 22 | } 23 | 24 | filter { 25 | name = "architecture" 26 | values = ["x86_64"] 27 | } 28 | } 29 | 30 | data "aws_ami" "amazon_linux2" { 31 | most_recent = true 32 | owners = ["137112412989"] # Amazon 33 | 34 | filter { 35 | name = "name" 36 | values = ["amzn2-ami-hvm-*"] 37 | } 38 | 39 | filter { 40 | name = "root-device-type" 41 | values = ["ebs"] 42 | } 43 | 44 | filter { 45 | name = "architecture" 46 | values = ["x86_64"] 47 | } 48 | 49 | filter { 50 | name = "virtualization-type" 51 | values = ["hvm"] 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /modules/aws-data/outputs.tf: -------------------------------------------------------------------------------- 1 | output "aws_region" { 2 | description = "Details about selected AWS region" 3 | value = data.aws_region.selected 4 | } 5 | 6 | output "available_aws_availability_zones_names" { 7 | description = "A list of the Availability Zone names available to the account" 8 | value = data.aws_availability_zones.available.names 9 | } 10 | 11 | output "available_aws_availability_zones_zone_ids" { 12 | description = "A list of the Availability Zone IDs available to the account" 13 | value = data.aws_availability_zones.available.zone_ids 14 | } 15 | 16 | output "amazon_linux2_aws_ami_id" { 17 | description = "AMI ID of Amazon Linux 2" 18 | value = data.aws_ami.amazon_linux2.id 19 | } 20 | 21 | output "ubuntu_1804_aws_ami_id" { 22 | description = "AMI ID of Ubuntu 18.04" 23 | value = data.aws_ami.ubuntu_1804.id 24 | } 25 | -------------------------------------------------------------------------------- /modules/organizations/README.md: -------------------------------------------------------------------------------- 1 | # organizations 2 | 3 | This module describes all AWS Organizations resources as-is. Most of this code has been imported from already created resources (before this project started). 4 | 5 | 6 | ## Requirements 7 | 8 | No requirements. 9 | 10 | ## Providers 11 | 12 | | Name | Version | 13 | |------|---------| 14 | | aws | n/a | 15 | 16 | ## Inputs 17 | 18 | | Name | Description | Type | Default | Required | 19 | |------|-------------|------|---------|:--------:| 20 | | feature\_set | Specify 'ALL' (default) or 'CONSOLIDATED\_BILLING'. | `string` | `"ALL"` | no | 21 | 22 | ## Outputs 23 | 24 | | Name | Description | 25 | |------|-------------| 26 | | acme\_prod\_organizations\_account\_arn | The ARN for this account | 27 | | acme\_prod\_organizations\_account\_id | The AWS account id | 28 | | acme\_staging\_organizations\_account\_arn | The ARN for this account | 29 | | acme\_staging\_organizations\_account\_id | The AWS account id | 30 | | this\_organizations\_organization\_arn | ARN of the organization | 31 | | this\_organizations\_organization\_id | Identifier of the organization | 32 | | this\_organizations\_organization\_master\_account\_arn | ARN of the master account | 33 | | this\_organizations\_organization\_master\_account\_email | Email address of the master account | 34 | | this\_organizations\_organization\_master\_account\_id | Identifier of the master account | 35 | 36 | 37 | -------------------------------------------------------------------------------- /modules/organizations/main.tf: -------------------------------------------------------------------------------- 1 | variable "feature_set" { 2 | description = "Specify 'ALL' (default) or 'CONSOLIDATED_BILLING'." 3 | default = "ALL" 4 | } 5 | 6 | resource "aws_organizations_organization" "this" { 7 | feature_set = var.feature_set 8 | } 9 | 10 | output "this_organizations_organization_id" { 11 | description = "Identifier of the organization" 12 | value = aws_organizations_organization.this.id 13 | } 14 | 15 | output "this_organizations_organization_arn" { 16 | description = "ARN of the organization" 17 | value = aws_organizations_organization.this.arn 18 | } 19 | 20 | output "this_organizations_organization_master_account_arn" { 21 | description = "ARN of the master account" 22 | value = aws_organizations_organization.this.master_account_arn 23 | } 24 | 25 | output "this_organizations_organization_master_account_email" { 26 | description = "Email address of the master account" 27 | value = aws_organizations_organization.this.master_account_email 28 | } 29 | 30 | output "this_organizations_organization_master_account_id" { 31 | description = "Identifier of the master account" 32 | value = aws_organizations_organization.this.master_account_id 33 | } 34 | 35 | // acme-prod 36 | resource "aws_organizations_account" "acme_prod" { 37 | name = "acme-prod" 38 | email = "anton+acme-prod@antonbabenko.com" 39 | iam_user_access_to_billing = "ALLOW" 40 | role_name = "admin" 41 | } 42 | 43 | output "acme_prod_organizations_account_id" { 44 | description = "The AWS account id" 45 | value = aws_organizations_account.acme_prod.id 46 | } 47 | 48 | output "acme_prod_organizations_account_arn" { 49 | description = "The ARN for this account" 50 | value = aws_organizations_account.acme_prod.arn 51 | } 52 | 53 | // acme-staging 54 | resource "aws_organizations_account" "acme_staging" { 55 | name = "acme-staging" 56 | email = "anton+acme-prod@antonbabenko.com" 57 | iam_user_access_to_billing = "ALLOW" 58 | role_name = "admin" 59 | } 60 | 61 | output "acme_staging_organizations_account_id" { 62 | description = "The AWS account id" 63 | value = aws_organizations_account.acme_staging.id 64 | } 65 | 66 | output "acme_staging_organizations_account_arn" { 67 | description = "The ARN for this account" 68 | value = aws_organizations_account.acme_staging.arn 69 | } 70 | --------------------------------------------------------------------------------