Как я могу использовать выходные данные модулей Terraform в качестве входных данных для другого модуля Terraform?

Я пишу Terraform для развертывания корзины S3 и лямбды. Необходима корзина S3, так как именно здесь будет храниться zip-объект, готовый к развертыванию в лямбда-выражении.

У меня есть два модуля в моем файле main.tf верхнего уровня:

module "s3" {
  count  = var.enable_s3 ? 1 : 0
  source = "./modules/s3"
}

module "lambdas" {
  count     = var.enable_lambdas ? 1 : 0
  source    = "./modules/lambdas"
  bucket_id = module.s3.lambda_bucket_id
}

модуль s3:

main.tf

resource "aws_s3_bucket" "lambda_bucket" {
  bucket = "lunchboxd-lambdas"

  tags = {
    Owner       = "Terraform",
    Description = "A bucket to hold the lambdas zip"
  }
}

выходы.tf

output "lambda_bucket_id" {
  value       = aws_s3_bucket.lambda_bucket.id
  description = "ID of the bucket holding the lambda functions."
}

лямбда-модуль:

переменные.tf

variable "bucket_id" {}

main.tf

data "archive_file" "lambda_hello_world" {
  type = "zip"

  source_dir  = "${path.module}/hello-world"
  output_path = "${path.module}/hello-world.zip"
}

resource "aws_s3_object" "lambda_hello_world" {
  bucket = var.bucket_id

  key    = "hello-world.zip"
  source = data.archive_file.lambda_hello_world.output_path

  etag = filemd5(data.archive_file.lambda_hello_world.output_path)
}


resource "aws_lambda_function" "hello_world" {
  function_name = "HelloWorld"

  s3_bucket = var.bucket_id
  s3_key    = aws_s3_object.lambda_hello_world.key

  runtime = "nodejs12.x"
  handler = "hello.handler"

  source_code_hash = data.archive_file.lambda_hello_world.output_base64sha256

  role = aws_iam_role.lambda_exec.arn
}

resource "aws_cloudwatch_log_group" "hello_world" {
  name = "/aws/lambda/${aws_lambda_function.hello_world.function_name}"

  retention_in_days = 30
}

resource "aws_iam_role" "lambda_exec" {
  name = "serverless_lambda"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Sid    = ""
      Principal = {
        Service = "lambda.amazonaws.com"
      }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "lambda_policy" {
  role       = aws_iam_role.lambda_exec.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

Когда я пытаюсь проверить свою терраформу, я получаю следующую ошибку:

╷
│ Error: Unsupported attribute
│ 
│   on main.tf line 36, in module "lambdas":
│   36:   bucket_id = module.s3.aws_s3_bucket.lambda_bucket.id
│     ├────────────────
│     │ module.s3 is a list of object, known only after apply
│ 
│ Can't access attributes on a list of objects. Did you mean to access an attribute for a specific element of the list, or across all elements of the list?
╵

Я следил за документацией по выходным данным и композиции модулей, но я не уверен, что делаю неправильно. Вся помощь приветствуется.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
23
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш блок module "s3" имеет мета-аргумент count, поэтому здесь применяется документация Ссылаясь на экземпляры.

В частности, module.s3 — это список объектов, а не просто один объект (как указано в сообщении об ошибке), поэтому, когда вы ссылаетесь на него, вам нужно указать, на какой из элементов этого списка вы хотите ссылаться.

В вашем случае у вас есть только ноль или один экземпляр модуля, поэтому module.s3 будет списком из нуля или одного элемента. Поэтому вам нужно будет объяснить Terraform, что должно произойти, если элементов module.s3 нет, но есть один экземпляр module.lambdas.

Если допустимо, чтобы переменная bucket_id в module "lambdas" была нулевой, когда нет ведра, один из способов написать это — использовать функция one для преобразования списка либо в одно значение, если он имеет один элемент, либо в null, если в нем нет элементов. :

  bucket_id = one(module.s3.aws_s3_bucket[*].lambda_bucket.id)

В этом выражении сначала используется оператор знака [*] для перевода из списка объектов в список только значений id, а затем используется one для перевода либо в одну строку, либо в нулевое значение.

Если вам нужно, чтобы bucket_id имел какое-то другое значение в случае, когда нет экземпляров module.s3, вам нужно указать здесь некоторую другую логику, чтобы описать, как заполнить эту переменную в этом случае. Что именно делать, будет зависеть от нужного вам правила перевода; вы можете использовать любое выражение или функцию языка Terraform, чтобы принять здесь динамическое решение.

Другие вопросы по теме