DEV Community

Cover image for Terraform Best Practices
Pankaj Kumar
Pankaj Kumar

Posted on • Updated on

Terraform Best Practices

Original Post Published here : Terraform Best Practices

Terraform is an open-source tool that allows you to define the infrastructure for a variety of cloud providers (e.g. AWS, Azure, Google Cloud, DigitalOcean, etc) using a simple, declarative programming language.

This guide assumes that you have a basic idea of terraform. I have taken examples of Terraform with AWS provider. Concepts will be similar to other providers as well.

I will be using this repo for explaining all the examples: Terraform-examples

Always use latest terraform version (Current version is terraform v0.12.x)

We should always pick the latest terraform version. The reason is that sometimes terraform doesn't have backward compatibility. You will always be stuck with the chosen version.

Always use var-file for terraform plan

We should always use var-file for variables. It will be easy to maintain different variables for different environments and modules. There are different methods which can be used for variables like assign a string value to var variable, an Environment variable, var-file.

Checkout this guide for all options Input Variable guide
Checkout this example Variable Example

Manage s3 backend for tfstate files

Whenever we create any resource with terraform (terraform apply), it maintains the state in tfstate file. Try to run Variable Example. It will create tfstate file in local. If we modify any resource or add, tfstate will be changed after each terraform apply.
In the team , multiple team members will be modifying terraform code. So we should maintain tfstate at version control system (Example: S3).
Checkout this example S3 backend Example

Use dynamo db for locking tfstate modification

Multiple team members will run terraform apply at the same time which can create issues. We should use dynamo DB for locking. It will not allow other terraform apply a process to change tfstate till the release of the lock.
Checkout this example S3 backend Example

Enable version control on terraform state files bucket

First, we should use s3 remote storage for managing tfstate. We should enable version control on this s3 remote.
Reason: If any issue comes with current tfstate in production, we can always go back to the previous version.
Checkout this example Variable Example

Use terraform import for existing resources

Suppose we have created resources earlier. Now we want to use it with terraform code. It is possible with terraform import. It will make these resources as part of terraform.
Checkout this example Import Example

Use shared modules

Terraform community has shared generic modules on terraform registry like ecs-fargate , ecs-service, s3 bucket creation.

Module Registry
Checkout this example Share Module Example

Use terraform modules for mananging different environments(dev/stage/prod)

A module is a container for multiple resources that are used together. We should use terraform modules for managing the code between different environment. Every terraform configuration has its root module which consists of resources defined in the .tf files in the main working directory. We wrap common resources in modules so it can be reused for a different environment. We can use the git version system for modules. Checkout share modules example. It is hosted on Github and we are directly using it.
Checkout this example for modules structure: Module Example

If you want to learn terraform in detail, check out the below book:

Terraform in Detail

Top comments (9)

Collapse
 
david_j_eddy profile image
David J Eddy

Nice article Pankaj! Some very good points. When I saw Use terraform modules for managing different environments(dev/stage/prod) I thought to myself "Terragrunt fixed this for me". Check it out. It makes using Terraform and multiple environments a lot easier.

Also, I noticed the Original Post Published here : Terraform Best Practices points to google.com; might want to correct that. :)

Collapse
 
cryptic022 profile image
Pankaj Kumar

Thanks a lot, David. I will check it out Terragrunt. Will fix the original post link as well.

Collapse
 
cteyton profile image
Cédric Teyton

Hi Pankaj, FYI we've added your blog post on a GitHub project gathering content about best coding practices :)
github.com/promyze/best-coding-pra...

Collapse
 
padakipavan profile image
padaki-pavan • Edited

I've been using terraform workspace to manage different env setup like Dev, prod, etc. That works well for me. What's the possible downside to this approach?

Collapse
 
cryptic022 profile image
Pankaj Kumar

Sorry for the late reply. How are you managing the remote state in this case? We manage each environment on different AWS accounts. As per my knowledge, we can't use different remote s3 bucket for each terraform workspace.

Collapse
 
padakipavan profile image
padaki-pavan

Afaik, switching terraform workspaces creates completely independent state files. I usually commit them to a private git repo. Probably not the best solution, but it works for me.

Thread Thread
 
padakipavan profile image
padaki-pavan

Alternatively have a look at terragrunt, it solves the exact same problem you described.

Thread Thread
 
cryptic022 profile image
Pankaj Kumar

I have just started using terragrunt. It solves the exact problem.

Thread Thread
 
aronjohnson profile image
Aron Johnson

Thanks for the tip about Terragrunt. Looks super handy.