Terraform Basics
Providers
are for interacting with remote systems, like cloud providers, and call APIs. terraform init
will install providers.
Provider Config
provider "aws" {
access_key = var.aws_access_key
secret_key = var.aws_secret_key
region = "us-east-1"
}
Resources
describe infrastructure objects and are implemented by a provider.
- resource type: “aws_instance”
- resource name: “server”
- resource argument: “ami”, “instance_type”, “tags”
- Meta_Argument: “count”
Use the <RESOURCE TYPE>.<NAME>.<ATTRIBUTE>
to access attributes.
Provisioners
are used to run some commands when the resource is created/destroyed. Generally not recommnended by Terraform.
resource "aws_instance" "server" {
count = 4 # create four similar EC2 instances
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
tags = {
Name = "Server ${count.index}"
}
provisioner "local-exec" {
command = "echo The server's IP address is ${self.private_ip}"
}
}
Meta-Arguemnts
- depends_on
- count
- for_each
- provider
- lifecycle
- provisioner
Data Sources
are essentially read only resources. Usually provided alongside with resource type for accessing info via data.<TYPE>.<NAME>.<ATTRIBUTE>
.
data "aws_ami" "example" {
most_recent = true
owners = ["self"]
tags = {
Name = "app-server"
Tested = "true"
}
}
Meta-Arguemnts
- depends_on
- count
- for_each
- provider
- provisioner
Variables, Outputs and Values
Input Variables
serve as parameters for a Terraform module, like function arguments, and can be accessed via var.<NAME>
.
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"
}
]
}
Optional arguments
- default
- type
- description
- validation
- sensitive
- nullable
Varialbes in root modudule can be assigned with .tfvars
file. Also, terraform searches for environment variables named TF_VAR_
followed by the name of a declared variable.
image_id = "ami-abc123"
availability_zone_names = [
"us-east-1a",
"us-west-1c",
]
Output Values
are like return values for a Terraform module, like function return values. In a parent module, outputs of child modules are available in expressions as module.<MODULE NAME>.<OUTPUT NAME>
.
output "instance_ip_addr" {
value = aws_instance.server.private_ip
}
Optional arguments
- description
- precondition
- sensitive
- depends_on
Local Values
are a convenience feature for assigning a short name to an expression, like local variable. A set of related local values can be declared together in a single locals block and can be referenced as local.<NAME>
.
locals {
service_name = "forum"
owner = "Community Team"
}
locals {
# Ids for multiple sets of EC2 instances, merged together
instance_ids = concat(aws_instance.blue.*.id, aws_instance.green.*.id)
}
locals {
# Common tags to be assigned to all resources
common_tags = {
Service = local.service_name
Owner = local.owner
}
}
Modules
Modules are containers for multiple resources that are used together. A module consists of a collection of .tf
and/or .tf.json
files kept together in a directory.
Calling a child module with specific values for its input variables.
module "consul" {
source = "hashicorp/consul/aws"
version = "0.0.5"
servers = 3
}
Accessing module output values via module.<NAME>.<OUTPUT NAME>
.
Meta-Arguments
-
source
argument is mandatory for all modules. -
version
argument is recommended for modules from a registry. - count
- for_each
- providers
- depends_on
Module Sources
The source
argument in a module block tells Terraform where to find the source code for the desired child module.
Local Paths
A local path must begin with either ./
or ../
to indicate that a local path is intended
module "consul" {
source = "./consul"
}
Terraform Registry
Modules on the public Terraform Registry can be referenced using a registry source address of the form <NAMESPACE>/<NAME>/<PROVIDER>
.
module "consul" {
source = "hashicorp/consul/aws"
version = "0.1.0"
}
GitHub
Terraform will recognize unprefixed github.com
URLs and interpret them automatically as Git repository sources.
module "consul" {
source = "github.com/hashicorp/example"
}
module "consul" {
source = "hashicorp/consul/aws"
version = "0.1.0"
}