Using Terraform to Up Your Automation Game

As a proponent of automation I am a big fan of using Terraform to deploy infrastructure across my environments.  Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently.  With an ever-growing list of supported providers it is clear that it belongs in our automation toolbox and can be leveraged across local datacenter, IaaS, PaaS and SaaS deployments.  If you come from a VMware background and work with AWS or Azure, like me, I would recommend checking out Nick Colyer's PluralSight course and Yevgeniy Brikman's "Terraform: Up & Running" book / blog posts.  Hopefully this post will entice you to learn more.

Mission

Our mission is to create and deploy a set of auto-scaling web servers, front ended by a load balancer for our development, staging and production environments across 3 different AWS regions.  We will utilize a modular approach to create and build our infrastructure, and reuse our code when possible to keep things simple.

Building A Virtual Private Cloud

Before deploying any instances, we need to create our landing pad which will consist of a dedicated VPC (Virtual Private Cloud) and the necessary subnets, gateways, route tables and other AWS goodies.  The diagram below depicts the development environment to be deployed in the AWS us-west-2 region, including private, public and database subnets across 3 availability zones.

awsvcpdev.png

Terraform allows us to take a modular approach for our deployment by offering self-contained/packaged configurations called modules.  Modules allow us to piece together our infrastructure, and enable the use of reusable components.  Terraform provides a Module Registery of community and verified modules for some of the most common infrastructure configurations.  For our purposes we will leverage the VPC module for AWS.

To begin creating our development VPC, we can create a file called main.tf.  Inside this Terraform file we will add a few lines of declarative code and the AWS provider to attach to the us-west-2 region.  I am hiding my AWS credentials, but you can include them under the AWS provider.

provider "aws" {
  region = "us-west-2"
  access_key = "AWSAccessKeyHere"
  secret_key = "AWSSecretKeyHere"
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "1.37.0"

  name = "dev"

  cidr = "10.0.0.0/16"

  azs             = ["us-west-2a", "us-west-2b", "us-west-2c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
  database_subnets = ["10.0.201.0/24", "10.0.202.0/24"]

  enable_nat_gateway = true
  single_nat_gateway = true

  tags = {
    Owner       = "user"
    Environment = "dev"
  }

  vpc_tags = {
    Name = "dev-environment"
  }
}

We add a few additional lines of code to our main.tf file inserting the VPC module for AWS to define the availability zones, subnets, IP addresses and tags.  You can carve out your subnets as you see fit.  Less then 30 lines of code and we are now ready to initialize and deploy a working VPC for our development envioronment.  You can see why I like Terraform.

Deploying our VPC

To deploy our newly created VPC, we simple need to install Terraform on our computer, initialize and plan the deployment and then apply it.  The download and install of Terraform is very straight forward as it deploys as a single binary.  From the command line browse to the directory that holds your main.tf file, and execute the initialize, plan and apply commands.

terraform init

The first command that should be run after setting up a new Terraform configuration is terraform init.  This command is used to initialize a working directory containing Terraform configuration files, and needs to be run from the same directory that our main.tf file is located.

terraforminit.png
terraform plan

Before deploying our development environment, Terraform provides the ability to run a check to see whether the execution plan matches our expectations for what is to be deployed.  By running the terraform plan command, no changes will be made to the resources or state of our environment.  In our case, there will be 25 additions to our development environment and these created items are detailed in the output of the terraform plan command.

terraformplan1.png
 
terraformplan2.png
terraform apply

Now that everything is initialized and the plan meets our expectation, it is time to deploy.  The terraform apply command is used to apply the changes specified in the execution plan.  You will be prompted to enter 'yes' in order to deploy.  The summary of this command shows that all 25 additions completed.  We now have a working VPC for our development environment.

terraformapply1.png
 
terraformapplycomplete.png

We can confirm that is the case by logging into AWS and viewing our VPC in the us-west-2 region.

awsvpc.png
terraform destroy

One of my favorite uses of Terraform is to quickly turn up an infrastructure environment with only a few lines of code, and conversely tear it down when it is no longer needed.  This is extremely practical when working with cloud providers to keep costs low and maintain a clean environment which is ready for future deployments.  The terraform destroy command does exactly what you would expect - it is used to destroy the managed infrastructure deployed.  In our case we will utilize terraform destroy to tear down our development VPC.  When we are ready to use it again, we simply issue a plan and apply - which is the power of Infrastructure as Code.

terraformdestroy.png
 
terraformdestroycomplete.png

Deploying our Web Servers, Load Balancers and Auto-Scaling Groups

Now that we have a place to put our web servers, it is time to create and deploy them.  We will complete this process in the next post.