linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/lessons/tf-beginner-10-locals-and-functions

lesson ── terraform-beginner ── ~12 мин ── 3 шагов

locals и функции: убираем дублирование в HCL

Когда несколько ресурсов используют один и тот же префикс, набор тегов или вычисленное значение, копипастить плохо. HCL даёт два инструмента: locals для именованных значений внутри HCL и встроенные функции для трансформации строк, чисел, списков.

В этом уроке слепим имя бакета из переменной + текущего региона, общие теги вынесем в locals, и применим строковые функции для нормализации. Это финал beginner-трека. См. tf-locals, tf-interpolation, tf-functions-string.

▶ интерактивный sandbox

Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.

запустить sandbox →

stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Вынеси префикс в locals

    Создай main.tf:

    hcl
    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
    }

    Заметь:

    • local.name_prefix, собирается из переменной и data.
    • local.common_tags, один раз, два раза используется.
    • Если завтра поменяешь префикс, поменяешь в одном месте.
    bash
    cd /home/student/tf-locals
    terraform init -input=false
    terraform apply -auto-approve -input=false
    подсказка

    Префикс `local.x` без s: типичная ошибка. Объявление: `locals { ... }`, ссылка, `local.x`.

    ✓ Оба бакета получили один и тот же набор тегов через locals.

  2. 02

    Добавь специфичные теги через merge

    Сейчас оба бакета имеют одинаковые теги. Иногда нужно к общим добавить специфичный, например, Purpose у каждого свой. Для этого функция merge():

    Открой main.tf и поменяй блоки tags:

    hcl
    resource "aws_s3_bucket" "logs" {
      bucket = "${local.name_prefix}-logs-${random_id.suffix.hex}"
      tags = merge(local.common_tags, {
        Purpose = "logs"
      })
    }
    resource "aws_s3_bucket" "data_store" {
      bucket = "${local.name_prefix}-data-${random_id.suffix.hex}"
      tags = merge(local.common_tags, {
        Purpose = "data"
      })
    }

    merge(map1, map2), слить две map в одну. При коллизии ключей, второй перебивает первый. Подробнее, в tf-functions-collection.

    Применить:

    bash
    terraform apply -auto-approve

    Plan покажет ~ change с добавленным тегом Purpose у каждого бакета.

    подсказка

    merge: встроенная функция, обычные скобки. Не путать с {{merge}}: HCL, не Jinja.

    ✓ У logs теперь Purpose=logs, у data_store. Purpose=data. Остальные теги общие.

  3. 03

    Финальный output с функциями

    Добавь файл outputs.tf:

    hcl
    output "buckets_summary" {
      value = format(
        "%s в регионе %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
    }

    Запусти:

    bash
    terraform apply -auto-approve
    terraform output buckets_summary

    Получишь строку вида:

    "DEV в регионе us-east-1: logs=linuxlab-dev-us-east-1-logs-abc12345, data=linuxlab-dev-us-east-1-data-abc12345"

    format(), это sprintf. %s, placeholder для строки. upper()

    • поднять в верхний регистр. Эти функции pure: без побочных эффектов, всегда возвращают одно и то же на одних входах.

    Подробнее, tf-functions-string.

    подсказка

    Если apply жалуется на «inconsistent format»: проверь, что число %s совпадает с числом аргументов после spec.

    ✓ Output собран через format() из нескольких источников: locals, data, переменной.

    locals + другие ресурсы: IAM, SQS, Lambda

    S3, не единственное место, где удобны locals. Тот же common_tags и name_prefix отлично ложатся на другие AWS-ресурсы, которые LocalStack эмулирует:

    hcl
    # IAM-роль с общими тегами
    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-очередь, общий префикс, общие теги, своё Purpose
    resource "aws_sqs_queue" "events" {
      name = "${local.name_prefix}-events"
      tags = merge(local.common_tags, { Purpose = "events-queue" })
    }

    Дальше, beginner-трек закрывается. Темы intermediate:

    • Модули, выделить эту группу ресурсов в переиспользуемое целое. Базовая практика любого реального проекта.
    • Remote state, перенести state в S3 для командной работы.
    • CI/CD, terraform plan в PR, apply после ревью.
    • Testing, нативный terraform test или terratest.

    То же самое на OpenTofu, locals и встроенные функции работают идентично, синтаксис идентичен. См. tf-opentofu-parity.

    • → locals целиком
    • → Строковые функции
    • → Функции коллекций
    • → OpenTofu parity

Что ты узнал

Ты вынес общий префикс и теги в locals, использовал функции upper(), lower(), format() для нормализации, и собрал имя бакета из нескольких частей. HCL стал DRY: добавишь новый ресурс, он автоматически получит общие теги.

команды

  • terraform consoleпроверить значение local.x перед apply
  • terraform planувидеть как локалы развернулись в реальные значения

концепции

  • · locals: внутренние имена, видны только внутри HCL
  • · merge() для слияния общих и специфичных тегов
  • · Функции pure: без побочных эффектов, можно вкладывать

← предыдущий

OIDC, IAM-роль для CI без access-keys

следующий →

preconditions, postconditions и check блок

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки