lesson ── terraform-beginner ── ~12 мин ── 3 шагов
When several resources share the same prefix, a set of tags, or a
computed value, copy-paste is a bad idea. HCL gives you two tools:
locals for named values inside HCL, and built-in functions for
transforming strings, numbers, and lists.
In this lesson you build a bucket name from a variable plus the current region, move shared tags into locals, and apply string functions to normalize values. This is the end of the beginner track. See tf-locals, tf-interpolation, tf-functions-string.
интерактивный sandbox
Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.
stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя
Create main.tf:
variable "env" {type = string
default = "dev"
}
data "aws_region" "current" {}locals { name_prefix = "linuxlab-${var.env}-${data.aws_region.current.name}" common_tags = {Project = "linuxlab-terraform-course"
Env = var.env
ManagedBy = "terraform"
}
}
resource "aws_s3_bucket" "logs" { bucket = "${local.name_prefix}-logs-${random_id.suffix.hex}"tags = local.common_tags
}
resource "aws_s3_bucket" "data_store" { bucket = "${local.name_prefix}-data-${random_id.suffix.hex}"tags = local.common_tags
}
resource "random_id" "suffix" {byte_length = 4
}
Notice:
local.name_prefix, assembled from a variable and a data source.local.common_tags, defined once, used twice.cd /home/student/tf-locals
terraform init -input=false
terraform apply -auto-approve -input=false
The prefix is `local.x` without the s: a common mistake. Declaration: `locals { ... }`, reference: `local.x`.
✓ Both buckets got the same set of tags through locals.
Add a file outputs.tf:
output "buckets_summary" {value = format(
"%s in region %s: logs=%s, data=%s",
upper(var.env),
data.aws_region.current.name,
aws_s3_bucket.logs.bucket,
aws_s3_bucket.data_store.bucket,
)
}
output "common_tags" {value = local.common_tags
}
Run:
terraform apply -auto-approve
terraform output buckets_summary
You get a string like:
"DEV in region us-east-1: logs=linuxlab-dev-us-east-1-logs-abc12345, data=linuxlab-dev-us-east-1-data-abc12345"
format(), this is sprintf. %s, a placeholder for a string.
upper(), raise to uppercase. These functions are pure: no side
effects, and they always return the same result for the same inputs.
More detail in tf-functions-string.
If apply complains about "inconsistent format": check that the number of %s matches the number of arguments after the spec.
✓ The output is built with format() from several sources: locals, data, and a variable.
S3 is not the only place where locals are handy. The same
common_tags and name_prefix fit nicely onto other AWS
resources that LocalStack emulates:
# IAM role with shared tags
resource "aws_iam_role" "events_handler" { name = "${local.name_prefix}-events-handler" tags = merge(local.common_tags, { Purpose = "events" }) assume_role_policy = jsonencode({Version = "2012-10-17"
Statement = [{Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }}]
})
}
# SQS queue, shared prefix, shared tags, its own Purpose
resource "aws_sqs_queue" "events" { name = "${local.name_prefix}-events" tags = merge(local.common_tags, { Purpose = "events-queue" })}
After this the beginner track closes. Intermediate topics:
terraform plan in the PR, apply after review.terraform test or terratest.The same holds on OpenTofu: locals and built-in functions work identically, and the syntax is identical. See tf-opentofu-parity.
You moved the shared prefix and tags into locals, used the
functions upper(), lower(), format() to normalize values, and
assembled a bucket name from several parts. The HCL is now DRY: add a
new resource and it picks up the shared tags automatically.
команды
terraform consolecheck the value of local.x before applyterraform plansee how locals expand into real valuesконцепции