Terraform Cheatsheet | Programster's Blog (2023)

Terraform

Related Posts / Resources

  • GitHub - Terraform Examples - Some example Terraform scripts to allow you to quickly get started with various scenarios.
  • Use S3 To Store Terraform State
  • Use PostgreSQL To Store Terraform State

Table Of Contents

  1. Installation
    1. PPA Install
    2. Snap Install
  2. Files
    1. File Extension
    2. Gitignore
  3. Commands
    1. Plan
    2. Apply
    3. Init
    4. Destroy
    5. Refresh (Sync)
    6. Graph
    7. Taint
  4. AWS Authentication
  5. Basic Example
  6. Variables
    1. Types
    2. Set Values In File
    3. Multi-line Variables
  7. Outputs
    1. Sensitive Outputs
    2. Sensitive Output Retrieval
  8. String Substitution
  9. Functions
  10. Locals
  11. Misc
    1. Language
    2. Packer

Installation

PPA Install

The following chained commands will install the Hashicorp GPG key, add their PPA, and use that to install Terraform.

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - \ && sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" \ && sudo apt-get update && sudo apt-get install terraform -y

This will install Terraform version 1.0.0 at the time of updating this post.

Snap Install

You can install the the terraform CLI tool con Ubuntu 20.04 by running:

sudo snap install terraform

... however, this will install Terraform v0.11.11 which will not work with some of the examples I provide, which need 0.12+.

Files

File Extension

Terraform files should have the .tf extension

Gitignore

Terraform will create the following files/folders that you may wish to add to your .gitignore file.

(Video) Terraform Advance Tutorial | Part Out 1 Out 21

  • .terraform
  • .tfstate
  • .tfstate.backup

Commands

Plan

The terraform plan command will tell you what changes are going to be made. Run this command before running terraform apply, which actually applies the changes.

Apply

terraform apply
  • Applies the changes that terraform plan says it would make.

Init

terraform init
  • Sets up the area for terraform.
  • Can be run multiple times without issue.

Destroy

terraform destroy

This command completely destroys/removes anything that Terraform set up.

Refresh (Sync)

terraform refresh

This command refreshes the state from how the infrastructure is actually deployed. This will sync down changes that may have occurred in the field. E.g. perhaps someone manually deleted an S3 bucket from the web console.

Graph

  • Run the terraform graph command to map out the dependencies in your terraform setup. This will be output in DOT language which you can visualize by using GraphvizOnline.

Taint

  • Run the terraform taint command to mark a resource as "tainted". This allows you to force it to be replaced the next time you run terraform plan and terraform apply.
    • This is useful when you push an update to a docker image, which an EC2 image uses, but only fetches it when it is getting deployed etc.
    • Example usage: terraform taint aws_instance.my_compute_instance

AWS Authentication

To use terraform with AWS, you will need to provide it with your access key and secret. You can do this by running:

export AWS_ACCESS_KEY_ID=yourKeyIdexport AWS_SECRET_ACCESS_KEY=yourKeySecret

Basic Example

The following terraform file will deploy a basic webserver (in London) that runs on port 8080 and will just respond with "Hello World". To "run" it, execute terraform apply.

provider "aws" { region = "eu-west-2"}# Create security group to allow port 8080resource "aws_security_group" "instance" { name = "terraform-example-instance" ingress { from_port = 8080 to_port = 8080 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] }}# Create the ubuntu 20.04 EC2 webserver resource # that uses the above security groupresource "aws_instance" "example" { ami = "ami-05c424d59413a2876" instance_type = "t2.micro" vpc_security_group_ids = [aws_security_group.instance.id] user_data = <<-EOF #!/bin/bash /usr/bin/sleep 10 /usr/bin/echo "Hello, World" > index.html /usr/bin/nohup /usr/bin/busybox httpd -f -p 8080 & EOF tags = { Name = "terraform-example" }}

If you wish to change the region, you will also need to change the AMI ID as AMIs are tied to regions.

After executing that successfully, log into your amazon web console, find the instance to find its IP address and go to that in your browser with :8080 on the end.

You should see "Hello World" in your browser. If it doesn't appear, just wait a bit. It takes quite a while before its ready, especially after I had to put in a sleep to make the script work.

Variables

Variables can be defined like so:

(Video) Terraform Advance Tutorial | Part Out 2 Out 21

variable "aws_region" { type = string description = "The region to deploy to. E.g. eu-west-2 for London." default = "eu-west-2"}

You don't have to provide a default or description. They just help when it comes to someone specifying the values.

Types

  • string
  • number
  • bool
  • list - a sequence of values, like ["us-west-1a", "us-west-1c"]. Elements in a list or tuple are identified by consecutive whole numbers, starting with zero.
  • tuple (alias of list)
  • map - a group of values identified by named labels. E.g. {name = "Mabel", age = 52}
  • object - alias of map

