Image

Terraform

Core Files

-- main.tf #Main entrypoint
-- providers.tf #Required providers
-- variables.tf #Variables for resources at runtime
-- ouputs.tf #Select output of resources, if needed
-- terraform.tsstate #Read-only file that displays the current state of the project (generated automatically)

Terraform Commands

Initialize the provider and download plugins for provider for the configurations.

terraform init

Builds an execution plan (does not change or create) to preview the results

terraform plan

Applies the current configuration and shows what it will create or destroy based on the difference with the new and the old.

terraform apply

Similar to apply, but behaves as if all resources have been removed from the configuration.

terraform destroy

Format your .tf file(s).

terraform fmt

Common Patterns

Main.tf Patterns

resource "resource_type" "resource_name" {
    #Resource specific arguments
}

# Exmple

resource "google_compute_instance" "my_instance" {
    name = "test"
    machine_type = "e2-medium"
    zone = "us-central1-a"
    boot_disk {
        initialize_params {
            image = "debian-cloud/debian-9"
        }
    }
}

Providers.tf Patterns

Specify the provider your IaC will use. The provdiers will have their own specific APIs.

terraform {
    required_providers {
        google = {
            source = "hashicorp/google"
            version = "4.23.0"
        }
    }
}

provider "google" {
    # Configuration options
    project = <project_id>
    region = "us-central1"
}

Output.tf Patterns

You may need to use the output of some resource, for example a storage bucket’s self-link. These will be printed to the terminal when command apply completes successfully.

output "bucket_URL" {
    value = google_storage_bucket.mybucket.URL
}

Example:

output "network_IP" {
  value = google_compute_instance.vm_instance.instance_id
  description = "The internal ip address of the instance"
}
output "instance_link" {
  value = google_compute_instance.vm_instance.self_link
  description = "The URI of the created resource."
}

Accessing Resource from Another Resource

To access a resource within another, e.g. refer to network from a subnet. Use <resource_type>.<resource_name>.<attribute>.

Example:

// if the name of a network is "vpc_network", and you need to refer to it within a subnet resource:
network = google_compute_network.vpc_nework.id

Meta-arguments

  • count Create multiple instances according to the value assigned to the count.
  • for_each Create multiple resource instances as per a set of strings.
  • depends_on Specify explicit dependency.
  • lifecycle Define life cycle of a resource (useful when needing to create a resource before destroying one in other to maintain high availability).
  • provider Select a non-default provider configuration.

Explicit Dependency

To determine dependencies between resources otherwise not known to Terraform, use the depends_on argument.

Example, one client VM that explicitly depends on a server VM:

resource "google_compute_instance" "client" {
    // ...
    depends_on = [google_compute_instance.server]
}

resource "google_compute_instance" "server" {
    // server config...
}

Variables (values for apply or runtime phase)

To access variables in a resource, use the var. notation.

Example syntax:

variable "variable_name" {
    type        = <variable_type>
    description = "<variable description>"
    default     = "<default value for the variable>"
    sensitve    = true
}

Example use:

// main.tf
resource "google_storage_bucket" "my_bucket1" {
    // ...
    storage_class = var.bucket_storage_class
}

// variables.tf
variable "bucket_storage_class" {
    // ...
    default = "REGIONAL" // default value can be overriden by assigning a value in environment values or .tfvars files or `var.` option.
}

To make use of variables explicitly for runtime, use the terraform.tfvars file.

Here you must define the variables in a key = "value" pattern.

To apply in a command, use tf apply -var-file my-vars-tf or tf apply -var="mybucket_storage_class=REGIONAL"

Sensitive Variables (secrets)

Set sensitive to true in order to avoid exposure of secrets.

variable "user_information" {
    type = object({
        api_key_gcp    = string
        api_key_ms     = string
    })
    sensitive = true
}

resource "some_resource" "foo" {
    api_key_gcp    = var.user_information.api_key_gcp
    api_key_ms = var.user_information.api_key_ms
}

Dependency Graph

To create a dependency graph of the current Terraform:

terraform graph | dot -Tsvg > graph.svg

https://developer.hashicorp.com/terraform/internals/graph

Storing State in Bucket

You can store state locally or in a bucket. To store the state in a bucket, a bucket resource must be created and delegated to the backend.

provider "google" {
  project     = "qwiklabs-gcp-04-7cccf18fd186"
  region      = "us-central-1"
}
resource "google_storage_bucket" "test-bucket-for-state" {
  name        = "qwiklabs-gcp-04-7cccf18fd186"
  location    = "US"
  uniform_bucket_level_access = true
}
terraform {
  backend "gcs" {
    bucket  = "qwiklabs-gcp-04-7cccf18fd186"
    prefix  = "terraform/state"
  }
}

© Filip Niklas 2024. All poetry rights reserved. Permission is hereby granted to freely copy and use notes about programming and any code.