Let’s discuss some of the best practices to follow when using Terraform.
Terraform is a very popular open source IaC (Infrastructure as Code) tool for defining and provisioning complete infrastructure.
Terraform was introduced in 2014, but adoption of this tool is increasing globally. More and more developers are learning Terraform to deploy infrastructure within their organizations.
As you start using Terraform, you should adopt best practices to improve the provisioning of your production infrastructure.
If you’re a beginner, check out our Terraform for beginners article.

structuring
If you are working on a large production infrastructure project using Terraform, you need to follow a proper directory structure to handle the complexity that may arise within your project. It’s best to create separate directories for each purpose.
For example, if you are using terraform in a development, staging, and production environment, have separate directories for each.
@:~$ tree terraform_project/
terraform_project/
├── dev
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
├── modules
│ ├── ec2
│ │ ├── ec2.tf
│ │ └── main.tf
│ └── vpc
│ ├── main.tf
│ └── vpc.tf
├── prod
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── stg
├── main.tf
├── outputs.tf
└── variables.tf
6 directories, 13 filesOver time, the configuration of a growing infrastructure becomes complex, so Terraform configurations must also be individualized.
For example, you could write all your Terraform code (modules, resources, variables, outputs) within main.tf file itself, but it’s more readable and understandable if you write separate Terraform code for variables and outputs. It becomes easier.

Naming convention
Terraform uses naming conventions to make it easier to understand.
For example, let’s say you want to create three different workspaces for different environments within your project. So instead of naming them env1, en2, env3, you should call them dev , stage , prod . From the name itself, it is clear that each environment has three different workspaces.
Similar rules must be followed for resources, variables, modules, etc. Terraform resource names must start with the provider name, followed by an underscore and other details.
For example, the resource name for creating a route table Terraform object in AWS is aws_route_table .
Therefore, if you follow naming conventions correctly, even complex code will be easier to understand.

We highly recommend using the official Terraform modules available. No need to reinvent modules that already exist. It will save you a lot of time and effort. There are many ready-to-use modules in the Terraform registry . Make changes to existing modules as needed.
Also, each module should focus on only one aspect of your infrastructure, such as creating an AWS EC2 instance or configuring a MySQL database.
For example, if you want to use AWS VPC in your Terraform code, you can use it like this – simple VPC
module "vpc_example_simple-vpc" {
source
= "terraform-aws-modules/vpc/aws//examples/simple-vpc"
version = "2.48.0"
} 
Latest version
The Terraform development community is very active, and new features are released frequently. As with any new major release, we recommend that you continue to use the latest version of Terraform. Easily upgrade to the latest version.
Skipping multiple major releases greatly complicates the upgrade.
Run the terraform -v command to check for new updates.
@:~$ terraform -v
Terraform v0.11.14
Your version of Terraform is out of date! The latest version
is 0.12.0. You can update by downloading from www.terraform.io/downloads.html System state backup
Be sure to back up your Terraform state files.
These files track infrastructure metadata and resources. By default, these files, called terraform.tfstate , are saved locally in your workspace directory.
Without these files, Terraform has no idea what resources are deployed to your infrastructure. Therefore, it is essential to create a backup of the state file. By default, a file named terraform.tfstate.backup is created to store a backup of the state file.
@:~$ tree terraform_demo/
terraform_demo/
├── awsec2.tf
├── terraform.tfstate
└── terraform.tfstate.backup
0 directories, 3 files If you want to save the backup state file in a different location, use -backup flag with the terraform command and specify the path to that location.
In most cases, multiple developers are working on a project. Therefore, to allow access to state files, you must store them in a remote location using terraform_remote_state data source.
The following example takes a backup to S3.
data "terraform_remote_state" "vpc" {
backend = "s3"
config = {
bucket = “s3-terraform-bucket”
key = “vpc/terraform.tfstate"
region = “us-east-1”
}
}lock state file
There are several possible scenarios where multiple developers attempt to run Terraform configurations at the same time. This can lead to terraform state file corruption and data loss. A locking mechanism helps prevent that from happening. This ensures that only one person is running the Terraform configuration at a time and there are no conflicts.
Here is an example of using DynamoDB to lock a state file in a remote location.
resource “aws_dynamodb_table” “terraform_state_lock” {
name = “terraform-locking”
read_capacity = 3
write_capacity = 3
hash_key = “LockingID”
attribute {
name = “LockingID”
type = “S”
}
}
terraform {
backend “s3” {
bucket = “s3-terraform-bucket”
key = “vpc/terraform.tfstate”
region = “us-east-2”
dynamodb_table = “terraform-locking”
}
}The DynamoDB database name and primary key are used to lock the state and maintain consistency when multiple users attempt to access the state file.
Note : Not all backends support locking.
Use self variables
self variable is a special type of variable used when the value of the variable is not known before deploying the infrastructure.
Suppose you want to use the IP address of the instance that is deployed only after the terraform apply command. Therefore, the IP address is not known until the instance is up and running.
In such cases, use the self variable. The syntax to use this is self.ATTRIBUTE . So in this case, use self.ipv4_address as the self variable to get the IP address of the instance. These variables are only allowed in the connection and provisioner blocks of Terraform configuration.
connection {
host = self.ipv4_address
type = "ssh"
user = var.users[2]
private_key = file(var.private_key_path)
}Minimize explosion radius
Blast radius is just a measure of the damage that can occur if things don’t go as planned.
For example, if you have some Terraform configurations deployed on your infrastructure and the configurations are not applied correctly, how much damage will it cause to your infrastructure?
Therefore, it is always recommended to push several configurations to your infrastructure at once to minimize the blast radius. So if something goes wrong, the damage to your infrastructure is minimal and can be fixed quickly. Deploying many configurations at once is very risky.
Use var files
terraform allows you to create a file with the extension <em>.</em>tfvars and pass this file to the terraform apply command using the -var-file flag. This is useful for passing variables that you don’t want to include in your terraform configuration code.
It is always recommended to pass variables such as passwords and private keys locally via -var-file rather than storing them within the Terraform configuration or in a remote version control system.
For example, if you want to launch an ec2 instance using terraform, you can pass the access key and secret key using -var-file .
Create a file terraform.tfvars and put your keys in this file.
@:~$ gedit terraform.tfvars
access_key = "AKIATYWSDFYU5DUDJI5F"
secret_key = "W9VCCs6I838NdRQQsAeclkejYSJA4YtaZ+2TtG2H"Then use this var file with the terraform command.
@:~$ terraform apply -var-file=/home//terraform.tfvarsuser docker
We recommend using Docker containers to run build jobs for your CI/CD pipeline. Terraform provides official Docker containers that you can use. If you want to change your CI/CD server, you can easily pass the infrastructure around in a container.
Before deploying your infrastructure in production, you can also test it on Docker containers, which are very easy to deploy. Terraform and Docker together provide a portable, reusable, and repeatable infrastructure.
conclusion
We hope these best practices will help you create better Terraform configurations. Implement these in your Terraform project for better results.




![How to set up a Raspberry Pi web server in 2021 [Guide]](https://i0.wp.com/pcmanabu.com/wp-content/uploads/2019/10/web-server-02-309x198.png?w=1200&resize=1200,0&ssl=1)











































