Метааргумент count
Один блок ресурса или модуля не может использовать одновременно count и 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
В блоках, где задано 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.10/language/meta-arguments/count/