Post

Create AWS Organization With Terraform

AWS Account

Image by Arief JR

AWS organizations is an account management service that enables you to consolidate multiple AWS accounts into an organization that you create and centrally manage. AWS Organizations includes account management and consolidated billing capabilities that enable you to better meet the budgetary, security, and compliance needs of your business. As an administrator of an organization, you can create accounts in your organization and invite existing accounts to join the organization. More read AWS Organization

With AWS organizations, we can isolate the environment like development and production. so, the environment is focusses to manage and maintain the resource only in development not mixed with resource for production. The images in above will implementation the AWS organization for each environment (development, staging and production), but in example case will use terraform for create AWS organization units.

1. Enable AccessKey and SecretKeys in AWS root account

For your info, the step to enable or create AccessKey and SecretKay in AWS root account is not recommended and high risk. So, this is only temporary, after which it will be deleted again.

Go to your aws account, select your account then go to security credentials

aws-account

Then create AccessKeys, check i understand then click to create the AccessKeys then you will retrieve the AccessKeys include SecretKeys

aws-root-mfa

2. Setup AWS Cli

To setup awscli adapt to your operating system.

On this step i will not explain to detail how to configure awscli, but you can visit on this site: aws docs

After installed you can run with command:

1
aws configure

In above command input your AccessKeys and SecretKeys has created in early.

3. Terraform (HCL Script)

Prepare the terraform script, create the files like this:

1
2
3
4
5
├── aws-ou.tf
├── providers.tf
└── variables.tf

0 directories, 3 files

Here the script, first create the files with name and copy this script in below:

aws-ou.tf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
locals {
  dev-ou-name = "Development"
  staging-ou-name = "Staging"
  prod-ou-name = "Production"
  manage = "Terraform"
  environment-dev = "development"
  environment-staging = "staging"
  environment-prod = "production"
  env-dev = "tuxnoob-dev"
  env-staging = "tuxnoob-staging"
  env-prod = "tuxnoob-prod"
  organization  = "tuxnoob"
}

resource "aws_organizations_organizational_unit" "tuxnoob-dev" {
  name = "Tuxnoob-Development"
  parent_id = local.root_id
}

resource "aws_organizations_account" "tuxnoob-dev" {
  name  = "development"
  email = "admin+tuxnoob-development@example.com"
  iam_user_access_to_billing = "ALLOW"
  role_name = "tuxnoob"
  parent_id = aws_organizations_organizational_unit.tuxnoob-dev.id
  close_on_deletion = "true"

  tags = {
    Name = local.dev-ou-name
    ManagedBy = local.manage
    Environment = local.environment-dev
    env = local.env-dev
    organization = local.organization
  }
}

resource "aws_organizations_organizational_unit" "tuxnoob-staging" {
  name = "Tuxnoob-Staging"
  parent_id = local.root_id
}

resource "aws_organizations_account" "tuxnoob-staging" {
  name  = "staging"
  email = "admin+tuxnoob-staging@example.com"
  iam_user_access_to_billing = "ALLOW"
  role_name = "tuxnoob"
  parent_id = aws_organizations_organizational_unit.tuxnoob-staging.id
  close_on_deletion = "true"

  tags = {
    Name = local.staging-ou-name
    ManagedBy = local.manage
    Environment = local.environment-staging
    env = local.env-staging
    organization = local.organization
  }
}

resource "aws_organizations_organizational_unit" "tuxnoob-production" {
  name = "Tuxnoob-Production"
  parent_id = local.root_id
}

resource "aws_organizations_account" "tuxnoob-prod" {
  name  = "production"
  email = "admin+tuxnoob-production@example.com"
  iam_user_access_to_billing = "ALLOW"
  role_name = "tuxnoob"
  parent_id = aws_organizations_organizational_unit.tuxnoob-production.id
  close_on_deletion = "true"

  tags = {
    Name = local.prod-ou-name
    ManagedBy = local.manage
    Environment = local.environment-prod
    env = local.env-prod
    organization = local.organization
  }
}

On above terraform script is for create the organization for environment development, staging and production. Then change your email when your registered in AWS Account. Then create a files with name providers.tf, copy this code:

1
2
3
4
5
6
7
8
9
10
provider "aws" {
  shared_credentials_files = var.credentials_file
  profile = var.profile
  region = var.region
}

data "aws_organizations_organization" "root" {}
locals {
  root_id = data.aws_organizations_organization.root.roots[0].id
}

Then create a files with name variables.tf, the variables is use for customize aspect of terraform. like input the region etc.

1
2
3
4
5
6
7
8
9
10
11
12
variable "credentials_file" {
  description = "PATH to credentials file on your local laptop"
  default = ["~/.aws/credentials"]
}
variable "profile" {
  description = "Profile of AWS credential"
  default = "root-tuxnoob"
}
variable "region" {
  description = "AWS Region"
  default = "ap-southeast-1"
}

Makesure you has setup the credentials (AccessKeys and SecretKeys), in default after setup aws cli config will place in $HOME/.aws.

4. Run Terraform (HCL Script)

Run terraform script with command:

1
terraform init && terraform plan

then apply

1
terraform apply -auto-approve

the options -auto-approve it will skip prompt when your apply.

Here the results:

AWS Account

5. Enable AWS Account Management and SCP (Service Control Policies)

Don’t forget to enable this Account Management into your root aws account, go to organization »» services »» select Account Management then click to enable. like this image:

AWS OU Enabled Trust Access

Then type/write enable then click enable

AWS OU Enabled

After that you should enable SCP, if you has enabled this scp will show like this image:

AWS SCP

Full source code: Soon update

Cheers

This post is licensed under CC BY 4.0 by the author.