An Introduction to Terraform

Prabhu Rajendran
Everything at Once
Published in
5 min readSep 8, 2019

About Terraform : With Terminal a few bytes of code and no SSH logins we can spin up in minute , a production ready cluster and a capable of heavy work loads and here it comes “Terraform” — an extremely powerful tool written in “Go” that helps us “writing ,planing and creating stateful reproducible infrastructure as code”.

Terraform by HashiCorp an orchestration tool for “building,changing and versioning infrastructure safely and efficiently” that allows to represent instances and other resources with declarative code inside configuration files.(instead of manually creating those resources).

  1. Write configuration files (.tf) in which we declare the elements or piece of infrastructure that we want to create.
  2. Tell terraform to analyze our created configuration file and then create corresponding infrastructure.

Primary Job of terraform is to create,modify and destroy servers and other resources,can manage existing or popular service providers like custom in house solutions.

  1. Infrastructure as code : Instead of going to provider console and doing manually -Terraform allows something in code. — Minimization of human error,Better collaboration among team members.
  2. Automation of our infrastructure.
  3. Keep our infrastructure in certain state. ( ex : 2 web instances with 2 volumes and 1 load balancer)
  4. Make our infrastructure auditable. (We can keep infrastructure in a version control like Git)
  5. Ansible,Chef,Puppet,Saltstack focus on automating installation the installation and configuration of software (will see why we choose terraform then these software in one part)
  6. Terraform can automate provisioning of infrastructure itself.

Installation Terraform : Download from here! according to machine and unzip downloaded file. That’s it ready for Go!

Step : 1 : Terraform State : Terraform keeps the State of the managed infrastructure and its configuration.

  1. By Default state is stored locally in a JSON formatted file called terraform.state.
  2. What it keeps? from first lift to latest change of our infrastructure’s plan and every chunk of information , to keep track of meta data is saved in the state file.
  3. Bring Benefits to scenarios like versioning,performance monitoring,debugging,rollbacks,rolling updates, immutable deployments,traceability and so on..

Now Let’s see how it works :

  1. Terraform uses the state to create plans , which are representation of the resources which we are deploying and the changes we are applying.
  2. Prior to any operation , a refresh is performed to synchronise the state with the running resources.
  3. state file (terraform.state) contains sensitive information and plays a crucial role in entire management process of our infrastructure.
  4. Now Next question arise? How to store the state? when to store state? and How to secure it ?
  5. What determines how the state is stored and loaded? How do we modify the default behavior? The answer is “Backend”.

Step : 2: Terraform Backend: is an abstraction that determines how the state is handled and way certain operations are executed and enable a number of important features.

  1. Backend — store the state remotely and protects it with lock to prevent corruption.
  2. Better Protection for sensitive data : when the state is retrieved from backend it get stored in memory and never persisted on a local drive.
  3. Remote Operations : For large infrastructure or when pushing specific changes , terraform apply can take quite long time.Normally for the entire duration of the deployment,it is not possible to disconnect the client without compromising its execution.Along with remote state storage and locking, remote operations are a big help for teams and more structured environments.

Step : 3 : Configuration: Backends are configured in Terraform files with the HCL syntax, inside the terraform section. The following simplified snippet shows how a remote backend can be enabled leveraging an AWS s3 bucket, where the terraform.tfstate will persist.

terraform {
backend "s3" {
bucket = "<your_bucket_name>"
key
= "terraform.state"
region
= "<your_aws_region>"
}
}

when configuring a backend rather than default for first time, terraform will provide the option to migrate the current state to new backend , in order to transfer existing data and not losing any information.

It is recommended,though not mandatory, to manually backup the state before initializing any new backend by running “terraform init”.To do that, it is enough to copy the state file outside the scope of the project, in a different folder. The initialisation process should create a backup as well.

Time for coding and demonstrate how to set up a remote backend, with a real life example.

Step : 4: The AWS s3 Backend : Setting up a Terraform backend it is relatively easy. Let’s see how to implement one with AWS s3.
To run the code of the example, be sure to have available AWS IAM credentials with enough permissions to create/ delete s3 buckets and put bucket policies.

# backendstate-store.tfterraform {
backend "s3" {
bucket = "everythingatonce"
key
= "terraform.state"
region
= "ap-south-1"
encrypt
= true
}
}

Once in place, terraform must be initialised (again).terraform init.

What about locking?

Storing the state remotely brings a pitfall, especially when working in scenarios where several tasks, jobs and team members will have access to it. Under these circumstances, the risk of multiple concurrent attempts to make changes to the state, is high. Here comes to help the lock, a feature that prevents the state file to be opened while already in use.

Back to our example, the lock can be implemented by creating an AWS DynamoDB Table, that will be used by terraform to set and unset the locks.

We can create the table resource using terraform itself:

resource "aws_dynamodb_table" "dynamodb-terraform-state-lock" {
name = "terraform-state-lock-dynamo"
hash_key
= "LockID"
read_capacity
= 20
write_capacity = 20
attribute {
name = "LockID"
type
= "S"
}
tags = {
Name = "DynamoDB Terraform State Lock Table"
}
}

and deploy it (terraform apply).

Once the command execution is completed, the locking mechanism must be added to our backend configuration as follow:

terraform {
backend "s3" {
bucket = "everythingatonce"
key
= "terraform.state"
region
= "ap-south-1"
encrypt
= true
dynamodb_table
= "terraform-state-lock-dynamo"
}
}

That’s it we are done now.

In case of queries please feel free to comment!.

Thanks for the time.

--

--