disasters :: dated :: notes

sed s/terraform/tofu

HCL language stuff

Some basic nice stuff:
# Get module basename:
basename(abspath(path.module))

: : : :

Iteration is kind of tricky in Terraform. You're only permitted to iterate over a set(string) OR a map(any). For this reason you will often see people projecting a set of objects into a mapping from an index (cast to string) to an objec

Provision a list of resources based on the contents of a map:

use each.key and each.value to access item key/values, respectively

# from a servicebus module
resource "azurerm_servicebus_subscription" "subscription" {
  for_each = local.topic_subscriptions
  # . . .
  topic_id = "${local.namespace_id}/topics/${each.key}"
  max_delivery_count = each.value.max_delivery_count
  lock_duration = each.value.lock_duration
}

: : : :

You can use the random provider to generate a password

Use the keepers property to manage regeneration

variable "password_timestamp" {
  description = "A description of the last time the dbadmin password was refreshed."
  type        = string
  default     = null
}
resource "random_string" "database_admin_password" {
  length           = 25
  special          = true
  min_lower        = 1
  min_upper        = 1
  min_numeric      = 1
  min_special      = 1
  override_special = "@!_%"
  keepers = {
    "last_generated" = var.password_timestamp
  }
}
output "admin_password" {
  value     = random_string.database_admin_password.result
  sensitive = true
}

: : : :

Interpolate defaults for an object with nullable fields

Here we use coalesce to do, you guessed it, null coalescence
variable "some_object_configurations" {
  type = map(object({
    rules     = optional(set(string))
    character = optional(string)
    stock     = optional(number)
    items     = optional(bool)
  }))
  default = {
    "example" = {}
  }
}
variable "some_object_config_defaults" {
  type = object({
    rules     = set(string)
    character = string
    stock     = number
    items     = bool
  })
  default = {
    rules = ["fox only", "no items", final destination"]
    character = "fox"
    stock = 4
    items = false
  }
}
locals {
  some_object_applied_configurations = { 
    for object_name, object_config in var.some_object_configurations:
      object_name => {
        for k, v in object_config:
          k => coalesce(v, var.some_object_config_defaults[k])
      }
  }
}

: : : :

Use null-resource to run some command

resource "null_resource" "example_env" {
  # ...
  provisioner "local-exec" {
    command = "echo $FOO $BAR $BAZ >> env_vars.txt"
    environment = {
      FOO = "bar"
      BAR = 1
      BAZ = "true"
    }
  }
}