Top 3 Terraform Best Practices

Terraform is an open-source infrastructure as a code tool created by HashiCorp. Terraform can manage your AWS, Azure, and Google Cloud resources. In addition, terraform can create, manage, and delete infrastructure components such as instances, volumes, networks, and DNS entries.

It is critical to have a standardized folder structure for your terraform project. Make sure you are using source control methodology such as git. I also use source control platforms like Atlassian Bitbucket and GitLab. If you want to know more about structuring your code.

Let’s dig deeper into some of the most important Terraform best practices:

Create and Adopt a Naming Convention

Using a standardized naming convention is fundamental to using Terraform at scale. Develop a naming convention that can adapt between the name of the repo, the environment, the name of cloud resources, and everything in between.

One of the easiest ways to do this is to create some standard variables in your .tfvars file. 

This is how I do it:

#Project Vars
environment = "dev"
project     = "tech"
usage       = "data"
category    = "infra"

You can then pass these variables into your code like so:

name = "${var.envionment}-${var.project}-${var.usage}-domain-01

This would name the resource:

dev-tech-data-domain-01

Advanced users can create a label module that automatically tags resource names. There are a number of repos on github to get you started. Other tips to follow here include always labeling your resource with and underscore and the name of a resource with a hypen. This practice ensures consistency with the naming convention for resource types, data source types, and other predefined values.

 Recommended:
resource "aws_instance" "web_server" {   
  name = "web-server" 
} 
Not recommended:
resource "aws_instance" "web-server" {   
  name = "web-server" 
} 

Do Not OverUse Variables

Terraform is a tool that helps you create, change, and manage infrastructure in a scalable and reliable way. One of the main features of Terraform is the ability to use variables. Variables are key in Terraform because they allow you to change the behavior of your infrastructure without having to rebuild it. For example, you can use a variable to change the size of a container fleet based on the time of year.

Variable definitions are stored in a file called vars.tf. You can use the terraform apply command to apply the variable definitions to an infrastructure. Variables are needed in your code, that is a fact. However many users try to variablize everything which can make managing the code complicated in the future.

Instead I recommend exposing local values to the code, you can even use a tool like the AWS parameter store to call the parameters and set them as local values.

Examples:

You can call a parameter as a data source

data "aws_ssm_parameter" "base_rhel_image" {
  name = "/dev/ami/base/rhel7"
}
data "aws_ssm_parameter" "main_vpc_id" {
  name = "/terraform/${var.environment}/main_vpc_id"
}
data "aws_ec2_managed_prefix_list" "corporate" {
  name = "my-corporate-name"
}

Or you can write your own module to get and put values in the parameter store. There is a good example on github.

This example will call a parameter set called default_security_groups and assign it a local value that can be called anywhere within your code.

module "my_params" {
  source          = "git/modules/ssm_parameters_get?ref=v1.0"
  environment     = var.environment
  parameter_names = ["default_security_groups"]
}

locals {
  param_aws_api_sec_group      = lookup(jsondecode(nonsensitive(module.my_params.values["default_security_groups"])), "api")
  param_aws_services_sec_group = lookup(jsondecode(nonsensitive(module.my_params.values["default_security_groups"])), "services")
  param_aws_support_sec_group  = lookup(jsondecode(nonsensitive(module.my_params.values["default_security_groups"])), "support")
}

Put static files in a separate directory

Sometime you will need to write code that contains static files, such as a json file, perhaps an installer file, or even userdata templates and ansible playbooks. I commonly use static files to upload data to Amazon S3, and then the resources I provision pull down the static files from S3 and execute locally.

If you’re using Terraform to manage your infrastructure, you may need to take extra care when it comes to static files. Terraform uses a number of different files to keep track of state, and if you move or delete any of these files, Terraform may not be able to continue working as expected.

Here are a few tips to keep your static files safe:

1. Make sure your static files are stored in a location where Terraform can access them easily.

2. Avoid moving or deleting any of Terraform’s static files.

3. Make sure your Terraform configuration files are versioned and stored in a separate location. (e.g Amazon S3 Bucket versioning)

Want to know more about Terraform? Check out our other artices:

Learn Core Terraform Concepts

Terraform Core Commands

Learn out Terraform Plan -Out

Elsewhere On TurboGeek:  How to Decommission an AWS Control Tower Landing Zone

Richard.Bailey

Richard Bailey, a seasoned tech enthusiast, combines a passion for innovation with a knack for simplifying complex concepts. With over a decade in the industry, he's pioneered transformative solutions, blending creativity with technical prowess. An avid writer, Richard's articles resonate with readers, offering insightful perspectives that bridge the gap between technology and everyday life. His commitment to excellence and tireless pursuit of knowledge continues to inspire and shape the tech landscape.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

Translate ยป