Terraform & OpenStack - без изменений времени простоя - PullRequest
1 голос
/ 16 апреля 2020

Я использую openstack_compute_instance_v2 для создания экземпляров в OpenStack. Существует настройка жизненного цикла create_before_destroy = true присутствует. И это работает очень хорошо, если я, например, изменить размер тома, где экземпляры должны быть заменены.

Но. Когда я делаю изменение вкуса, что можно сделать с помощью опции resize instance из OpenStack, он делает именно это, но не заботится о HA. Все экземпляры в кластере недоступны в течение 20-30 секунд, пока не завершится изменение размера.

Как я могу изменить это поведение?

Некоторые настройки, например serial из Ansible или другие варианты пригодятся. Но я ничего не могу найти. Просто любое решение, которое позволило бы мне сказать, что «по крайней мере половина экземпляров должна быть подключена постоянно».

Версия Terraform: 12.20.

План TF: https://pastebin.com/ECfWYYX3

Ответы [ 2 ]

2 голосов
/ 16 апреля 2020

Поставщик Openstack Terraform знает, что он может обновить flavor с помощью вызова API изменения размера вместо того, чтобы уничтожать экземпляр и воссоздавать его.

К сожалению, в настоящее время нет опция жизненного цикла, которая заставляет изменчивые вещи выполнять уничтожение / создание или создание / уничтожение в сочетании с настройкой create_before_destroy жизненного цикла, поэтому вы не можете легко заставить вместо этого заменить экземпляр.

Один вариант в этих обстоятельствах это найти параметр, который не может быть изменен на месте (они отмечены флагом ForceNew на схеме в исходном коде основного поставщика для ресурса), а затем иметь изменение в изменяемом параметре, также каскадное изменение в неизменный параметр.

Типичным примером здесь является замена группы автоматического масштабирования AWS при изменении шаблона запуска (изменяемого по сравнению с неизменяемыми конфигурациями запуска), чтобы вы могли сразу же развернуть изменения вместо ожидания для ASG медленно повторять зашнуровать экземпляры с течением времени. Простой пример будет выглядеть примерно так:

variable "ami_id" {
  default = "ami-123456"
}

resource "random_pet" "ami_random_name" {
  keepers = {
    # Generate a new pet name each time we switch to a new AMI id
    ami_id = var.ami_id
  }
}

resource "aws_launch_template" "example" {
  name_prefix            = "example-"
  image_id               = var.ami_id
  instance_type          = "t2.small"
  vpc_security_group_ids = ["sg-123456"]
}

resource "aws_autoscaling_group" "example" {
  name                = "${aws_launch_template.example.name}-${random_pet.ami_random_name.id}"
  vpc_zone_identifier = ["subnet-123456"]
  min_size            = 1
  max_size            = 3

launch_template {
    id      = aws_launch_template.example.id
    version = "$Latest"
  }

  lifecycle {
    create_before_destroy = true
  }
}

В приведенном выше примере изменение AMI запускает новое случайное имя питомца , которое меняет имя ASG, которое является неизменным полем, так это вызывает замену ASG. Поскольку ASG имеет настройку жизненного цикла create_before_destroy, она создаст новую ASG, подождите, пока минимальное количество экземпляров пройдет проверку работоспособности EC2, а затем уничтожит старую ASG.

Для вашего случая вы также можете использовать параметр name в ресурсе openstack_compute_instance_v2, поскольку он также является неизменным. Таким образом, базовый c пример может выглядеть так:

variable "flavor_name" {
  default = "FLAVOR_1"
}

resource "random_pet" "flavor_random_name" {
  keepers = {
    # Generate a new pet name each time we switch to a new flavor
    flavor_name = var.flavor_name
  }
}

resource "openstack_compute_instance_v2" "example" {
  name            = "example-${random_pet.flavor_random_name}"
  image_id        = "ad091b52-742f-469e-8f3c-fd81cadf0743"
  flavor_name     = var.flavor_name
  key_pair        = "my_key_pair_name"
  security_groups = ["default"]

  metadata = {
    this = "that"
  }

  network {
    name = "my_network"
  }
}
0 голосов
/ 16 апреля 2020

Итак. Сначала я начал копать, как, как предложил @ydaetskcoR, использовать случайное имя экземпляра.

Name не было вариантом, и потому, что в openstack это изменяемый параметр, и потому, что у меня есть выбрал схему именования, которую я не могу изменить.

Я начал искать другие параметры, которые я мог бы изменить, чтобы принудительно создавать экземпляр, а не изменять. Я нашел около personality. https://www.terraform.io/docs/providers/openstack/r/compute_instance_v2.html#instance -с личностью

Но это тоже не сработало. Главным образом, потому что личность больше не поддерживается, как кажется:

Использование личных файлов не рекомендуется, начиная с микроверсии 2.57. Используйте метаданные и user_data для настройки экземпляра сервера. https://docs.openstack.org/api-ref/compute/

Не уверен, что terraform не поддерживает это, или есть какие-либо другие проблемы. Но я пошел с user_data. Я уже использовал user_data в модуле экземпляра вычислений, поэтому при добавлении некоторых данных об ароматах проблем быть не должно.

Итак, в user_data я добавил следующее:

  user_data          = "runcmd:\n - echo ${var.host["flavor"]} > /tmp/tf_flavor"

Нет необходимости в случайных именах питомцев, не нужно менять имена экземпляров. Просто измените их "индивидуальность", добавив название аромата куда-нибудь. Это заставляет экземпляр обновляться при изменении аромата.

Итак. Вместо простого:

  # module.instance.openstack_compute_instance_v2.server[0] will be updated in-place
  ~ resource "openstack_compute_instance_v2" "server" {

У меня сейчас:

-/+ destroy and then create replacement
+/- create replacement and then destroy

Terraform will perform the following actions:

  # module.instance.openstack_compute_instance_v2.server[0] must be replaced
+/- resource "openstack_compute_instance_v2" "server" {
...