Я рву на себе волосы, пытаясь отладить проблему, когда у меня есть файл yaml, который содержит два атрибута для каждой записи:
topics:
- name: topic_one
partitions: 24
- name: topic_two
partitions: 1
- name: topic_three
partitions: 12
- name: topic_four
partitions: 6
Я втягиваю это в TF с помощью:
locals {
confluent = yamldecode(file("./confluent.yaml"))["topics"]
confluent_topics = flatten([for topic in local.confluent :
{
"name" = topic.name
"partitions" = topic.partitions
}])
}
Переходим в модуль с:
module "confluent" {
source = "./modules/confluent-cloud"
count = var.confluent_cluster ? 1 : 0
topics = local.confluent_topics
region = var.region
}
Затем в модуле:
resource "confluent_kafka_topic" "kafka" {
for_each = {
for topic in var.topics : topic.name => name
}
kafka_cluster {
id = confluent_kafka_cluster.kafka.id
}
topic_name = each.value.name
partitions_count = each.value.partitions
...
Я перепробовал почти все комбинации и установил тип переменной в модулях variables.tf практически на все, что только можно вообразить... но ошибка в том, что он не думает, что у объекта есть атрибут с именем partitions - я пробовал упрощая локальное без выравнивания списка, я пробовал так много разных вариантов ... но всегда что-то вроде этого;
│ Error: Unsupported attribute
│
│ on main.tf line 40, in locals:
│ 40: "partitions" = topic.partitions
│
│ This object does not have an attribute named "partitions".
Консоль дает мне:
> local.confluent
[
{
"name" = "topic_one"
"partitions" = 24
},
{
"name" = "topic_two"
"partitions" = 1
},
{
"name" = "topic_three"
"partitions" = 12
},
{
"name" = "topic_four"
"partitions" = 6
}
Консоль на сглаженном локальном просто возвращает:
> local.confluent_topics
(known after apply)
... что несколько озадачивает, потому что я думаю, что он должен знать это без применения, однако.. Я вполне уверен, что это не моя проблема.
Раздражает то, что я делал это раньше без проблем ... поэтому мне интересно, является ли это ситуацией версии TF, где что-то должно обрабатываться по-другому?
❯ terraform version
Terraform v1.1.7
on darwin_arm64
+ provider registry.terraform.io/confluentinc/confluent v0.7.0
+ provider registry.terraform.io/hashicorp/aws v4.12.1
+ provider registry.terraform.io/hashicorp/kubernetes v2.11.0
+ provider registry.terraform.io/hashicorp/null v3.1.1
+ provider registry.terraform.io/hashicorp/random v3.1.3
+ provider registry.terraform.io/hashicorp/tls v3.3.0
Your version of Terraform is out of date! The latest version
is 1.1.9. You can update by downloading from https://www.terraform.io/downloads.html





С вашей логикой все в порядке, кроме зацикливания с атрибутом name. Вы не можете иметь атрибут name и извлекать из него поле partitions. Его можно получить только из объекта topic.
Попробуй это..
resource "confluent_kafka_topic" "kafka" {
for_each = {
for topic in var.topics : topic.name => topic
}
kafka_cluster {
id = confluent_kafka_cluster.kafka.id
}
topic_name = each.value.name
partitions_count = each.value.partitions
...
У вас есть уникальный ключ в виде topic.name, а topic — это объект с полем partitions.
Тем не менее, я получаю ту же ошибку при изменении его, как вы предложили :(
Вы изменили свой for_each с for_each = { for topic in var.topics : topic.name => name } на for_each = { for topic in var.topics : topic.name => topic }.. Вы все еще получаете ту же ошибку?
Для меня terraform validate и terraform plan сработало. Можете ли вы опубликовать свой обновленный код?
for_each = { for topic in var.topics : topic.name => topic } Я получаю ту же ошибку от terraform validate : This object does not have an attribute named "partitions".У вас есть специальные символы в поле partitions? Как вы читаете из файла? Это сработало для меня
Я поместил дамп yaml в исходный вопрос. Поле разделов представляет собой целое число, а не строку. Я пытался решить эту проблему в объявлении переменной, но я не думаю, что это должно иметь большое значение?
Я вижу так много примеров в Интернете, которые предполагают, что я делаю это правильно. Это так сбивает меня с толку.
Кажется, я делаю то же самое, что и в этих статьях: medium.com/@dfinnoy/… и aws.plainenglish.io/terraform-yaml-%EF%B8%8F-3550a3642dd3.
Почему нет? Вы должны использовать int, поскольку ресурс confluent_kafka_topic ожидает этот тип. Тем не менее, в этом случае вы получите ошибку проверки от провайдера, а не ту, которую вы получили. Я до сих пор подозреваю, что с вашей стороны что-то не так, поскольку plan сработало с моей стороны.
Давайте продолжить обсуждение в чате.
Спасибо за ваш ответ, я не совсем уверен, что понимаю, что вы имеете в виду здесь. В этой части мы не просто говорим циклу рассматривать
nameкак ключ для цикла. Таким образом, запускать цикл для каждого уникального имени, которое вы найдете? По общему признанию, мои глубокие знания этой конкретной функции недостаточны.