Метааргумент 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.9/language/meta-arguments/count/