An overview of DevOps with Terraform

Josué Carvajal
5 min readFeb 2, 2022

--

Have you ever built from scratch your enterprise dev environment? Have you felt that the process of requesting VMs and dev environments must be automated to truly fulfill the DevOps life cycle?

Well, with terraform we are able to achieve it. Terraform is an open-source tool developed by HashiCorp, and it allows us to automate the provisioning of architecture without human interaction, making it easier to set up environments and deprovision them, following the declarative model of IAC (Infrastructure as a code).

Terraform by HashiCorp

But what the heck IAC does do? Basically is the managing and provisioning of infrastructure through code instead of through manual processes and there are different tools with different approaches to achieve this:
- Infraestructure definition: Terraform, Cloud Formation (AWS), Open Stack Heat.
- Server configuration: Ansible, chef, and puppet.

As you can see there are two major parts in the IAC, one is the infrastructure and the server configuration. In this article, we are going to explain the infrastructure definition.

Terraform advantages

Terraform is widely used since it follows a declarative language in which we avoid the config drift and only deploy what has changed. Pluggable: Modules and resources that can help us to connect to any cloud. DevOps First: Follows the best practices of DevOps in your infrastructure

Declarative vs Imperative

It is really common to have questions such as, why declarative is better than imperative? Well:

  • Imperative (step by step) in how we want to deploy our infrastructure, for example, CLI commands but this doesn’t scale well since you need to create custom scripts and if a failure occurs during the process you need to re-run from the beginning.
  • Declarative Like terraform, you define the final state of your infrastructure, using config maps, it escalates faster and allows us to keep track of where we had the issue so we can check that specific step.

Other tools such as Kubernetes, Docker, Ansible make use of the declarative syntax as well, which is the new form.

Configuration Drift

No one wants to get a configuration drift during the DevOps operations, this basically means that our existing environment is no longer matching our automation environment, this is usually lead due to the mutable infrastructure approach.

With Terraform we can achieve mutable and immutable systems, in which the last approach is the best but also the expensive one:

- Immutable: Can’t be mutated. When a new configuration needs to be added we set up a new environment along with the old one, and once we have confirmed that the new one is working, we deprovision the old one and just leave the new one. It is kind of expensive but it is the best practice.
- Mutable: Allow modifications, for example, you can create scripts to “upgrade” your current infrastructure, but if something fails you fall down in a limbo, which is called configuration (environment) drift, in which our configuration that defines our infrastructure actually does not match what is actually there.

Terraform LifeCycle

Terraform enables you to automate and manage your infrastructure, platform, and services using a declarative language and taking advantage of the Infrastructure as a code, therefore understanding the major phases of terraform will boost your knowledge while working with it.

There are 3 major phases in which Terraform perform its provisioning, those are:
- Code: Here is where using the declarative language we define what is needed for our infrastructure. Everything has .tf extension
- Plan: In this phase, Terraform compares our desired state with our current available infrastructure.
- Apply: Here is where terraform will work with the cloud provider using the API token to provision

There is another known module that is usually known as the Terraform Module, which provides a way of grouping together some terraform automation, it takes a set of inputs and provides a set of outputs, basically, it is in the PLAN phase and generates the OUTPUT declared during the CODE phase.

I’ve done this image showing the details of each of those steps

Terraform lifecycle

In the previous image there is a lot of information about files, here are the details:

Code Phase:

variables.tf: Terraform allows you to parameterize your declarative file, you need to create a file called variables.tf to instantiate your variables with a description, and type if needed. The supported types are string, number, bool, list, or map. Here is an example of how it looks, a good practice is to always setup a default value, description, and the type of the variable

Instantiating variables

And the way we can call or define those varaibles in our main.tf file, is done by using var.myVariableName for example, here is how it looks the main.tf file:

Variables in the main.tf

dev.tfvars: Since we declared the variable files, now we need to assign a value to those, the most important part here is the extension .tfvars since you can have several of this files, for example prod, test, staging, etc.

Assigning variables

modules: Terraform allows us to create and use modules, so we can use specific pieces of defined infrastructure to avoid re-creating those each time.

Plan Phase:

When we run the terraform plan, terraform will check the terraform.tfstate, which is a file that describes the current status of the declared architecture. If it is the first time it is executed it will know that he needs to create everything, if not he can just check what has changed and apply only the part needed, this is a really good advantage of the declarative language.

Apply Phase

During the apply phase, all the parts that were specified during the code phase, and confirmed with the plan phase will be created, and this is achieved by using the provider, which is usually a cloud provider. Here is where we deploy our architecture based on our files.

Real-life example:

Imagine that we have a requirement to set up a VM and a Kubernetes cluster with a VPC around it. So we start declaring the code, we create the variables, outputs, providers, and resources as needed, then the terraform plan check the desired state vs our current one, if it is a new architecture, it will identify and provide all the architecture needed, if there are changes, it checks what has been added and create those, and also providing the outputs at the end of that phase.

Thanks for reading!!

--

--

Josué Carvajal

Sr. Security software engineer working in the DevSecOps area. CompTIA Sec+, C|EH