Introduction To Terraform - Infrastucture as Code (IaC)
Posted on May 29, 2023 (Last modified on March 8, 2024) • 6 min read • 1,133 wordsIntroduction to using Terraform to provision infrastructure resources and why IaC can be useful to the homelabber as much as it is to large organisations
Infrastructure provisioning and management have become pivotal for organisations seeking agility, scalability, and efficiency. Traditional manual processes are no longer sufficient to keep up with the demands of modern infrastructure deployment. This is where Terraform, an open-source infrastructure as code (IaC) tool, comes into play.
Terraform, developed by HashiCorp, is a powerful tool that enables users to define and provision infrastructure resources declaratively. It treats infrastructure as code, allowing you to describe your desired infrastructure state in a declarative configuration language, known as HashiCorp Configuration Language (HCL). Terraform then automates the process of provisioning and managing infrastructure resources across various cloud providers, data centers, services and on-prem. Learn more in the official HashiCorp Docs
To begin using Terraform, you need to follow a few essential steps:
main.tf
), where you define your desired infrastructure resources, providers, and variables. This file will serve as the blueprint for your infrastructure.terraform init
command to initialize the Terraform environment in your project directory. This command downloads the necessary provider plugins and sets up the backend for state storage.terraform plan
to preview the changes Terraform will apply to your infrastructure. This step is essential for reviewing and validating your configuration. To apply the changes, run terraform apply
. Terraform will orchestrate the necessary actions to achieve the desired infrastructure state.An example of a Terraform environment folder is given on the left. When a project is initialised (init
) Terraform generates a .terraform
folder. In this example I store my credentials in the credentials.auto.tfvars
file that is ignored by version control. Terraform then reads any required credentials and secret variables from this file. There are other ways to do this such as using HashiCorps Vault or another secret store manager. But for getting started I found it easier to store them like this. main.tf
contains my declared resources. which is an Ubuntu VM using the Proxmox provider in this case. I’ll be going into more detail about this in a future post. .terraform.lock.hcl
is a dependency lock file which details the versions of the dependencies (providers and modules) that are in use and compatible with the current configuration.
provider.tf
defines the Proxmox provider and any arguments it requires (which is Telmate/proxmox
in this case). The state of the remote resources is stored in the terraform.tfstate
file which can also be stored on remote storage such as S3, Terraform Cloud or another storage/bucket provider so your state is accessible anywhere and not just on your local computer. This state file is used to compare against the local declared state in main.tf
. Terraform works out what is required to reach the required state as declared in your main.tf
and applies this to the remote resource.
See the resources below for some more examples and best practices for project environment structure.
Here are some very basic Terraform resource snippets taken from the providers documention, to give you and idea of how resources are defined. Note that you would have to define other configuration, i.e provider, region, credentials etc for these to work.
The below snippet shows an EC2 machine called test
of instance type c5.18xlarge
.
resource "aws_ec2_host" "test" {
instance_type = "c5.18xlarge"
availability_zone = "us-west-2a"
host_recovery = "on"
auto_placement = "on"
}
The below snippet creates a DNS A
record at terraform.domain.tld
pointing to the IP address 192.0.2.1
.
# Add a record to the domain
resource "cloudflare_record" "example" {
zone_id = var.cloudflare_zone_id
name = "terraform"
value = "192.0.2.1"
type = "A"
ttl = 3600
}
Terraform simplifies and automates the process of infrastructure provisioning by treating it as code. With its declarative configuration language and multi-provider support, it empowers organisations, and homelabbers, to achieve infrastructure agility and scalability. By adopting Terraform, you can increase operational efficiency, reduce human errors, and ensure consistent infrastructure deployments across multiple environments. Plus save hours manually setting up resources! So why not explore Terraform further and learn more about automated infrastructure management.
I’ll be discussing how I switched to using Terraform to declare and provision my machines in my homelab in future posts.
Below are some useful resources that helped me get started and that I’m still learning from.