Terraform 3: HCL basics — blocks, arguments, expressions
easy⏱ 5 mincourseterraform
Blocks, labels and arguments
An HCL block has a type (resource), zero or more labels ("azurerm_resource_group", "orders"), and a body of argument = value pairs. The two labels on a resource are the provider type and a local name you use to reference it elsewhere.
# type label 1 (provider type) label 2 (local name)
resource "azurerm_resource_group" "orders" {
name = "myorg-orders-dev-rg" # argument = value
location = "westus2"
}
Expressions and references
Values can be expressions: string interpolation with ${...}, references to other blocks (azurerm_resource_group.orders.location), variables (var.env), and locals (local.name_prefix). This is how you avoid hard-coding — one source of truth flows everywhere.
variable "env" { default = "dev" }
variable "service" { default = "orders" }
locals {
name_prefix = "${var.env}-${var.service}" # "dev-orders"
}
resource "azurerm_resource_group" "orders" {
name = "myorg-${local.name_prefix}-rg" # references the local
location = "westus2"
}
resource "azurerm_storage_account" "orders" {
name = "myorgordersdev"
resource_group_name = azurerm_resource_group.orders.name # reference
location = azurerm_resource_group.orders.location # reference
account_tier = "Standard"
account_replication_type = "LRS"
}
References create dependencies
When block B references block A, Terraform infers B depends on A and creates A first. This implicit dependency graph — built from your expressions — is why you rarely need depends_on manually. Order in the file does not matter; references do.
Build a resource name like HCL would
Write resourceName(env: string, service: string, type: string): string that returns {env}-{service}-{type} (e.g. dev-orders-rg). Log resourceName("dev", "orders", "rg").