При создании гибкого модуля terraform для настройки дополнительных параметров

#terraform #terraform-provider-aws

#terraform #terraform-provider-aws

Вопрос:

Я хотел бы поместить пару ресурсов в модуль terrafrom. у этого одного из ресурсов есть aws_ecs_service некоторые необязательные аргументы, которые мне могут понадобиться или не понадобиться, и я хотел бы передать значения при вызове модулей.

Например, рассмотрим ordered_placement_strategy аргумент. Служба может иметь один или несколько ordered_placement_strategy . Некоторые службы могут иметь или не иметь placement_constraints . Как я могу написать гибкий универсальный модуль для aws_ecs_service.

 resource "aws_ecs_service" "mongo" {
  name            = "mongodb"
  cluster         = aws_ecs_cluster.foo.id
  task_definition = aws_ecs_task_definition.mongo.arn
  desired_count   = 3
  iam_role        = aws_iam_role.foo.arn
  depends_on      = [aws_iam_role_policy.foo]

  ordered_placement_strategy {
    type  = "binpack"
    field = "cpu"
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.foo.arn
    container_name   = "mongo"
    container_port   = 8080
  }

  placement_constraints {
    type       = "memberOf"
    expression = "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]"
  }
}
 

Ответ №1:

Выглядит как надежный вариант использования для локальных динамических блоков.

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

Например: допустим, мы хотим поддерживать два вида сервисов:

  • простой
  • сложный

Сначала я бы определил входную переменную с такой проверкой, чтобы избежать неизвестных:

 variable "ecs_service_type" {
  type        = string
  description = "What kind of service is this?"

  validation {
    condition     = can(regex("^(simple|complex)$", var.ecs_service_type))
    error_message = "The service type must be in (simple|complex)."
  }
}
 

Вы можете определить поддерживаемые стратегии размещения задач и ограничения, используя локальные значения, подобные этому:

 locals {
  ordered_placement_strategy = {
    simple = [
      {
        "field" : "instanceId",
        "type" : "spread"
      }
    ]
    complex = [
      {
        type  = "spread"
        field = "attribute:ecs.availability-zone"
      },
      {
        type  = "spread"
        field = "instanceId"
      }
    ]
  }

  placement_constraints = {
    simple = []

    complex = [
      {
        type = "distinctInstance"
      }
    ]
  }

}
 

И, в конце концов, создайте сервис соответствующим образом, используя динамические блоки:

 resource "aws_ecs_service" "service" {
  ...
  ...

  dynamic "ordered_placement_strategy" {
    for_each = local.ordered_placement_strategy[var.ecs_service_type]

    content {
      type  = ordered_placement_strategy.value.type
      field = ordered_placement_strategy.value.field
    }
  }

  dynamic "placement_constraints" {
    for_each = local.placement_constraints[var.ecs_service_type]

    content {
      type = placement_constraints.value.type
    }
  }
}
 

PS: этот конкретный фрагмент кода не тестировался, но я использовал аналогичные подходы. Дайте мне знать, если вам понадобится помощь в чем-либо.

Комментарии:

1. Спасибо, это полезно, но два вопроса. нужно ли нам использовать local или мы можем использовать variable? Это делается для того, чтобы затем иметь все значения в my .tfvars. Во-вторых, я не понимаю этого local.placement_constraints[var.ecs_service_type]. В локальном определении нет ссылки на ecs_service_type .

2. @kumar — Итак, есть много способов сделать это. Я предпочел locals для этого варианта использования, поскольку хотел упростить принятие решений для конечных пользователей. Подробнее по этой теме: — learn.hashicorp.com/tutorials/terraform/locals medium.com/@pavloosadchyi /… Вы можете проверить эти общедоступные модули ecs и решить, какой подход соответствует вашим потребностям: — github.com/infrablocks/terraform-aws-ecs-service github.com/trussworks/terraform-aws-ecs-service