Terraform Basics Training Course
Working with Terraform
Terraform Commands
In this guide, we explore essential Terraform commands used to validate configurations, format files, inspect state, manage providers, output variables, refresh state, and visualize resource dependencies. Each section provides clear examples and outputs to help you master the use of Terraform in your infrastructure management tasks.
Terraform Validate
After crafting your Terraform configuration files, you can verify their syntax without running a full plan or apply. The terraform validate
command checks your configuration for errors, ensuring that your HCL (HashiCorp Configuration Language) is correct.
For example, consider the following configuration:
resource "local_file" "pet" {
filename = "/root/pets.txt"
content = "We love pets!"
}
Run the command:
$ terraform validate
Success! The configuration is valid.
If an error is present, such as using an unsupported argument, Terraform will indicate the issue. For instance, using file_permissions
instead of file_permission
may lead to an error. The corrected configuration should be:
resource "local_file" "pet" {
filename = "/root/pets.txt"
content = "We love pets!"
file_permission = "0700"
}
If left uncorrected, you might see an error like this:
$ terraform validate
Error: Unsupported argument
on main.tf line 4, in resource "local_file" "pet":
4: file_permissions = "0777"
An argument named "file_permissions" is not expected here. Did you mean "file_permission"?
Terraform fmt
The terraform fmt
command scans your configuration files in the current directory and reformats them into a standard style. This canonical formatting greatly improves code readability and consistency. Running the command will list any files that were modified during the formatting process.
Terraform Show
The terraform show
command is used to display the current Terraform state, detailing all attributes of your managed resources. This output helps you verify the actual state of your infrastructure.
For example, if you have a local file resource, running:
$ terraform show
# local_file.pet:
resource "local_file" "pet" {
content = "We love pets!"
directory_permission = "0777"
file_permission = "0777"
filename = "/root/pets.txt"
id = "cba595b7d9f94ba1107a46f3f731912d95fb3d2c"
}
To view this state in JSON format, use the -json
flag:
$ terraform show -json
{"format_version":"0.1","terraform_version":"0.13.0","values":{"root_module":{"resources":[{"address":"local_file.pet","mode":"managed","type":"local_file","name":"pet","provider_name":"registry.terraform.io/hashicorp/local","schema_version":0,"values":{"content":"We love pets!","content_base64":null,"directory_permission":"0777","file_permission":"0777","filename":"/root/pets.txt","id":"cba595b7d9f94ba1107a46f3f731912d95fb3d2c","sensitive_content":null}}]}}}
Terraform Providers
The terraform providers
command lists all providers required by your configuration along with those used in your state. It also supports mirroring provider plugins to a specified directory.
For example:
$ terraform providers
Providers required by configuration:
└── provider[registry.terraform.io/hashicorp/local]
Providers required by state:
provider[registry.terraform.io/hashicorp/local]
$ terraform providers mirror /root/terraform/new_local_file
- Mirroring hashicorp/local...
- Selected v1.4.0 with no constraints
- Downloading package for windows_amd64...
- Package authenticated: signed by HashiCorp
Tip
Mirroring providers can accelerate deployments in environments with restricted internet access, ensuring that all necessary plugins are available locally.
Terraform Output Variables
Terraform output variables allow you to extract and display configuration values once your infrastructure has been applied. This is particularly useful for showing key results or passing values between modules.
Consider the following configuration:
resource "local_file" "pet" {
filename = "/root/pets.txt"
content = "We love pets!"
file_permission = "0777"
}
resource "random_pet" "cat" {
length = "2"
separator = "-"
}
output "content" {
value = local_file.pet.content
sensitive = false
description = "Print the content of the file"
}
output "pet-name" {
value = random_pet.cat.id
sensitive = false
description = "Print the name of the pet"
}
After applying the configuration, run:
$ terraform output
content = We love pets!
pet-name = huge-owl
Terraform Refresh
The terraform refresh
command synchronizes your Terraform state with the actual state of your infrastructure. This is particularly useful when external changes have occurred outside of Terraform.
Consider the following configuration:
resource "local_file" "pet" {
filename = "/root/pets.txt"
content = "We love pets!"
file_permission = "0777"
}
resource "random_pet" "cat" {
length = "2"
separator = "_"
}
When you run a plan, Terraform refreshes the state in-memory:
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage.
random_pet.cat: Refreshing state... [id=huge-owl]
local_file.pet: Refreshing state... [id=cba595b7d9f94ba1107a46f3f731912d95fb3d2c]
--------------------------------------------------------------------
No changes. Infrastructure is up-to-date.
You can also update the state file without changing any infrastructure by using the -refresh-only
flag with terraform apply
:
$ terraform apply -refresh-only
random_pet.cat: Refreshing state... [id=huge-owl]
local_file.pet: Refreshing state... [id=cba595b7d9f94ba1107a46f3f731912d95fb3d2c]
To prevent automatic refreshing during plan or apply, use the -refresh=false
option.
Terraform Graph
The terraform graph
command creates a DOT format representation of resource dependencies in your configuration. The graph visually outlines how resources are connected.
For example, in this configuration with dependency references:
resource "local_file" "pet" {
filename = "/root/pets.txt"
content = "My favorite pet is ${random_pet.my-pet.id}"
}
resource "random_pet" "my-pet" {
prefix = "Mr"
separator = "."
length = "1"
}
Running the command produces:
$ terraform graph
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] local_file.pet (expand)" [label = "local_file.pet", shape = "box"]
"[root]"
provider["registry.terraform.io/hashicorp/local"] [label = "provider[\"registry.terraform.io/hashicorp/local\"]", shape = "diamond"]
"[root]"
provider["registry.terraform.io/hashicorp/random"] [label = "provider[\"registry.terraform.io/hashicorp/random\"]", shape = "diamond"]
"[root] random_pet.my-pet (expand)" [label = "random_pet.my-pet", shape = "box"]
"[root] local_file.pet (expand)" -> "[root] local_file.pet (expand)" [label = "provider[\"registry.terraform.io/hashicorp/local\"]"]
"[root] local_file.pet (expand)" -> "[root] random_pet.my-pet (expand)"
"[root] meta.count-boundary (EachMode fixup)" -> "[root] local_file.pet (expand)"
}
}
Graph Visualization
The DOT format may be challenging to interpret directly. Use a visualization tool like Graphviz to render a graphical version of the dependency graph.
Visualizing the Graph with Graphviz
Graphviz is a widely-used tool for converting DOT files into visual images. On Ubuntu, you can install Graphviz as follows:
$ apt update
$ apt install graphviz -y
After installation, pipe the output of the terraform graph
command into Graphviz's dot
command to create an SVG:
$ terraform graph | dot -Tsvg > graph.svg
Open the resulting graph.svg
file in your browser to see a visual representation of your resource dependencies. This helps in understanding how resources like the local file and random pet interact through dependency expressions.
That concludes our comprehensive look at essential Terraform commands. Use these tools to validate, format, and manage your infrastructure configurations effectively. Now, proceed to the hands-on labs to further explore and practice Terraform’s capabilities.
Watch Video
Watch video content
Practice Lab
Practice lab