1

openstack_compute_instance_v2用来在 OpenStack 中创建实例。存在生命周期设置create_before_destroy = true。如果我更改卷大小(需要替换实例),它就可以正常工作。

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

我怎样才能改变这种行为?

Ansible 中的一些设置serial或其他一些选项会派上用场。但我什么也找不到。任何能让我说“至少有一半的实例需要始终在线”的解决方案。

地形版本:12.20。

TF计划:https ://pastebin.com/ECfWYYX3

4

2 回答 2

2

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因为它也是一个不可变字段。因此,一个基本示例可能如下所示:

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"
  }
}
于 2020-04-16T09:44:34.233 回答
0

所以。起初,我已经开始研究如何按照@ydaetskcoR 的建议使用随机实例名称。

Name不是一个选项,既因为在 openstack 中它是一个可变参数,又因为我有一个无法更改的确定命名模式。

我已经开始寻找可以修改的其他参数,以强制创建而不是修改实例。我发现了关于personality. https://www.terraform.io/docs/providers/openstack/r/compute_instance_v2.html#instance-with-personality

但它也没有奏效。主要是因为似乎不再支持个性:

从 2.57 微版本开始,不推荐使用个性文件。使用 metadata 和 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" {
于 2020-04-16T12:41:13.560 回答