Создание ресурсов с использованием модуля Terraform с некоторыми ресурсами, общими для модулей - PullRequest
1 голос
/ 04 апреля 2019

У меня есть App1, App2, App3 и т. Д. Чтобы повторно использовать код, я хочу создать его с помощью модуля Terraform.

Общая инфраструктура, вызываемая модулями: корень \ Common_infra \ main.tf:

resource "aws_lambda_function" "app" {
     # count = “${var.should_launch}”
     function_name = "app"
     …
}
resource "aws_cloudwatch_event_rule" "app" {
  name                = " ${var.app_name } "
  schedule_expression = "${var.app_schedule}"
}
resource "aws_cloudwatch_event_target" "app_target" {
  rule      = "${aws_cloudwatch_event_rule.app.name}"
  arn       = "${aws_lambda_function.app.arn}"
  input = <<EOF
{
  "app_name": "${var.app_name}"
}
EOF
}
resource "aws_lambda_permission" "allow_cloudwatch_to_call_lambda"   {
  action        = "lambda:InvokeFunction"
  function_name =     "${aws_lambda_function.app.function_name}"
  principal     = "events.amazonaws.com"
  source_arn    = "${aws_cloudwatch_event_rule.app.arn}"
}
# Other resources each app need to create.

Модуль для app1 выглядит следующим образом: корень \ app1 \ main.tf:

module "app1" {
  # should_launch = 1
  source  = "../common_infra"
  app_name = "app1"
  schedule = "cron(01 01 ? * * *)"
  ……
}

Используя модуль, я успешно запустил событие cloudwatch, которое запускает лямбду по расписанию, и я успешно запустил лямбду под названием «приложение». Лямбда получает app_name = app1 в качестве входных данных и затем работает на app1.

когда я создаю другое приложение2 следующим образом, корень \ app2 \ main.tf:

module "app2" {
  # should_launch = 0
  source = "../common_infra"
  app_name = "app2"
  schedule = "cron(01 01 ? * * *)"
  ……
}

Он пытается создать другую лямбду, но терпит неудачу, потому что лямбда была создана модулем app1. На самом деле я не хочу создавать новую лямбду, потому что нет необходимости создавать несколько лямбда-выражений для app1, app2…. Я могу использовать input = app_name для управления тем, что должна делать лямбда.

Я пытаюсь использовать should_launch (см. Выше закомментированные строки), чтобы лямбда создавалась только при создании app1. Но это не работает. При развертывании app1, лямбда создается. При создании приложения2. Террформ жалуется:

aws_cloudwatch_event_target.app_target 

не могу найти

arn = "${aws_lambda_function.app.arn}"

Мой вопрос: как организовать макет / структуру моего кода так, чтобы лямбда-ресурс объявлялся только один раз для нескольких модулей? например может мне стоит создать новую папку root / resource_called_by_all_module / lambda.tf? и затем развернуть эту новую папку заранее?

1 Ответ

1 голос
/ 04 апреля 2019

Да, как вы уже указали, в текущей настройке все ваши модули будут пытаться создать все ресурсы в этом файле по отдельности. Поскольку имя вашей лямбды жестко закодировано, terraform будет справедливо жаловаться.

Если у вас есть ресурс, от которого зависят другие вещи, вы можете переставить свою терраформу, чтобы создать этот ресурс на отдельной терраформе.

Таким образом, вы можете извлечь этот ресурс Lambda из этих файлов и поместить его в отдельную папку. Затем вы просто запускаете Terraform apply для этих общих ресурсов в первую очередь («app» лямбда) перед ресурсами, которые зависят от них («app1», «app2»).

После создания общих ресурсов вы можете извлечь из них необходимую информацию, используя Источники данных Terraform (обычно для получения имен или ARN).

...