Конвертация Terraform в карту - PullRequest
1 голос
/ 31 января 2020

Я довольно новичок в Terraform, и я использую эту функцию для повторного использования одного и того же списка подсетей для запуска большего количества экземпляров, чем у меня есть подсети. (Это просто l oop over). Это прекрасно работает, если я предоставляю свою собственную карту подсетей, но данные в удаленном состоянии являются кортежем, и я получаю эту ошибку:

Invalid value for "inputMap" parameter: lookup() requires a map as the first argument. data.terraform_remote_state.vpc.outputs.private_subnets is tuple with 4 elements

Я также попробовал tomap ( функция, но это не с:

Invalid value for "v" parameter: cannot convert tuple to map of any single type.

Вот мой код:

  count                  = var.instance_count
  ami                    = var.ami
  instance_type          = "t2.medium"
  subnet_id              = lookup(data.terraform_remote_state.vpc.outputs.private_subnets, count.index%length(data.terraform_remote_state.vpc.outputs.private_subnets))
  vpc_security_group_ids = ["${data.terraform_remote_state.foo_sg.outputs.foo_sg_id}"]
  key_name               = var.key_name
  iam_instance_profile   = var.iam_instance_profile

  user_data = <<-EOF
              #!/bin/bash
              hostnamectl set-hostname --static "${var.app_name}-${count.index + 1}.${data.terraform_remote_state.vpc.outputs.private_zone_domain_name}"
              echo "127.0.0.1 localhost.localdomain localhost4 localhost4.localdomain4 ${var.app_name}-${count.index + 1}.${data.terraform_remote_state.vpc.outputs.private_zone_domain_name} localhost" > hosts
              echo "::1 localhost localhost.localdomain localhost6 localhost6.localdomain6" >> hosts
              EOF

  tags = {
    Name                 = "${var.app_name}-${count.index +1}.${data.terraform_remote_state.vpc.outputs.private_zone_domain_name}"
}

Как я уже сказал, моя цель состоит в том, чтобы повторно использовать 4 подсети в том удаленном состоянии, которое у меня есть, поэтому, если я захочу 6 экземпляров, это будет l oop через 4, которые у меня есть, а 5-й и 6-й экземпляры будут на su bnet 1 и 2 в кортеже. Будем благодарны за любые предложения!

1 Ответ

1 голос
/ 21 марта 2020

У вас есть 3 формы, чтобы сделать l oop.

1º, используя dynamic block ... Пример:

resource "aws_security_group" "ecc_default" {
  count       = length(var.clusters)
  vpc_id      = var.vpc_id
  name        = "${terraform.workspace}.ecc-${var.clusters[count.index].engine}.sg"
  description = "${terraform.workspace}.ecc-${var.clusters[count.index].engine}.sg"

  ingress {
    from_port   = var.clusters[count.index].port
    to_port     = var.clusters[count.index].port
    protocol    = "tcp"
    cidr_blocks = [var.vpc_cidr]
  }

  dynamic "ingress" {
    iterator = item
    for_each = var.enable_vpn ? var.vpn_cidr : []

    content {
      from_port   = var.clusters[count.index].port
      to_port     = var.clusters[count.index].port
      protocol    = "tcp"
      cidr_blocks = [item.value["cidr"]]
      description = item.value["description"]
    }
  }
...
...
}

2º Используя for_each ... ( нажмите здесь для ответа )

3º Используя арифметику c итерация ... ( нажмите здесь для ответа ) Пример:

resource "aws_security_group_rule" "ecc_internal" {
    count = length(var.ingress_security_groups) > 0 ? length(var.ingress_security_groups) * length(var.clusters) : 0
    security_group_id = aws_security_group.ecc_default[count.index % length(var.clusters)].id
    type = "ingress"
    from_port = var.clusters[count.index % length(var.clusters)].port
    to_port = var.clusters[count.index % length(var.clusters)].port
    protocol = "tcp"
    source_security_group_id = var.ingress_security_groups[floor(count.index / length(var.clusters))]
}

И, для ошибки при преобразовании: попытайтесь использовать coalescelist с поддельной заменой. Например:

resource "aws_lb_listener_certificate" "default" {
  count           = (coalescelist(data.aws_alb_listener.https, [{ certificate_arn = "" }])[0].certificate_arn != var.certificate_arn) ? local.enabled : 0
  listener_arn    = coalescelist(data.aws_alb_listener.https, [{ arn = "" }])[count.index].arn
  certificate_arn = var.certificate_arn
}

Преобразование кортежа ([N1, N2, N3]) в карту ({N1 = "", N2 = ""}) действительно не допускается. Но вы можете использовать поддельную замену, чтобы сделать работу. tomap нужен объект для аргумента. И map, для получения результата требуется несколько аргументов. Попробуйте манипулировать своим списком, конвертировать в карту , с помощью другой формы, подобной этой (если вы хотите просто конвертировать, а не решить проблему):

environment_vars = jsonencode([
      for key in sort(keys(data.external.environment_vars.result)) : {
        name  = key
        value = lookup(data.external.environment_vars.result, key)
    }])

Я рекомендую для вас: Советы и хитрости Terraform: циклы, операторы if и ошибки

...