Как условно заполнить значение аргумента в terraform? - PullRequest
1 голос
/ 24 апреля 2019

Я пишу Terraform скрипт для ускорения ресурсов в Google Cloud Platform.
Некоторым ресурсам требуется только один аргумент, если задан другой, как заполнить один аргумент, только если заполнен другой (или любое другое подобное условие)?

Например:

resource "google_compute_router" "compute_router" {
  name    = "my-router"
  network = "${google_compute_network.foobar.name}"
  bgp {
    asn               = 64514
    advertise_mode    = "CUSTOM"
    advertised_groups = ["ALL_SUBNETS"]
    advertised_ip_ranges {
      range = "1.2.3.4"
    }
    advertised_ip_ranges {
      range = "6.7.0.0/16"
    }
  }
}

В указанном выше ресурсе ( google_compute_router ) описание для advertised_groups и advertised_ip_ranges содержит Это поле может быть заполнено только в том случае, если advertise_mode имеет значение CUSTOM и объявляется всем равноправным узлам маршрутизатора. .

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

resource "google_compute_router" "compute_router" {
  name    = "my-router"
  network = "${google_compute_network.foobar.name}"
  bgp {
    asn               = 64514

    #Changin only the value below
    advertise_mode    = "DEFAULT"

    advertised_groups = ["ALL_SUBNETS"]
    advertised_ip_ranges {
      range = "1.2.3.4"
    }
    advertised_ip_ranges {
      range = "6.7.0.0/16"
    }
  }
}

Однако приведенный выше скрипт при запуске выдает следующую ошибку:

* google_compute_router.compute_router_default: Error creating Router: googleapi: Error 400: Invalid value for field 'resource.bgp.advertiseMode': 'DEFAULT'. Router cannot have a custom advertisement configurati
on in default mode., invalid

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

resource "google_compute_router" "compute_router_default" {
  count               = "${var.advertise_mode == "DEFAULT" ? 1 : 0}"
  name                = "${var.router_name}"
  region              = "${var.region}"
  network             = "${var.network_name}"

  bgp {
    asn               = "${var.asn}"
    advertise_mode    = "${var.advertise_mode}"
    #Removed some codes from here
  }
}

resource "google_compute_router" "compute_router_custom" {
  count               = "${var.advertise_mode == "CUSTOM" ? 1 : 0}"
  name                = "${var.router_name}"
  region              = "${var.region}"
  network             = "${var.network_name}"

  bgp {
    asn               = "${var.asn}"
    advertise_mode    = "${var.advertise_mode}"
    advertised_groups = ["${var.advertised_groups}"]

    advertised_ip_ranges {
      range = "${var.advertised_ip_range}"
      description = "${var.advertised_ip_description}"
    }
  }
}

Приведенный выше скрипт работает нормально, однако мне кажется, что для меня много повторений кода и взлом. Кроме того, для двух опций (зависимых атрибутов) это хорошо, однако, если есть больше опций, скажем, 5, повторение кода для такой маленькой вещи было бы слишком много. Есть ли лучший способ сделать то, что я пытаюсь достичь?

1 Ответ

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

Это в значительной степени то, что вы ограничены в Terraform <0.12. Некоторые ресурсы позволяют использовать пустую строку для пропуска базовых значений, и поставщик будет интерпретировать это как нулевое значение, не передавая его конечной точке API, поэтому он не будет жаловаться на то, что он не был установлен должным образом. Но из моего короткого опыта работы с провайдером GCP это не относится к большинству вещей. </p>

Terraform 0.12 представляет null способных аргументов , которые позволят вам установить их условно с помощью чего-то вроде следующего:

variable "advertise_mode" {}

resource "google_compute_router" "compute_router" {
  name    = "my-router"
  network = "${google_compute_network.foobar.name}"
  bgp {
    asn               = 64514
    advertise_mode    = "${var.advertise_mode}"
    advertised_groups = ["${var.advertise_mode == "DYNAMIC" ? ALL_SUBNETS : null}"]
    advertised_ip_ranges {
      range = "${var.advertise_mode == "DYNAMIC" ? 1.2.3.4 : null}"
    }
    advertised_ip_ranges {
      range = "${var.advertise_mode == "DYNAMIC" ? 6.7.0.0/16 : null}"
    }
  }
}

Также будут введены динамические блоки , которые вы можете зациклить, чтобы у вас также было динамическое число advertised_ip_ranges блоков.

...