Terraform 101 - Inception to Mastering Terraform - Part 2
Maharshi Dutta
Senior Project Engineer @ Wipro (LAB45) ? DevOps Engineer ? Multi-Cloud Infrastructure ? Enhancing collaboration with centralized open-source DevOps solutions
Introduction
In the realm of DevOps engineering, mastering Terraform is akin to wielding a powerful wand that can shape infrastructure with a mere flick of code. However, behind the magic lies the crucial aspect of managing Terraform state effectively, ensuring security, integrity, and scalability. Join me as we explore into the intricacies of Terraform state management, explore the benefits of remote storage, harness the versatility of variables, unveil the insights of outputs, and tread cautiously into the realm of provisioners.
State Management
At the heart of Terraform's functionality lies its ability to track and manage state. Think of it as the blueprint guiding Terraform's actions, dictating which resources need creation, updating, or destruction. This mechanism not only ensures synchronization between your configuration code and real-world resources but also empowers efficient resource management over multiple deployments.
By default, Terraform stores state locally tracked through a flat file named by default terraform.tfstate, a JSON dump that contains metadata and data about deployed resources.
Terraform state has 3 common sub-commands:
1. terraform state list - List tracked resources by terraform state.
2. terraform state show - Shows the details of tracked resources.
3. terraform state rm - Remove resources from the state file so they can't be tracked.
But for robustness and collaboration across teams, it's prudent to opt for remote state storage. Whether it's HashiCorp Consul, AWS S3, or Azure Storage Account, remote storage offers enhanced availability, security, and visibility. Transitioning from local to remote storage is seamless, requiring a mere tweak in the Terraform configuration block.
terraform {
backend "s3" {
bucket = "mybucket"
key = "path/to/my/key"
region = "ap-south-1"
}
}
This assumes we have a bucket created called "mybucket". The Terraform state is written to the key path/to/my/key.
Using Azure, you can also store the state as a Blob with the given Key within the Blob Container within the Blob Storage Account. Those are some configuration examples:
Variables
Variables in Terraform serve as the building blocks of dynamic configurations, enabling clean, reusable, and parameterized code. From simple strings to complex data structures like lists, sets, maps, and objects, Terraform accommodates a spectrum of variable types, ensuring flexibility in configuration management. With validation mechanisms and sensitivity flags, Terraform empowers engineers to handle sensitive data securely while preempting configuration errors.
variable “my-variable” {
description = “This is some description”
type =? string
default = “Mimo”
}
Variables types are two:
We can define a variable type to be combined with one or more types, for instance:
领英推荐
variable “set_of_objects” {
type = set (object ( {
port = number
service = string }))
default = [
{
port = 22
service = “ssh”
},
{
port = 80
service = “http”
},
]
}
Terraform variables are referenced in configuration code with var.name_of_var, and read precedence starts with ones passed through the OS environment variables and then the terraform.tfvars file, then variables in the main configuration code.
Other parameters that are useful in variables declaration are
variable "ip_address" {
type = string
description = "Example to validate IP address"
validation {
condition = can(regex("^25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", var.ip_address))
error_message = "Invalid IP address provided."
}
}
Outputs
In the lifecycle of Terraform, outputs serve as the gateway to glean insights into deployed resources. Analogous to return statements in programming languages, outputs furnish valuable information back to the CLI, facilitating post-deployment operations and integration with external systems. Whether it's fetching the private IP address of an EC2 instance or extracting metadata from a container, outputs streamline post-deployment workflows with precision.
output “my-ec2-ip” {
description = “ec2 Private ip”
value = aws_instance.my-ec2.private_ip
}
output variable values are shown in the CLI after successful terraform apply. You can still set senstive=true to outputs, in case they contain sensitive values.
Provisioners
While Terraform's declarative paradigm emphasizes idempotent resource management, provisioners offer a gateway to execute imperative commands or scripts during resource lifecycle events. Whether it's configuring software post-deployment or executing cleanup tasks upon resource destruction, provisioners augment Terraform's capabilities. However, tread cautiously, for provisioners bypass Terraform's state tracking, necessitating prudence in usage and strategic evaluation against native cloud provider capabilities.
Provisioners are recommended to be used if Terraform declarative model doesn’t already offer the action to be taken. If while applying configuration the code exits with non-zero code, it’s considered failed and the resource is tainted.
The configuration below runs two provisioners on a null resource:
resource "null_resource" "null_resource" {
provisioner "local-exec" {
command = "echo '0' >> status.txt"
}
provisioner "local-exec" {
when = destroy
command = "echo '1' >> status.txt"
}
}
one that runs in resource create and another (that contains destroy) that runs when destroying the resource, the two provisioners add 0, and 1 respectively to a file named status.txt. So as you can tell, when first provision the null_resoure there will be in status.txt 0 , and after destroying it, there will be 01 in that file.
Conclusion
In the ever-evolving landscape of DevOps engineering, mastering Terraform transcends proficiency in writing code; it entails understanding the nuances of state management, remote storage, variables, outputs, and provisioners. By leveraging Terraform's arsenal effectively, engineers can orchestrate infrastructure with finesse, balancing automation with control, and embracing agility without compromising stability. As we navigate the complexities of modern infrastructure provisioning, let Terraform be our guiding beacon toward a future where infrastructure as code reigns supreme.
Thanks for the read.
Follow for the upcoming part of the Terraform learning journey.