Метааргумент 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 обеспечивает ту же гибкость без лишних изменений.
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.11/language/meta-arguments/count/