Terraform is an open-source Infrastructure as Code (IaC) tool developed by HashiCorp. It enables users to define configuration environments as resources, which can be deployed to third-party services such as DigitalOcean, AWS, and Azure through the use of providers.
Infrastructure as Code involves describing an application's entire infrastructure—servers, databases, and more—as code. This approach consolidates the environment into a single codebase, allowing users to create, declare, and deploy it efficiently.
As the infrastructure is managed from a single source of truth (the version-controlled codebase), developers can quickly modify existing infrastructure without navigating the user interface of the infrastructure provider.
Basic Terraform Example
Terraform requires a main configuration file, conventionally named main.tf, to function. To deploy infrastructure, a provider for a third-party service is necessary. For example, to work with AWS, you would use the AWS provider.
provider "aws" {
profile = "default"
region = "us-east-1"
}
The
main.tffile above declares the AWS provider, specifying the profile and region for AWS interactions.
Running terraform init in the directory downloads the provider and stores it locally, enabling direct communication with AWS. All available providers are listed in the Terraform Registry.
After declaring the provider, you define a resource, which represents a service component provided by the third-party service.
resource "aws_instance" "app_server" {
ami = "ami-0123456789example"
instance_type = "t2.micro"
tags = {
Name = "MyTerraformInstance"
}
}
This
main.tfsnippet defines an AWS t2.micro instance named "MyTerraformInstance".
Executing terraform apply applies these changes to AWS, creating the instance, which becomes visible in the AWS control panel. This command also generates a state file (terraform.tfstate), which records the infrastructure's current state, similar to a .lock file. Subsequent changes are compared against this state, and only the differences are applied.
Improvements
The example resource above uses hard-coded values, such as the instance type. To make changes, you would need to edit main.tf directly. To enhance flexibility, you can use variables by creating two additional files: variables.tf for declaring variables and terraform.tfvars for assigning values.
variable "instance_name" {
type = string
default = "MyNewInstance"
}
The
variables.tffile declares a variableinstance_namewith a default value.*
instance_name = "MyNewInstanceNewName"
The
terraform.tfvarsfile assigns a specific value to theinstance_namevariable.*
These variables can then be referenced in main.tf:
resource "aws_instance" "app_server" {
ami = "ami-0123456789example"
instance_type = "t2.micro"
tags = {
Name = var.instance_name
}
}
This updated
main.tfsnippet uses theinstance_namevariable for the instance's name tag.
Using variables makes the configuration more flexible, as changes can be made by updating the terraform.tfvars file without modifying main.tf. Another useful file is outputs.tf, which defines values displayed after running terraform apply. For example:
output "ip_address" {
value = aws_instance.app_server.public_ip
description = "The public IP address of the created instance"
}
The
outputs.tffile defines an output to display the instance's public IP address after deployment.
This output allows users to immediately access the instance’s IP address, facilitating connections via SSH if needed.
Final Directory Configuration
With these improvements, the basic directory structure (excluding provider-specific folders) is as follows:
.
├── main.tf
├── outputs.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── terraform.tfvars
└── variables.tf
The directory structure for a basic Terraform project, including configuration, variable, output, and state files.