Skip to content

Instantly share code, notes, and snippets.

@Mirakurun
Last active January 4, 2023 06:08
Show Gist options
  • Save Mirakurun/acad34de2985d4e458e6140a22172762 to your computer and use it in GitHub Desktop.
Save Mirakurun/acad34de2985d4e458e6140a22172762 to your computer and use it in GitHub Desktop.
Terraform Notes

Terraform Notes

Terraform Registry

https://registry.terraform.io/

Terraform CLI

https://www.terraform.io/docs/cli/index.html

Initializing Working Directories

https://www.terraform.io/docs/cli/commands/init.html

init

terraform init [options]

Create An Execution Plan

https://www.terraform.io/docs/cli/commands/plan.html

plan

terraform plan

Create Or Update Infrastructure

https://www.terraform.io/docs/cli/commands/apply.html

apply

terraform apply

Destroy Terraform-Managed Infrastructure

https://www.terraform.io/docs/cli/commands/destroy.html

destroy

terraform destroy [options]

Speculative Destroy Plan

terraform plan -destroy

⚠️Note: Commenting out code can also destroy resources

Console

https://www.terraform.io/docs/cli/commands/console.html

console

The terraform console command provides an interactive console for evaluating expressions.

terraform console [options]

AWS Provider

https://registry.terraform.io/providers/hashicorp/aws/latest/docs

//main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region = "us-east-1"
  access_key = "my-access-key"
  secret_key = "my-secret-key"
}

AWS Resource

https://www.terraform.io/docs/language/resources/index.html

Instance

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
}

Input Variables

https://www.terraform.io/docs/language/values/variables.html

Input variables serve as parameters for a Terraform module, allowing aspects of the module to be customized without altering the module's own source code, and allowing modules to be shared between different configurations.

Declaring a Variable:

//variables.tf
variable "image_id" {
  type        = string
  description = "The id of the machine image (AMI) to use for the server."
}

Variables on the Command Line

To specify individual variables on the command line, use the -var option when running the terraform plan and terraform apply commands:

terraform apply -var="image_id=ami-abc123"
terraform apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
terraform apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}'

Variable Definitions (.tfvars) Files

image_id = "ami-abc123"
availability_zone_names = [
  "us-east-1a",
  "us-west-1c",
]

To set lots of variables, it is more convenient to specify their values in a variable definitions file (with a filename ending in either .tfvars or .tfvars.json) and then specify that file on the command line with -var-file:

terraform apply -var-file="testing.tfvars"

Terraform also automatically loads a number of variable definitions files if they are present:

  • Files named exactly terraform.tfvars or terraform.tfvars.json.
  • Any files with names ending in .auto.tfvars or .auto.tfvars.json.

Environment Variables

This can be useful when running Terraform in automation, or when running a sequence of Terraform commands in succession with the same variables. For example, at a bash prompt on a Unix system:

export TF_VAR_image_id=ami-abc123
terraform plan

Output

https://www.terraform.io/docs/language/values/outputs.html

Output values are like the return values of a Terraform module, and have several uses:

  • A child module can use outputs to expose a subset of its resource attributes to a parent module.
  • A root module can use outputs to print certain values in the CLI output after running terraform apply.
  • When using remote state, root module outputs can be accessed by other configurations via a terraform_remote_state data source.

Each output value exported by a module must be declared using an output block:

output "instance_ip_addr" {
  value = aws_instance.server.private_ip
}

Locals

https://www.terraform.io/docs/language/values/locals.html

locals {
  service_name = "forum"
  owner        = "Community Team"
}

Expressions

References to Values

https://www.terraform.io/docs/language/expressions/references.html

Resource

<RESOURCE TYPE>.<NAME>

Input Variables

var.<NAME>

Local Values

local.<NAME>

Child Module Outputs

module.<MODULE NAME>.<OUTPUT NAME>

Data Sources

data.<DATA TYPE>.<NAME>

Resource Attributes

<RESOURCE TYPE>.<NAME><ATTRIBUTE>

Example:

aws_instance.example.ami

resource "aws_instance" "example" {
  ami           = "ami-abc123"
  instance_type = "t2.micro"

  ebs_block_device {
    device_name = "sda2"
    volume_size = 16
  }
  ebs_block_device {
    device_name = "sda3"
    volume_size = 20
  }
}

Types

https://www.terraform.io/docs/language/expressions/types.html

The Terraform language uses the following types for its values:

  • string: a sequence of Unicode characters representing some text, like "hello".
  • number: a numeric value. The number type can represent both whole numbers like 15 and fractional values like 6.283185.
  • bool: a boolean value, either true or false. bool values can be used in conditional logic.
  • list (or tuple): 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.
  • map (or object): a group of values identified by named labels, like {name = "Mabel", age = 52}.

Strings, numbers, and bools are sometimes called primitive types. Lists/tuples and maps/objects are sometimes called complex types, structural types, or collection types.

Finally, there is one special value that has no type:

null: a value that represents absence or omission. If you set an argument of a resource or module to null, Terraform behaves as though you had completely omitted it — it will use the argument's default value if it has one, or raise an error if the argument is mandatory. null is most useful in conditional expressions, so you can dynamically omit an argument if a condition isn't met.

Indices and Attributes

Indices

var.<LIST>[0] or local.<LIST>[1]

Attributes

local.<MAP>["keyname"]

Conditional Expressions

https://www.terraform.io/docs/language/expressions/conditionals.html

condition ? true_val : false_val

Modules

Meta-Arguments

https://www.terraform.io/docs/language/meta-arguments/count.html

count

resource "aws_instance" "server" {
  count = 4 # create four similar EC2 instances

  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"

  tags = {
    Name = "Server ${count.index}"
  }
}

When count is set, Terraform distinguishes between the block itself and the multiple resource or module instances associated with it. Instances are identified by an index number, starting with 0.

<TYPE>.<NAME>[<INDEX>] (for example, aws_instance.server[0], aws_instance.server[1], etc.) refers to individual instances.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment