Terraform 101
Who am I?
Craig Reeder
Cloud Engineer @
Uturn Data Solutions
You could also call me a Terraform Engineer
I write a lot of Terraform
What is Terraform?
It is an open source infrastructure as code software tool.
What does that mean?
It means that your infrastructure is represented as code.
Why?
Allows the provisioning to be automated, repeatable, and less error prone.
There's a lot of tools for this
Why Terraform?
Terraform is cross-platform
Terraform is cloud-agnostic
While we primarily use it for AWS, it can be used for much, much more.
Terraform is popular
This has lots of benefits as far as community support and documentations
So lets learn some Terraform!
First, some important concepts
What's a Provider?
Providers connect Terraform to to the underlying architecture
Terraform is just a tool to write configuration
The provider performs the "magic" of converting that configuration to the result
You can even order pizza with Terraform
The most common provider for our purposes is AWS
Other common ones are PostgreSQL, Cloudflare, and Kubernetes
What is a Resource?
A resource is one or more infrastructure objects that is implemented by the provider
Resources are the bread and butter of Terraform
resource "aws_instance" "example" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
tags = {
Name = "ExampleServer"
}
}
Resource - Type of resource - identifier of resource.
Resources have parameters
Parameters are for configuring a resource
resource "aws_instance" "example" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
tags = {
Name = "ExampleServer"
}
}
Resources have attributes
Attributes get information out of a resource
resource "aws_instance" "example" {
...
}
# You can later use this value
aws_instance.example.private_ip
How do I know the parameters and attributes for a specific resource?
Terraform Registry contains all public providers and documentation for them
Google search tends to work better for the registry
For example, search "Terraform AWS EC2 Instance"
Input Variables
Input variables allow for changing configuration values
variable "username" {
type = string
description = "Username to apply the changes to"
default = "Steve"
}
var.username
Variables can be set via environment variables, tfvars files, or passed during apply
If a variable doesn't have a default and isn't set it will prompt you on apply
Unlike other programming languages, variables cannot change during run-time
Local Values
Local values allow for a static value to be set during runtime
These are kind of like constants in other programming languages
locals {
department = "Operations"
}
local.department
Output Values
Can you guess what output values are?
Output values do exactly what they sound like
They allow you to get information out of the Terraform easily
output "public_ip" {
value = aws_instance.example.public_ip
}
Data Source
Data sources allow you to get information from a remote location into your terraform
Providers implement data sources, much like resources
A common data source is to get the most recent version of an AMI
data "aws_ami" "windows_server_2019" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["Windows_Server-2019-English-Full-Base-*"]
}
}
data.aws_ami.windows_server_2019.image_id
You can also use data sources to access another terraform project's resource information
State Files
Terraform keeps track of what it creates
It stores this in a statefile
This statefile contains all of the information about any resources created
You should never modify the statefile directly
Corrupting your state means that terraform doesn't know what exists
It may create new copies of infrastructure, or destroy the existing ones
With no additional configuration, statefiles are stored locally
In a file called "terraform.tfstate"
It's possible to move that state to a remote location
In AWS, we use S3 buckets (Object storage)
This enables multiple people to share a statefile to manage the same infrastructure
Modules
Modules allow you to reuse terraform code multiple times, in multiple places
Kind of like a software library, or a function
Modules use input variables as their parameters and output values as attributes
Modules can define multiple resources, or use multiple data sources
They can do anything any other terraform code can do
Modules can be sourced remotely or locally
This tells terraform where to find the code for a module
Modules are written in the same terraform code
module "servers" {
source = "../modules/example-cluster"
servers = 5
}
module.servers.ip_list
To know a modules parameters and attributes, you need to refer to it's documentation or code
We've written some terraform code now
How do we actually apply it?
First, you need to initialize
$ terraform init
You don't need to re-initialize every time you run, Terraform will generally tell you
To see the changes Terraform will make:
$ terraform plan
Planning will show you what terraform will change on apply, without changing anything
Ready to make your infrastructure changes?
$ terraform apply
This will prompt you for confirmation
Some final notes
Filenames don't matter in Terraform (only extensions)
All files with .tf will be combined for the apply
With Remote State comes Locking
Two people can't apply the the same project at the same time
In Terraform, your project is a module (even if it's used directly)
In the documentation, you'll see slightly different language
We Say → Terraform Docs
"Projects" → Root Modules
"Modules" → Child Modules
?