How to configure AWS Landing Zone in AWS?(Terraform)

Kubernetes Advocate
AVM Consulting Blog
5 min readAug 7, 2022

This Terraform will create the basic landing zone for a startup to begin building on Amazon Web Services (AWS). It will create the following resources:

  • Amazon Virtual Private Cloud (VPC)
  • NAT Gateways
  • Public and private subnets
  • Route tables
  • Tags for AWS resources

What we are creating

Prerequisites

You must have the following ready

  • AWS Access Key ID
  • AWS Secret Access Key
  • Amazon S3 bucket (used to store the Terraform state)
  • At least 2 Elastic IP Address allocation IDs
  1. Let's create AWS Access Key ID and Secret Key
  2. After Access keys are configured please allocate Elastic IP address
  3. Then create an S3 bucket.

Sample Bucket information

Name: [bucket-name] ie. Prod-terraform

Region: ap-southeast-1 (Singapore)

Access: Bucket and objects not public

Encryption: Yes (S3-SSE)

Versioning: ON

Update backend "s3" section

After creating the S3 bucket, you must update the S3 bucket information in environments/[production|development]/main.tf to match the bucket name and region you just created.

Example

terraform {	...backend "s3" {
bucket = "Prod-terraform"
key = "network/prod"
region = "ap-southeast-1"
}
}

The key prefix value

In this example, we instruct Terraform to use a key prefix network/[prod|dev|staging] to organize the Terraform state file. You can change the value to reflect the environment you wish to create. In this example, we will create a dev environment.

For more information on Amazon S3 key prefixes please visit https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-prefixes.html.

Terraform variables

The sample Landing Zone provides the input variable values by using Terraform’s variable definition files.

The Terraform variable file is located at environments/[production|development]/variables.tf. You can initiate the value of the variables in environments/[production|development]/terraform.tfvars.

The following is the list of Terraform’s variables needed to run this script.

aws_availability_zones: List of availability zones

For a production environment, we recommend at least 3 availability zones.

["ap-southeast-1a", "ap-southeast-1b", "ap-southeast-1c"]

For a non-production environment, we can start with 2 availability zones.

["ap-southeast-1a", "ap-southeast-1b"]

aws_elastic_ip_allocation_ids: List of Elastic IP allocation ids and availability zones:

The number of allocation IDs must match the number of availability zones above.

["eipalloc-abc", "eipalloc-def", "eipalloc-ghi"]

aws_region: AWS Region i.e. "ap-southeast-1".

enable_vpc_flow_logs: Enable VPC Flow logs

environment: Environment of this VPC ie d (development), p (production).

product: Product name i.e. website

public_subnet_cidrs: Map of public subnet's CIDRs and availability zone

{
"ap-southeast-1a" = "10.0.0.0/24"
"ap-southeast-1b" = "10.0.1.0/24"
"ap-southeast-1c" = "10.0.2.0/24"
}

private_subnet_cidrs: Map of private subnet's CIDRs and availability zone

{
"ap-southeast-1a" = "10.0.32.0/19"
"ap-southeast-1b" = "10.0.64.0/19"
"ap-southeast-1c" = "10.0.96.0/19"
}

vpc_cidr: VPC's CIDR ie. "10.0.0.0/16"

Environment variables

If you are running the script locally on your machine you will need to set up the following environment variables. Instructions on how to setup environment variables are available at: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html#envvars-set

AWS_ACCESS_KEY_ID: AWS Access Key ID

AWS_SECRET_ACCESS_KEY: AWS Secret Access Key

AWS_DEFAULT_REGION: AWS Region

TF_LOG: Terraform log level i.e. DEBUG or INFO

VPC Configurations

VPC CIDR

CIDR# of hosts10.0.0.0/1665,535

* 5 IP addresses are reserved for each CIDR range. More info.

Public Subnets’ CIDR

Example

Availability ZoneCIDRAvailable hostsap-southeast-1a10.0.0.0/24250ap-southeast-1b10.0.1.0/24250ap-southeast-1c10.0.2.0/24250

For AWS best practices we recommend minimizing the number of AWS services and components available on the public subnet. This will help reduce the attack surface of our network and improve the security posture of the workload. Also, the instances launched into the public subnet will not be assigned public IP addresses.

We should have the following components on the public subnet:

  • Load Balancers
  • Bastion hosts (Jump box)
  • VPN servers

Private Subnet’s CIDR

Example

Availability ZoneCIDRAvailable hostsap-southeast-1a10.0.32.0/198,187ap-southeast-1b10.0.64.0/198,187ap-southeast-1c10.0.96.0/198,187

This is the area where we should have our computing, applications, databases, caches, etc. It is not directly connected to the Internet. All outgoing traffic will go through a NAT Gateway, in addition, components will not have public IP addresses. Communication to AWS services should go through VPC Endpoints to improve security, so traffic will not leave the private network.

NAT Gateways

For the Landing Zone, this will create 3 NAT Gateways as part of the infrastructure. One in each public subnet, and attach the Elastic IP address to each. This allows you to give out these IP addresses to third-party websites or services that required IP addresses for filtering and authorization.

Routes and Route tables

The Terraform template will create 2 new routes in each subnet’s route tables

  1. Public Subnet: Traffic going to the Internet 0.0.0.0/0 will go via the Internet Gateway.
  2. Private Subnet: Traffic going to the Internet 0.0.0.0/0 will go via the NAT Gateway.

Sample Github Workflow and Gitlab CI/CD

The Landing Zone template includes a sample workflow YAML files for GitHub and GitLab CI/CD sample, so you can integrate this with your deployment pipeline.

List of Secrets and Variables

  • AWS_ACCESS_KEY_ID
  • AWS_DEFAULT_REGION: Region of AWS ie. ap-southeast-1. For more information please refer to AWS Regions documentation.
  • AWS_SECRET_ACCESS_KEY
  • TF_LOG: Terraform log level ie. INFO, DEBUG. For more information please refer to Debugging Terraform documentation.

Github Actions

Sample files are in _github/workflows/ the directory.

You need to add the above variables in Settings -> Secrets -> Actions Secrets the section in the repository.

Gitlab CI/CD

The sample file _gitlab-ci.yml is in the root directory of this repository.

You need to add the above variable in Settings -> CI/CD -> Variables the section in the repository. You should also check that these variables are Protected and Masked.

Resource Taggings

This script will create 4 tags.

  1. Component
  2. Environment
  3. Name
  4. Product

Examples

"Component"   = "vpc"
"Environment" = "p"
"Name" = "d-example-vpc"
"Product" = "example"

You can use these tags to monitor your usage and cost by Activating User-Defined Cost Allocation Tags.

How to run

The main directory to run Terraform is in environment/development the directory. Once you change the directory into it and set the environment variables, you can run the following commands:

cd environment/development
terraform init
terraform plan
terraform apply

However, it is recommended to run these commands from the CI/CD pipeline of your choice i.e. GitHub Actions or GitLab CI/CD.

👋 Join us today !!

️Follow us on LinkedIn, Twitter, Facebook, and Instagram

https://avmconsulting.net/

If this post was helpful, please click the clap 👏 button below a few times to show your support! ⬇

--

--

Kubernetes Advocate
AVM Consulting Blog

Vineet Sharma-Founder and CEO of Kubernetes Advocate Tech author, cloud-native architect, and startup advisor.https://in.linkedin.com/in/vineet-sharma-0164