Set Values In File

To automatically provide the values for the variables, it is good to create a file with the .tfvars extension, with values for the variables. E.g.

aws_region="eu-west-2"

Be sure to add these .tfvars files to your .gitignore files.

Multi-line Variable

If you need to provide a multi-line string for a variable, when using a .tfvars file, one can just make use of heredoc strings like so:

example = <<-EOT-----BEGIN PUBLIC KEY-----line1line2line3-----END PUBLIC KEY-----EOT

If not using a .tfvars file, then refer to this StackOverflow post.

Outputs

After you create resources using Terraform, you will likely need to know their names/identifiers to then start using them. E.g. you need to know the IP address of the EC2 server you just deployed.You do this by declaring an output block. E.g.

output "my_ec2_ip" { value = aws_eip.my_elastic_ip.public_ip}

This will cause them to be printed out out at the end of performing a terraform apply operation.

Show Outputs

You can run the command:

terraform output

... which will just print out the outputs.

(Video) 5 Lessons Learned From Writing Over 300,000 Lines of Infrastructure Code

You can also use the command:

terraform show

... which will print out more, with the outputs at the very end.

Sensitive Outputs

You can mark some outputs as sensitive so that they will be hidden from the output. Some attributes, like AWS IAM credentials have to be marked as sensitive in order to have them as an output, otherwise terraform apply won't even run.

Retrieval

You may notice that the sensitive outputs are hidden (showing myOutputName = <sensitive>) when you run the commands to show outputs.

In order to be able to retrieve these sensitive values, you can just add the -json flag like so:

terraform output -json

or

terraform show -json

That will output a massive JSON from which you would have to find your sensitive values.

If you just want a specific output you can just specify it, and it will not be hidden.

terraform output mySensitiveOutputName

If using terraform show you can save yourself a lot of effort trying to find the needle with the help of jq like so:

(Video) Terraform Advance Tutorial | Part Out 3 Out 21

terraform show -json | jq '.values.outputs.name_of_my_output'

E.g. if the name of your output was my_super_secret_thing, then you would need:

terraform show -json | jq '.values.outputs.my_super_secret_thing'

... or if you just want to see all of the outputs, you can use:

terraform show -json | jq '.values.outputs'

String Substitution

This is best demonstrated with an example. Below, I am creating the value by using both a dynamic resource ID, and an input variable, with fixed/known string content

output "ecr_registry" { value = "${aws_ecr_repository.compute_engine_ecr.registry_id}.dkr.ecr.${var.aws_region}.amazonaws.com"}

Functions

The Terraform language doesn't support user-defined functions, but has a number of built-in functions that can be used in expressions to transform and combine values.

For example, the merge command is very commonly useful:

tags = merge({Name = "NameForMyThing"}, local.common_tags)

To see the full list of functions, refer to the docs functions page, and look to the pane on the left for the various types.

Locals

Refer to: Terraform Locals: What Are They, How to Use Them [Examples]

Misc

Language

The "language" is called HCL (Hashicorp Configuration language).

Packer

Packer is HashiCorp's (the makers of Terraform) open-source tool for creating machine images from source configuration. You can configure Packer images with an operating system and software for your specific use-case.

(Video) Terraform Advance Tutorial | Part Out 11 Out 21

References

Last updated: 13th January 2023
First published: 24th September 2020

Videos

1. Terraform Advance Tutorial | Part Out 7 Out 21
(TheDevOpsSchool)
2. How to visualize your terraform code using Terraform Graph
(LetMeTechYou)
3. Terraform Advance Tutorial | Part Out 12 Out 21
(TheDevOpsSchool)
4. Terraform — VCS Workflows
(ExamPro)
5. Terraform Advance Tutorial | Part Out 8 Out 21
(TheDevOpsSchool)
6. Terraform Advance Tutorial | Part Out 6 Out 21
(TheDevOpsSchool)
Top Articles
Latest Posts
Article information

Author: Jeremiah Abshire

Last Updated: 02/04/2023

Views: 5321

Rating: 4.3 / 5 (54 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Jeremiah Abshire

Birthday: 1993-09-14

Address: Apt. 425 92748 Jannie Centers, Port Nikitaville, VT 82110

Phone: +8096210939894

Job: Lead Healthcare Manager

Hobby: Watching movies, Watching movies, Knapping, LARPing, Coffee roasting, Lacemaking, Gaming

Introduction: My name is Jeremiah Abshire, I am a outstanding, kind, clever, hilarious, curious, hilarious, outstanding person who loves writing and wants to share my knowledge and understanding with you.