Introduction of Terraform
Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently.
HashiCorp’s 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 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.
How Terraform Works
Terraform creates and manages resources on cloud platforms and other services through their application programming interfaces (APIs). Providers enable Terraform to work with any platform or service with an accessible API.
HashiCorp and the Terraform community have already written thousands of providers to manage many different types of resources and services. You can find all publicly available providers on the Terraform Registry, including Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog, and many more.
Terraform Workflow
Write: Define resources, which may be across multiple cloud providers and services. For example, you might create a configuration to deploy an application on virtual machines in a Virtual Private Cloud (VPC) network with security groups and a load balancer.
Plan: Terraform creates an execution plan describing the infrastructure it will create, update, or destroy based on the existing infrastructure and your configuration.
Apply: On approval, Terraform performs the proposed operations in the correct order, respecting any resource dependencies. For example, if you update the properties of a VPC and change the number of virtual machines in that VPC, Terraform will recreate the VPC before scaling the virtual machines.
Terraform use cases:
- Manage any infrastructure
- Track your infrastructure
- Automate changes
- Standardize configurations
- Collaborate
What is a Terraform Provider
A provider is a plugin that lets Terraform manage an external API. In your CDK for Terraform (CDKTF) application, you use your preferred programming language to define the resources you want Terraform to manage on one or more providers.
You can install pre-built providers packaged with the required code bindings for your language or add providers to the cdktf.json file and generate code bindings manually. To use providers in your application, you can import them from the Terraform Registry or from your local machine.
Syntax:
terraform {
required_providers {
aws = {
source = “hashicorp/aws”
version = “4.48.0”
}
}
}
provider “aws” {
# Configuration options
}
What is a State File in Terraform
Terraform stores information about your infrastructure in a state file. This state file keeps track of resources created by your configuration and maps them to real-world resources.
Terraform compares your configuration with the state file and your existing infrastructure to create plans and make changes to your infrastructure. When you run terraform apply or terraform destroy against your initialized configuration, Terraform writes metadata about your configuration to the state file and updates your infrastructure resources accordingly.
Terraform Cloud Capabilities
Terraform Cloud is HashiCorp’s managed service offering. It eliminates the need for unnecessary tooling and documentation for practitioners, teams, and organizations to use Terraform in production.
Provision infrastructure in a remote environment that is optimized for the Terraform workflow.
What is Terraform Backend
A backend defines where Terraform stores its state data files. Terraform uses persisted state data to keep track of the resources it manages. Most non-trivial Terraform configurations either integrate with Terraform Cloud or use a backend to store state remotely.
Syntax:
terraform {
backend “remote” {
organization = “example_corp”
workspaces {
name = “my-app-prod”
}
}
}
Terraform Module
A Terraform module is a set of Terraform configuration files in a single directory. Even a simple configuration consisting of a single directory with one or more .tf extension files is a module. When you run Terraform commands directly from such a directory, it is considered the root module.
Syntax:
module “servers” {
source = “./app-cluster”
servers = 5
}
Terraform Workspace
Workspaces in the Terraform CLI refer to separate instances of state data inside the same Terraform working directory. They are distinctly different from workspaces in Terraform Cloud, which each have their own Terraform configuration and function as separate working directories.
Syntax:
resource “aws_instance” “example” {
count = “${terraform.workspace == “default” ? 5 : 1}”
# … other arguments
}
Terraform Input Variables
Terraform input variables are used as parameters to input values at run time to customize our deployments. Input terraform variables can be defined in the main.tf configuration file but it is a best practice to define them in a separate variables.tf file to provide better readability and organization.
Syntax:
variable “image_id” {
type = string
}
variable “availability_zone_names” {
type = list(string)
default = [“us-west-1a”]
}
variable “docker_ports” {
type = list(object({
internal = number
external = number
protocol = string
}))
default = [
{
internal = 8300
external = 8300
protocol = “tcp”
}
]
}
Terraform Environment Variables
Terraform searches the environment of its own process for environment variables named TF_VAR_<var-name> followed by the name of a declared variable. Terraform scans all variables starting with TF_VAR and uses those as variable values for Terraform.
Syntax:
export TF_LOG=trace
export TF_LOG=off
export TF_LOG_PATH=./terraform.log
Terraform Provisioners
You can use provisioners to model specific actions on the local machine or on a remote machine in order to prepare servers or other infrastructure objects for service.
Local-Exec Provisioner
The local-exec provisioner invokes a local executable after a resource is created. This invokes a process on the machine running Terraform, not on the resource.
Basically, this provisioner is used when you want to perform some tasks on your local machine where you have installed Terraform. So local-exec provisioner is never used to perform any task on the remote machine. It will always be used to perform local operations onto your local machine.
Syntax:
resource “aws_instance” “web” {
# …
provisioner “local-exec” {
command = “echo The server’s IP address is ${self.private_ip}”
}
}
Remote-Exec Provisioner
As the name suggests, remote-exec provisioner is always going to work on the remote machine. With the help of this feature, you can specify the commands of shell scripts that want to execute on the remote machine. The remote-exec provisioner invokes a script on a remote resource after it is created. This can be used to run a configuration management tool, bootstrap into a cluster, etc. It requires a connection and supports both ssh and winrm.
Syntax:
resource “aws_instance” “web” {
# …
# Establishes connection to be used by all
# generic remote provisioners (i.e. file/remote-exec)
connection {
type = “ssh”
user = “root”
password = var.root_password
host = self.public_ip
}
provisioner “remote-exec” {
inline = [
“puppet apply”,
“consul join ${aws_instance.web.private_ip}”,
]
}
}