Terraform 地形及;OpenStack-零停机时间更改

Terraform 地形及;OpenStack-零停机时间更改,terraform,openstack,high-availability,terraform-provider-openstack,Terraform,Openstack,High Availability,Terraform Provider Openstack,我正在使用openstack\u compute\u instance\u v2在openstack中创建实例。存在生命周期设置create\u before\u destroy=true。它在需要替换实例的情况下可以正常工作,例如更改卷大小 但是。当我进行风格更改时,可以使用OpenStack中的调整实例大小选项来进行更改,它只进行更改,而不关心任何HA。在调整大小完成之前,群集中的所有实例在20-30秒内不可用 我怎样才能改变这种行为 Ansible提供的一些设置,如serial,或其他一些

我正在使用
openstack\u compute\u instance\u v2
在openstack中创建实例。存在生命周期设置
create\u before\u destroy=true
。它在需要替换实例的情况下可以正常工作,例如更改卷大小

但是。当我进行风格更改时,可以使用OpenStack中的
调整实例大小
选项来进行更改,它只进行更改,而不关心任何HA。在调整大小完成之前,群集中的所有实例在20-30秒内不可用

我怎样才能改变这种行为

Ansible提供的一些设置,如
serial
,或其他一些选项会很方便。但我什么也找不到。 任何一种解决方案都可以让我说“至少有一半的实例需要随时在线”

地形版本:12.20


TF计划:

Openstack Terraform提供程序知道,它可以通过使用来更新
味道
,而不必破坏实例并重新创建它

不幸的是,目前还没有一个生命周期选项可以强制可变的东西执行销毁/创建或创建/销毁操作,这与
create\u before\u 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
  }
}
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"
  }
}
在上面的示例中,对AMI的更改会触发一个新的命令,该命令会更改ASG名称,这是一个不可变字段,因此会触发替换ASG。由于ASG具有
create\u before\u destroy
生命周期定制,因此它将创建一个新ASG,等待最少数量的实例通过EC2健康检查,然后销毁旧ASG

对于您的情况,您还可以使用
openstack\u compute\u instance\u v2
资源上的
name
参数,因为这也是一个不可变字段。因此,一个基本示例可能如下所示:

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
  }
}
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"
  }
}

所以。首先,我开始研究如何使用@ydaetskcoR建议的随机实例名

Name
不是一个选项,因为在openstack中它是一个可变参数,并且因为我有一个我不能更改的已确定的命名模式

我已经开始寻找可以修改的其他参数,以强制创建实例而不是修改实例。我已经找到了关于
个性的

但它也不起作用。主要是因为人格不再像看上去那样受到支持:

从2.57微版本开始,不推荐使用个性文件。使用元数据和用户数据自定义服务器实例。

不确定terraform是否不支持它,或者是否存在任何其他问题。但是我使用了
用户数据
。我已经在compute实例模块中使用了user_数据,所以添加一些风格数据应该不会有问题

因此,在
user\u 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" {

进行此更改时,计划输出是什么样子的?你能用一些地形代码编辑成你的问题吗?我在问题中包括了地形平面图。我可能很难创建最小的可复制示例,因为我们为它添加了很多东西,以便它只使用openstack和gitlab管道设置。但在计划中,您可以看到有两个实例。唯一的变化是味道。它们同时不可用。好吧,这看起来很有希望,直到我发现它需要一些随机命名的实例。但我做不到。因为命名模式和格式是确定的,很多其他事情都取决于实例名、主机名等。我要检查一下是否有其他不可变项可以用于此。还阅读了关于蓝绿色和金丝雀在terraform上的部署:但在我看来,这有点过头了。如果有更简单的东西就好了。此外,使用此解决方案,团队中的每个人都必须记住,您不能更改风格,您需要使用绿-蓝部署。在这种情况下,您可能会陷入困境,除非您可以对其他不可变字段(如用户数据或个性)进行虚假更改。或者是的,您可以在更高的级别上使用蓝色/绿色,配置可以前后翻转,或者使用外部编排器,这会增加复杂性。命名模式是否完全固定?你不能因为任何原因给东西加后缀?哦。我深入研究了openstack提供程序源代码,名称字段也是ForceNew=false。这很有意义,因为在openstack中,您可以简单地重命名正在运行的实例,而不会出现问题。阅读关于个性的书籍。但是找不到任何好的解释它的作用/含义以及它是如何工作的。不妨尝试更改用户_数据,因为这可能是最简单的方法。我不使用OpenStack,因此可能缺少一些东西来完成这里的答案。如果您发现某些内容确实可以直接按照答案进行编辑,我们将不胜感激,因为它将帮助其他有相同问题的用户。如果你走的是一条完全不同的路线(例如使用一个条件变量来做蓝绿色或者在Terraform之外使用一个orchestrator),那么一个单独的