Найти тему
Infinite Technologies

DevOps. Terraform. depends_on - a single static variable reference is required

Оглавление

Задача

Создать и подключить к виртуальной машине диски в определённой последовательности. Чтобы в дальнейшем с помощью Ansible, на дисках создать разделы и подмонтировать их в нужные папки

Вариант без зависимостей

Код для создания дисков без зависимостей
Код для создания дисков без зависимостей

resource "vcd_vm_internal_disk" "disk_1" {

unit_number     = 1

}

resource "vcd_vm_internal_disk" "disk_2" {

unit_number     = 2

}

resource "vcd_vm_internal_disk" "disk_3" {

unit_number     = 3

}

Если использовать подобную конструкцию, тогда диски будут создаваться в случайной последовательности. В свойствах виртуальной машины у дисков будут правильные Unit Number, но не правильный Index. На хосте так же имена диски будут не в той последовательности, которая необходима

Случайная очерёдность дисков
Случайная очерёдность дисков

Решение со статическими зависимостями

Решение со статическими зависимостями
Решение со статическими зависимостями

resource "vcd_vm_internal_disk" "disk_1" {

unit_number     = 1

depends_on      = [vcd_vm.vm]

}

resource "vcd_vm_internal_disk" "disk_2" {

unit_number     = 2

depends_on      = [vcd_vm_internal_disk.disk_1]

}

resource "vcd_vm_internal_disk" "disk_3" {

unit_number     = 3

depends_on      = [vcd_vm_internal_disk.disk_2]

}

В данном решении указаны статические объекты, которые ссылаются на предыдущий элемент. Если в переменную depends_on подставить какую-нибудь переменную, тогда получаем ошибку "A single static variable reference is required: only attribute access and indexing with constant keys. No calculations, function calls, template expressions, etc are allowed here.". Использование переменных depends_on запрещены из-за особенности построения структуры создания ресурсов.

depends_on = [vcd_vm.vm] - указывает, что необходимо ждать пока создастся виртуальная машина (можно эту зависимость не указывать, terraform сам распределяет очерёдность создания и он не создаст диск, пока не будет создана виртуальная машина

depends_on  = [vcd_vm_internal_disk.disk_1] - указывает, что ждём пока не создастся ресурс vcd_vm_internal_disk.disk_1

depends_on  = [vcd_vm_internal_disk.disk_2] - указывает, что ждём пока не создастся ресурс vcd_vm_internal_disk.disk_2

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

Решение с динамическими зависимостями

Для данного решения вынесем создание диска в отдельный модуль modules>disks>main.tf

Код модуля для создания дисков
Код модуля для создания дисков

Основной код ./main.tf

Решение с динамическими интервалами создания
Решение с динамическими интервалами создания

Переменная откуда берётся список дисков (variables.tf)

Список необходимых дисков в определённой последовательности
Список необходимых дисков в определённой последовательности

Теперь с помощью цикла мы можем создать то количество дисков, которое нам необходимо и в нужной последовательности. Если последовательность нарушается, тогда можно увеличить время ожидания с 30 до 60 и т.д.

module "disks" {

count = length(var.vcd_vm.disks)

size_in_mb  = var.vcd_vm.disks[count.index]

unit_number = count.index + 1

sleep = (30 * count.index) + 1

}

В модуле с помощь переменной sleep мы регулируем, когда начинать создание диска. Для таймера мы так же указываем, чтобы он не начинал отсчёт, пока не будет создана машина указанная в переменной vcd_vm

resource "time_sleep" "wait" {

depends_on = [var.vcd_vm]

create_duration = "${var.sleep}s"

}

Спасибо за внимание! Надеюсь данное решение пригодится в работе.