Файл входных переменных для нескольких рабочих пространств Terraform

Мы все были там: вы написали конфигурацию Terraform, которая настолько потрясающая, что вам приходится применять ее несколько раз… Или, по крайней мере, в dev, test и prod. Какой бы замечательной ни была ваша конфигурация, очень редко бывает так, чтобы все детали были абсолютно одинаковыми в каждой среде. Обычно в итоге получается что-то вроде этого, и это совершенно нормально (для удобства чтения я немного сократил код, более полный пример смотрите в этом gist):

resource "aws_instance" "this" {
  count = var.instance_count

  ami           = var.ami_id
  instance_type = var.instance_type

  tags = {
    Name = "project-xyz-${terraform.workspace}-${count.index}"
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Где это начинает вредить, так это во время применения, потому что у вас будет, например:

terraform workspace select prod
terraform apply -var='instance_count=5' -var='ami_id=ami-1a2b3c' -var='instance_type=t2.large'
Войти в полноэкранный режим Выйти из полноэкранного режима

Эта строка переменных становится непонятной очень быстро. Кроме того, запоминать все эти переменные или заставлять командную строку запоминать утверждение (для каждого окружения) довольно обременительно. Более того, чтобы заставить это работать в автоматизации (опять же, для каждого окружения…), скорее всего, потребуется некоторая магия переменных env. Это отделяет определение вашей инфраструктуры от стандартных способов ее вызова, что плохо. (Кстати, если вы никогда не слышали о connascence, прекратите читать эту статью и прочитайте эту).

Terraform Cloud предлагает некоторое исправление этого, но и здесь вы создаете разделение между шаблонами и наборами переменных env. Было бы гораздо лучше, если бы мы могли держать наборы переменных по умолчанию в контроле версий рядом с нашей конфигурацией. После некоторых попыток я нашел следующее решение:

variable "workspace_variables" {
  type = map(object({
    instance_count = number
    ami_id         = string
    instance_type  = string
  }))
  default = {}
}

locals {
  default_vars = lookup(var.workspace_variables, terraform.workspace, {
    instance_count = 2
    ami_id         = "ami-abc123"
    instance_type  = "t2.micro"
  })
  instance_count = var.instance_count != null ? var.instance_count : local.default_vars["instance_count"]
  ami_id         = var.ami_id != null ? var.ami_id : local.default_vars["ami_id"]
  instance_type  = var.instance_type != null ? var.instance_type : local.default_vars["instance_type"]
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Этот фрагмент кода считывает одну необязательную переменную, чтобы править ими всеми: workspace_variables. Если она не указана, то будет использоваться набор подпеременных по умолчанию. Кроме того, вы можете переопределить любой набор переменных с помощью Terraform cli. Далее в этом фрагменте вам нужно сделать значение по умолчанию для всех переменных null и при их использовании заменить var. на local.. Затем вы можете создать в Terraform файл vars примерно следующего содержания:

workspace_variables = {
  dev = {
    instance_count = 2
    ami_id         = "ami-abc123"
    instance_type  = "t2.micro"
  }
  test = {
    instance_count = 3
    ami_id         = "ami-a1b2c3"
    instance_type  = "t2.medium"
  }
  prod = {
    instance_count = 5
    ami_id         = "ami-1a2b3c"
    instance_type  = "t2.large"
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Намного понятнее и все хранится в одном доступном месте, которое можно поместить в систему контроля версий! И вы получите нужную вам конфигурацию с помощью простого потока Terraform — выбрать рабочее пространство и нажать кнопку apply. Кроме того, вы все еще можете переопределить переменные с помощью командной строки для горячих исправлений, тестов и т.д.:

terraform workspace select prod
terraform apply -var='ami_id=ami-x1337x'
Вход в полноэкранный режим Выход из полноэкранного режима

Это может показаться слишком много шаблонов для простого ввода параметров, но я обнаружил, что при большом количестве переменных это весит больше, чем установка переменных «обычным» способом. Проверьте, работает ли это для вас!

Последнее замечание: для реализации правильной проверки переменных в Terraform и совместимости с файлом vars потребуется еще немного доработки, но это может быть исправлено, когда опциональные атрибуты переменных выйдут из публичной бета-версии.

(Приведенный выше код сокращен для удобства чтения, более полный пример см. в этом gist).

Оцените статью
Procodings.ru
Добавить комментарий