Terraforming on AWS

Terraforming on AWS


5 min read

What is Terraform?

HashiCorp Terraform is an infrastructure-as-code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.


To ensure a smooth start with Terraform on AWS you will need:

  • Active AWS Account

  • Install AWS CLI configured with your credentials

  • Install Terraform

Review the following documents for further information:

Installing Terraform: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli

Getting started with AWS CLI: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html

Overview of Terraform

Terraform reads from configuration files to deploy infrastructure. In order to instruct Terraform what we want it to deploy, we must declare resources as code. Terraform will read all files in the working directory that have a .tf extension and concatenate them together.

Terraform State

  • Terraform maintains infrastructure details in a state file, often named terraform.tfstate. This file guides Terraform in orchestrating changes to your infrastructure, such as modifications, additions, or removals. Before applying any operation, Terraform conducts a refresh to align the current infrastructure, addressing any configuration drifts in resources

Terraform CLI

  • Terraform provides a command line interface (CLI) that can be called with the terraform command once you've installed Terraform. The main commands for Terraform are:

Terraform init

  • Terraform config must be initialized at least once, but you may need to initialize again if you add new providers. After initialization, Terraform creates a hidden .terraform directory for installing plugins and modules.
terraform init

Terraform fmt

  • Used to automatically reformat the code in a consistent style according to the HashiCorp Configuration Language (HCL) style conventions.
terraform fmt

Terraform Validate

  • Used to check and validate the syntax and structure of your Terraform configuration files without actually applying or modifying any infrastructure. This command helps catch syntax errors, typos, and configuration issues early in the development process.
terraform validate

Terraform plan

  • Used to generate an execution plan that describes what actions Terraform will take to achieve the desired state specified in your configuration. It performs a dry run of your Terraform configuration and provides a detailed summary of the changes that will be made to your infrastructure.
terraform plan

Terraform apply

  • Used to apply the changes specified in the Terraform execution plan to your infrastructure. It is a critical step in the Terraform workflow and is used to create, modify, or delete resources according to the desired state defined in your Terraform configuration.
terraform apply

Terraform destroy

  • Used to destroy all the resources defined in your Terraform configuration. It effectively reverses the changes made during the terraform apply process, deleting all the infrastructure resources and leaving no trace of the previously deployed infrastructure.
terraform destroy

Standard Module Structure

Terraform recommends the following file and directory layout as the Standard Module Structure. For more information please visit: https://developer.hashicorp.com/terraform/language/modules/develop/structure

    + main.tf
    + providers.tf
    + outputs.tf
  • Main.tf will contain the core resources and should be considered the primary entry point. For my simple deployment, all of the resources we are creating will reside here. For complex modules, you may split resource creation into multiple files or nested modules.

Example of resources:

resource "aws_vpc" "example" {
  cidr_block = ""
  • Providers.tf - each resource in the configuration must be associated with a provider configuration.

Example of provider:

provider "aws" {
  region = "us-east-1"
  • Outputs.tf contains the outputs which we can specify (i.e ouputting instance public ip)

Example of outputs:

output "instance_tags" {
  value       = aws_instance.this_server.tags
  description = "A mapping of EC2 instance tags"


Today we will be utilizing Terraform to launch the following infrastructure on AWS:

    Size: Small (2,046 Ip's) -
    2 Public Subnets in two different AZ's
    2 Private Subnets in two different AZ's
Internet Gateway
Nat Gateway:
Route Table 1:
    Route 1 - to NAT
Route Table 2
    Route 2 - to IGW
    Public Subnets
    Private Subnets

Visual of VPC / Subnets

Terraforming our Infrastructure as Code

The completed file tree and code: Terraforming Infrastructure

main. tf,



Planning, Applying & Destroying our Infrastructure

terraform plan

terraform apply

  • Checking the Resource Map in the AWS Console

terraform destroy

Conclusion: Embracing Infrastructure as Code

As we wrap up our journey through Terraform on Amazon Web Services (AWS), we've navigated the fundamental aspects of Infrastructure as Code (IaC) utilizing Terraform. We've covered essential topics like terraform state, Terraform CLI, and key commands and launched a Virtual Private Cloud (VPC) with NAT Gateway / Internet Gateway with public and private subnets across two Availability Zones (AZs).

Yet, the Terraform adventure is far from over. There are advanced features such as variables, functions, loops, modules, and more—inviting you to dive deeper. This introduction aims to spark curiosity and serve as a stepping stone into the expansive universe of Terraform.

I hope this journey has ignited your interest in the potent world of Infrastructure as Code. Happy exploring in the ever-evolving landscape of Terraform!