[Terraform] Basics

Terraform is a tool for creating, updating, and versioning infrastructure locally or in the cloud by code.

Key Features

  • Infrastructure as Code – Automation
  • Execution Plans
  • Resource Graph

Terraform Workflow

  • Init
    • Initializes the working directory
    • Downloads providers, modules, and plugins
    • Sets up the backend for storing Terraform State
  • Plan
    • Reads the configuration and creates an execution plan
    • Allows a user to review the changes – execution plan – before applying them
    • Does not deploy any resources to the cloud yet
  • Apply
    • Deploys resources into real environments according to the execution plan
    • Updates Terraform State – state file
  • Destroy
    • Checks the stored Terraform State
    • Destroys all resources created by the configuration: non-reversible

Terraform CLI

You can access the features of Terraform using the terraform command and its sub-commands.

terraform version

terraform --help
terraform apply -h

# initialize the working dir
terraform init 
# reinitialize 
terraform init -upgrade

# display the execution plan: dry-run
terraform plan 
# save the plan as a file and pass it to "apply"
terraform plan -out {outfilename}
# display the destroy plan
terraform plan -destory 

# apply the changes
terraform apply 
terraform apply -auto-approve
# apply changes only to the specified resource
terraform apply -target={resource-name} 
# pass a variable via the command
terraform apply -var {variable}={value}
# pass variables via a file
terraform apply -var-file={file-name}

# check the output
terraform output

# deletes all managed resources
terraform destroy 

# get the provider info
terraform providers

Terraform Configuration File

One of the main use cases of Terraform is to provision cloud resources. You need to understand how you can specify your resources in the Terraform configuration files.

How Configuration is Applied

You can do the followings with the Terraform configuration.

  • Create
  • Update in-place
  • Destroy
  • Destroy and re-create

Terraform uses its own language (syntax) for configurations. It is called HashiCorp Configuration Language (HCL).

The basic structure is:

# Block
<TYPE> "<LABEL>" "<LABEL>" {
  # Body
  <IDENTIFIER> = <EXPRESSION>
}

Terraform can be the native format or the JSON format.

resource "docker_image" "nginx" {
  name = "nginx:latest"
}
{	
  "resource: {
    "docker_image": {
      "nginx" {
        "name": "nginx:latest"
      }
    }
  }
}

Providers

A Terraform provider is an integration layer that communicates with the Cloud infrastructure vendors via APIs.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}
 
provider "aws" {
  region  = "us-eat-1"
}

Modules

  • Terraform uses the .tf and/or .tf.json configuration files.
    • Configurations can be overridden by override files. They are merged together.
  • A module is a collection of configuration files in a directory.
  • A root module is a working directory where the Terraform is invoked.

Types of modules

  • Root Module
    • the starting point in the main directory
  • Child Modules
    • A nested directory is treated as a separate module. (root module + child modules)
  • Published Modules
    • loaded from a private or public registry

Calling a Child Module

You can use the “module” block in the parent module to call a child module.

  • You can give a name to refer to the module in the source directory.
  • Module Arguments
    • source: where to grab the module (required)
    • version: used for a module in a registry
    • input variable arguments
module "my_aws_instance" {
  source = "./aws-ec2"

  az_name = "us-east-1a"  
}

Module Sources

  • Local path
  • Terraform registry
  • GitHub, Bitbucket or Git repositories
  • HTTP URLs
  • S3 bucket
  • GCS buckets

Please check the examples here:

https://developer.hashicorp.com/terraform/language/modules/sources

Accessing Module Outputs

You can use the module name to access the output of it.

# module.{module_name}.{variable_name}

resources "aws_elb" "test" {
  instance_id = module.my_aws_instance.instance_id
}

Expressions

More than literal values, Terraform supports more complex expressions to represent the values using operators and functions.

Data Types

  • string
  • number
  • bool
  • list, tuple: [comma-separated array values]
  • map, object: { key:value pairs }
  • null

Expressions can be used

  • Resources
  • Input Variables
  • Local Values
  • Child Module Outputs
  • Data Sources
  • Filesystem and Workspace
  • Block-level Values

Types of Expressions

  • Conditional
  • Functions
# condition ? true_val : false_val
var.az != "" ? var.az : "us-east-1a"

# built-in functions
max(10, 99, 20)

Resources

The Resource block is where you describe infrastructure objects such as virtual networks, VM instances, etc…


States

Terraform needs to keep track of the differences between the configuration and the resources.

  • By default, the state is saved in the terraform.tfstate file in the local directory where terraform is run.
  • You can store the state file remotely by modifying the backend.
    • The remote state allows Terraform to write the data to a remote data storage such as S3.
    • The state data can be shared among all team members.
# terraform state <subcommand> {options}

terraform state list

terraform state show 'attribute_name'

terraform state rm 'object_name'

Built-in Functions

Terraform comes with pre-packaged functions to help you transform values.

https://developer.hashicorp.com/terraform/language/functions

Examples

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s