Managing Infrastructure States with Terraform

What is Terraform?

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is an open source tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.

 

Infrastructure States

Using Terraform within a team with more than one deployment environment was once considered problematic. It involved conflicts on deployed versions, changes made by other collaborators that would overwrite your own changes, especially if you did not use Atlas, the Hashicorp paid service.

Managing states across these environments used to be a difficult but recently, some changes have been made around workspaces and remote backends to improve the state management experience.

The infrastructure state concept is a snapshot of what we have already configured and running in our current infrastructure (VPC's, Subnets, Instances, RDS, Volumes, etc).

Having this “snapshot” helps us update our infrastructure, allowing us to run our scripts and only apply the changes we have, enabling idempotence in IT architecture creation.

State Synchronization Issues

Let's say we have a git repo with our terraform scripts. These scripts create a VPC, two subnets, and two instances, one inside each subnet. This git repo has collaborators that can execute a deployment whenever they want.

Screen Shot 2019-06-21 at 3.43.42 PM

The state file should not be stored in git since it is a file that contains sensitive information about our architecture. However, it changes quite often and we need to have a mechanism to manage those changes.

What would happen if two collaborators apply changes to the infrastructure without sharing their state file? We will have infrastructure consistency errors because some changes may be overwritten due to lack of synchronization.

So, what can we do?

The Terraform Approach

In this scenario, Terraform provides us with a remote state feature called backends; this allows us to have an updated state file with every iteration or execution.

But what would happen if you want to test your changes without changing the development, QA or production environment? We could use a simple Terraform tool called workspaces.

Workspaces will allow us to create different environments that will have their own state file and will not block the write over a state file. It will just give us the chance to work with different state files and different stacks.

To work with this configuration, we can attempt an approach using AWS infrastructure:

1. Create an AWS account with S3 access.

2. Create an S3 bucket to save terraform.tfstate files.

YOUR-BUCKET-NAME

3. Once you have created the bucket, you need to configure it to save the terraform state files.

4. Create your main.tf file and your variable.tf file that will have your provider and Bucket definition.
Note: the backend cannot use variables, this is why the region is ‘write down’.

main.tf


provider "aws" {
	region = "${var.region}"
	}
terraform {
	backend "s3" {
    	bucket = "YOUR-BUCKET-NAME"
        key = "terraform.tfstate"
        encrypt = true
        region = "us-west-1"
        }
    }

 

variables.tf


variable "region" {
	default = "us-west-1"
    }
    
variable "environment"{
	default = "dev"
	}

 

5. Initialize your backend:

terraform init -backend-config="access_key=<YOUR ACCESS KEY>"\ -backend-config="secret_key=<YOUR SECRET KEY>"\ -backend-config="region=<REGION TO USE>"\ -backend-config="bucket=YOUR-BUCKET-NAME"\ -backend-config="key=terraform.tfstate"

 

6. Add the workspaces you want to use:


terraform workspace new dev
terraform workspace new prod
terraform workspace new YOUR-WORKSPACE-NAME

 

7. Select the workspace you want to use:

terraform workspace use dev

 

8. Execute your terraform plan with the desired env vars:

terraform plan --var-file="variables_dev.tfvars"

 

9. Execute your terraform apply with the env vars that you want to use:

terraform apply --var-file="variables_dev.tfvars"

 

Terraform workspaces and remote backends look pretty handy so far. Based on this simple example, you can start managing multiple environments within a team. There are additional features, such as the locking of the Terraform state so that multiple people can’t modify the state at the same time. We will cover this in an upcoming post!

Conclusion

Terraform is a free and open source tool created by HashiCorp and written in the Go programming language. It can be used to provision entire infrastructures, ones that span across multiple public and private cloud providers, like AWS, Google Cloud, Digital Ocean, Microsoft Azure, OpenStack, and others.

As a next generation infrastructure orchestration system, Terraform brings a new set of features and functionalities to the table, including immutable infrastructure, declarative/not procedural code, and client-only architecture.

With an immutable infrastructure (state files) approach, Terraform eliminates the common lead to configuration drifts (where differences in configuration lead to bugs) that can be used as exploits and security breaches. With this approach, updating the development environment goes smoothly, making it is easier and less prone to bugs.

Terraform has many more powerful features and is popular due to the wide spectrum of cloud providers it supports. In case you haven’t tried it, it’s worth giving it a shot. Happy Terraforming!

Contact Us

Share this post