Filters
Zo zoek je
  • Gewone woorden vinden namen, teksten en voorbeelden.
  • "twee woorden" vindt precies die zin.
  • --naam of -x vindt een optie.
  • #woord zoekt alleen in commando's.
  • @grep vindt lessen en labs die grep gebruiken.
  • Filters: cat:network · in:labs · in:notes · level:rhcsa · ch:8 · root:yes. Zet ! voor een woord om het weg te laten. OR tussen woorden betekent één ervan.
  • ↑ ↓ bewegen · Enter openen · Esc sluiten · / zoeken

Hoofdstuk 5Naam in de cursus: Objective 4d–4e: complex types, expressions and functions

Use complex types, expressions and functions

Real configurations create many similar things: 5 subnets, 3 VMs, a rule per port. Complex types hold structured data, expressions and functions transform it, and count, for_each and dynamic blocks turn it into resources.

  • 5 Lessen
  • 1 Commando's

Dit deel is nog niet vertaald. Je ziet de Engelse tekst.

$ als gewone gebruiker# als root (of met sudo)

Vaardigheden in dit hoofdstuk

  • Complexe types, expressies, functies en dynamische blokken

5.1

Use complex types

Besides string, number and bool, variables can be lists, sets, maps, objects and tuples.

TypeExample value
list(string)["web", "app", "db"] (ordered, duplicates allowed)
set(string)["web", "app"] (no order, no duplicates)
map(string){ env = "dev", owner = "it" }
object({...}){ name = "web", size = "Standard_B2s", zone = 1 }
tuple([string, number])["web", 2]
variables.tf
variable "subnets" {
  type = map(object({
    prefix   = string
    nsg_open = list(number)
  }))
  default = {
    web = { prefix = "10.30.1.0/24", nsg_open = [80, 443] }
    app = { prefix = "10.30.2.0/24", nsg_open = [8080] }
  }
}

5.2

Create many resources with count and for_each

count makes N copies (index count.index). for_each makes one per map key or set item (key each.key, value each.value).

subnets.tf
resource "azurerm_subnet" "this" {
  for_each             = var.subnets
  name                 = "snet-${each.key}"
  resource_group_name  = azurerm_resource_group.app.name
  virtual_network_name = azurerm_virtual_network.app.name
  address_prefixes     = [each.value.prefix]
}
 
resource "azurerm_public_ip" "lb" {
  count               = var.env == "prod" ? 1 : 0
  name                = "pip-lb-${var.env}"
  location            = azurerm_resource_group.app.location
  resource_group_name = azurerm_resource_group.app.name
  allocation_method   = "Static"
  sku                 = "Standard"
}

Onthoud

Prefer for_each with stable keys. With count, removing an item in the middle shifts the index and Terraform replaces the following resources.

5.3

Write expressions

Expressions compute values: conditions, for expressions, splats and string templates.

examples.tf
locals {
  is_prod      = var.env == "prod"
  vm_size      = local.is_prod ? "Standard_D2s_v5" : "Standard_B2s"
  subnet_ids   = [for s in azurerm_subnet.this : s.id]
  upper_names  = { for k, v in var.subnets : k => upper(k) }
  open_ports   = flatten([for k, v in var.subnets : v.nsg_open])
  all_nic_ids  = azurerm_network_interface.web[*].id
  greeting     = "Hello from ${var.env}%{ if local.is_prod } (production)%{ endif }"
}
ExpressionMeaning
cond ? a : bChoose a or b
[for x in LIST : f(x)]A new list
{for k, v in MAP : k => f(v)}A new map
[for x in LIST : x if cond]Filter
resource[*].attrSplat: the attribute of all instances
"${…}", %{ if … }String templates

5.4

Use built-in functions

Terraform has many functions; you can not write your own. Try them in terraform console.

FunctionExample → result
lower, upper, replacelower("ShOp") → "shop"
join, splitjoin(",", ["a","b"]) → "a,b"
length, contains, lookuplookup(var.sizes, "dev", "B2s")
merge, concat, flatten, distinctmerge(local.tags, {app = "shop"})
cidrsubnet, cidrhostcidrsubnet("10.30.0.0/16", 8, 1) → "10.30.1.0/24"
file, templatefile, base64encodetemplatefile("cloud-init.tpl", {env = var.env})
try, can, coalescetry(var.cfg.size, "B2s")
jsonencode, yamldecodePolicies and config files

Commando's in deze les

5.5

Generate nested blocks with dynamic

A dynamic block writes repeated nested blocks (like NSG rules) from a list or map.

nsg.tf
resource "azurerm_network_security_group" "web" {
  name                = "nsg-web"
  location            = azurerm_resource_group.app.location
  resource_group_name = azurerm_resource_group.app.name
 
  dynamic "security_rule" {
    for_each = var.subnets["web"].nsg_open
    content {
      name                       = "allow-${security_rule.value}"
      priority                   = 100 + security_rule.key
      direction                  = "Inbound"
      access                     = "Allow"
      protocol                   = "Tcp"
      source_port_range          = "*"
      destination_port_range     = tostring(security_rule.value)
      source_address_prefix      = "Internet"
      destination_address_prefix = "*"
    }
  }
}

Let op

Dynamic blocks make code harder to read. Use them for real lists, not to hide two simple blocks.

Alle commando's in dit hoofdstuk