Метааргумент count
В одном блоке ресурса или модуля нельзя использовать count вместе с enabled или for_each.
По умолчанию блок ресурса настраивает один реальный объект инфраструктуры. (Аналогичным образом блок модуля включает содержимое дочернего модуля в конфигурацию один раз.) Однако иногда требуется управлять несколькими похожими объектами (например, фиксированным пулом вычислительных экземпляров), не создавая отдельный блок для каждого из них. OpenTofu предлагает два способа сделать это: count и for_each.
Если блок ресурса или модуля содержит аргумент count со значением — целым числом, OpenTofu создаст указанное количество экземпляров.
Основной синтаксис
count — это метааргумент, определённый языком OpenTofu. Его можно использовать с модулями и ресурсами любого типа.
Метааргумент count принимает целое число и создаёт указанное количество экземпляров ресурса или модуля. С каждым экземпляром связан отдельный объект инфраструктуры; при применении конфигурации каждый из них создаётся, обновляется или уничтожается независимо.
resource "aws_instance" "server" {
count = 4 # create four similar EC2 instances
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
tags = {
Name = "Server ${count.index}"
}
}Если вы используете count = var.enabled ? 1 : 0, чтобы условно включать или отключать один ресурс или модуль, рассмотрите возможность вместо этого использовать аргумент enabled в блоке lifecycle. Это обеспечивает более лаконичный синтаксис без необходимости индексирования массива и поддерживает автоматическую миграцию с шаблона count.
Объект count
В блоках, где задан count, в выражениях становится доступен дополнительный объект count, позволяющий изменять конфигурацию каждого экземпляра. У этого объекта есть один атрибут:
-
count.index— порядковый номер (начиная с0), соответствующий этому экземпляру.
Использование выражений в count
Метааргумент count принимает числовые выражения. Однако, в отличие от большинства аргументов, значение count должно быть известно до того, как OpenTofu выполнит какие-либо действия с удалёнными ресурсами. Это означает, что count не может ссылаться на атрибуты ресурсов, значения которых станут известны только после применения конфигурации (например, уникальный идентификатор, созданный удалённым API при создании объекта).
Ссылки на экземпляры
Когда задан count, OpenTofu различает сам блок и связанные с ним несколько экземпляров ресурса или модуля. Экземпляры идентифицируются порядковым номером, начиная с 0.
-
<TYPE>.<NAME>илиmodule.<NAME>(например,aws_instance.server) — ссылка на блок ресурса. -
<TYPE>.<NAME>[<INDEX>]илиmodule.<NAME>[<INDEX>](например,aws_instance.server[0],aws_instance.server[1]и т. д.) — ссылка на отдельные экземпляры.
Это отличается от ресурсов и модулей без count или for_each, на которые можно ссылаться без индекса или ключа.
Аналогичным образом ресурсы из дочерних модулей с несколькими экземплярами при отображении результатов плана и в других частях пользовательского интерфейса получают префикс module.<NAME>[<KEY>]. Для модуля без count или for_each адрес не будет содержать индекс модуля, поскольку для ссылки на модуль достаточно его имени.
Во вложенных блоках provisioner или connection специальный объект self ссылается на текущий экземпляр ресурса, а не на блок ресурса в целом.
Когда использовать for_each вместо count
Если экземпляры почти идентичны, подойдёт count. Если некоторым аргументам нужны разные значения, которые нельзя напрямую получить из целого числа, безопаснее использовать for_each.
До появления for_each было распространено вычислять count по длине списка и использовать count.index для поиска исходного значения в списке:
variable "subnet_ids" {
type = list(string)
}
resource "aws_instance" "server" {
# Create one instance for each subnet
count = length(var.subnet_ids)
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
subnet_id = var.subnet_ids[count.index]
tags = {
Name = "Server ${count.index}"
}
}Этот подход был ненадёжным, поскольку экземпляры ресурса по-прежнему идентифицировались по индексу, а не по строковым значениям списка. Если элемент удаляли из середины списка, у каждого экземпляра после этого элемента менялось значение subnet_id, что приводило к большему количеству изменений удалённых объектов, чем требовалось. Использование for_each обеспечивает ту же гибкость без лишних изменений.
Использование эфемерных значений
Поскольку count допускает использование выражений, если такое выражение содержит ссылку на эфемерное значение, всё вычисленное значение, используемое для метааргумента count, также будет эфемерным. Использование таких значений в блоках resource, data и ephemeral вызовет ошибку.
Это необходимо, чтобы гарантировать, что OpenTofu не сохраняет эфемерные данные в плане или состоянии.
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.12/language/meta-arguments/count/