What is Terraform

HashiCorp Terraform is an infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features. (https://developer.hashicorp.com/terraform/intro)

Terraform, an open-source Infrastructure-as-Code (IaC) tool developed by HashiCorp, allows users to define easily readable configuration files that support version control, automation, and collaboration. With compatibility across major environments such as AWS, Azure, Kubernetes, Docker, and Helm through providers available on the Terraform Registry. Terraform operates agentlessly. Users declare the desired state of their environment, and Terraform efficiently installs, updates, and tears down the infrastructure accordingly.

Benefits

  1. Multi-Cloud Deployment: Terraform’s multi-cloud support allows organizations to avoid vendor lock-in by seamlessly deploying and managing resources across different cloud providers like AWS or Azure.
  2. Stateful Infrastructure: Terraform maintains a state file that keeps track of the current state of the infrastructure. This ensures that Terraform knows what resources are deployed and allows for efficient updates and deletions.
  3. Version Control Integration: Integration with version control systems like Git enables teams to manage infrastructure changes effectively, roll back to previous states, and collaborate seamlessly.
  4. Declarative Configuration: Declarative syntax in Terraform configurations means specifying the desired end state without detailing the step-by-step procedure. This reduces the risk of errors and makes configurations more human-readable.
  5. Automation: Terraform enables automation of infrastructure setup and teardown processes, reducing manual intervention and potential human errors. This is especially crucial in the era of continuous integration and continuous deployment (CI/CD).
  6. Disaster Recovery: With Terraform, recovering from infrastructure failures or disasters becomes more manageable. The ability to redeploy infrastructure quickly ensures minimal downtime and efficient disaster recovery.

Installation

You can find the instructions here: https://developer.hashicorp.com/terraform/install.

”Hello World” example

Once Terraform is installed on the machine, run the following command to initialize the project:

Terminal window
# Init terraform directory
terraform init

Then, create a main.tf file and add this code inside:

main.tf
output "hello" {
value = "Hello world !"
}

This script creates a variable “hello” and puts “Hello world !” inside. Then, run the following command to tell to Terraform that the current state changed:

Terminal window
terraform plan
terraform apply

A file terraform.tfstate is created. It represents the database of our infrastructure.

When the infrastructure will evolve, we can update our main.tf file. Terraform will compare the terraform.tfstate file and the main.tf to apply the modifications.

Small example with Kubernetes

Project initialization

Note: This part requires a functioning Kubernetes/K3S cluster.

To manipulate Kubernetes, we will need to have this provider: https://registry.terraform.io/providers/hashicorp/kubernetes/latest. To install it, click on the button USE PROVIDER on the website, and copy paste the code. The current version (today is the 8th january 2024) is 2.25.1. To use it, copy paste this code in your main.tf file ;

main.tf
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.25.1"
}
}
}
provider "kubernetes" {
config_path = "~/.kube/config"
config_context = "default"
}

You can see that we added config_path and config_context to connect to the cluster.

Our first namespace/pod

First, let’s create our first namespace:

main.tf
// ...
resource "kubernetes_namespace" "namespace_alex" {
metadata {
name = "terraformtutoalex"
labels = {
env = "prod"
}
}
}
// ...

And we can add our pod like this:

main.tf
// ...
resource "kubernetes_pod" "nginxpod" {
metadata {
name = "nginx-pod"
namespace = kubernetes_namespace.namespace_alex.metadata[0].name
labels = {
App = "nginx"
}
}
spec {
container {
image = "nginx:latest"
name = "mynginx"
port {
container_port = 80
}
}
}
}
// ...

Our first service

We can continue with our first service, like this:

main.tf
// ...
resource "kubernetes_service" "nginxservice" {
metadata {
name = "nginxservice"
namespace = kubernetes_namespace.namespace_alex.metadata[0].name
}
spec {
selector = {
App = kubernetes_pod.nginxpod.metadata[0].labels.App
}
port {
port = 80
}
type = "NodePort"
}
}
// ...

Finally, to test if our nginx application is online, we can print the ports with these lines:

main.tf
// ...
output "app" {
value = {
name = kubernetes_pod.nginxpod.metadata[0].name
container = kubernetes_pod.nginxpod.spec[0].container[0].name
service = kubernetes_service.nginxservice.spec[0].port[0].node_port
}
}
// ...

Then, don’t forget to run the commands:

Terminal window
terraform plan
terraform apply

🎉 TADA, we created our first small infrastructure using Terraform !

To go further

Providers

Terraform comes with a lot of other providers. We can find the list here : https://registry.terraform.io/browse/providers.


Recommended articles