# locals: вычисляемые внутренние имена _Переменные и outputs · TerraformLab Knowledge Base_ **TL;DR:** locals: блок с именами, видимыми только внутри HCL (не вход, не выход). Удобны для DRY: один раз сосчитал общий префикс или теги: везде используешь через local.x. Не путать с variable (вход) и output (выход). ## variable vs locals vs output Три родственных, но разных вещи: - **variable**, **вход**. Значение приходит снаружи (CLI, .tfvars, env). - **locals**, **внутреннее**. Вычисляется из других значений, видно только в этом HCL. - **output**, **выход**. Значение видно после apply / другим модулям. Если значение приходит извне, variable. Если вы его используете в нескольких местах после вычисления, locals. Если хотите показать наружу, output. ## Базовый синтаксис ```hcl variable "env" { type = string default = "dev" } variable "app_name" { type = string default = "my-app" } locals { name_prefix = "${var.app_name}-${var.env}" common_tags = { Project = var.app_name Environment = var.env ManagedBy = "terraform" } } resource "aws_s3_bucket" "logs" { bucket = "${local.name_prefix}-logs" tags = local.common_tags } resource "aws_s3_bucket" "data" { bucket = "${local.name_prefix}-data" tags = local.common_tags } ``` Каждый ресурс использует общий префикс и общие теги, не повторяя себя. Префикс, `local.имя` (без `s`!). Объявление, `locals { ... }` (со `s`). ## Локалы могут ссылаться на другие локалы ```hcl locals { base_name = "${var.app_name}-${var.env}" bucket_name = "${local.base_name}-bucket" log_prefix = "${local.bucket_name}/logs/" } ``` Цепочка вычисляется автоматически. Terraform строит граф и разрешает зависимости. ## Локалы могут содержать сложные выражения ```hcl locals { enable_https = var.env == "prod" || var.env == "staging" azs = data.aws_availability_zones.available.names instance_count = var.env == "prod" ? 3 : 1 subnet_cidrs = [ for i in range(local.instance_count) : cidrsubnet(var.vpc_cidr, 8, i) ] } ``` Можно условия, циклы, функции, всё что разрешено в HCL expressions. См. [tf-conditional-expression](/terraform/kb/tf-conditional-expression.md) и [tf-functions-collection](/terraform/kb/tf-functions-collection.md). ## Несколько `locals` блоков, нормально ```hcl # general.tf locals { name_prefix = "${var.app_name}-${var.env}" } # tags.tf locals { common_tags = { Project = var.app_name Environment = var.env } } # network.tf locals { public_subnet_count = 3 } ``` В одном проекте может быть сколько угодно `locals` блоков. Terraform мерджит их в один namespace `local.*`. Это удобно для разделения по файлам. Но: имена в разных `locals` блоках **не должны пересекаться**. `local.foo = "a"` в одном файле и `local.foo = "b"` в другом, ошибка валидации. ## Когда использовать локалы Хорошие случаи: - **Общий префикс имён.** `${local.name_prefix}-bucket`, `${local.name_prefix}-role`, и так далее. - **Общие теги.** Одна map с тегами проекта, прикладывается к каждому ресурсу. - **Вычисления из нескольких переменных.** Из `env` и `region` слепить ARN, например. - **Условная логика.** `local.enable_https = var.env == "prod"`. - **Преобразования.** `local.azs = data.aws_availability_zones.available.names`, короткое имя для длинного выражения. Когда **не** надо: - Если значение используется один раз, пишите inline. - Если значение приходит снаружи, это variable. ## Подводные камни - **locals не для секретов.** Они хранятся в state в открытом виде, без какого-либо `sensitive`-маркера (sensitive есть только у variable и output). - **locals не могут ссылаться на сами себя.** `local.x = local.x + 1`, ошибка. Terraform, не язык программирования с итеративным состоянием. - **Не злоупотребляйте.** Если в HCL половина файла, это блок `locals`, кодcчитать сложнее. Это знак, что часть значений лучше вынести в variables. - **`local` vs `locals`, путаница.** Объявление, `locals { ... }` (множественное). Использование, `local.x` (единственное, без `s`). Никаких `local.x` без `local` префикса и никаких `locals.x` с `s`. - **Локалы не доступны в .tfvars.** В .tfvars пишутся только variables. Локалы вычисляются в HCL. - **При переименовании local, появляется в diff?** Нет. Локалы не хранятся в state, только в выражениях. Поменяли имя. Terraform пересчитает все ссылки, в облако ничего не уйдёт (если итоговое значение не поменялось). ## Команды ```bash terraform console ``` Интерактивный REPL: можно проверить значение local.x в expressions. Удобно для отладки сложных выражений. ```bash terraform plan ``` В выводе plan видно итоговые значения, в которые развернулись локалы: полезно убедиться что префикс собрался правильно. ## См. также - [Блок variable: вход в конфигурацию](/terraform/kb/tf-variable.md) - [Блок output: что Terraform возвращает наружу](/terraform/kb/tf-output.md) - [Ссылки в HCL: как читать aws_s3_bucket.demo.bucket](/terraform/kb/tf-references.md) - [${...}: подстановка значений в строки](/terraform/kb/tf-interpolation.md)