1.9.3.1. 多可用区分布

这是一个相当常见的小技巧。多数公有云为了高可用性,都在单一区域内提供了多可用区的设计。一个可区是一个逻辑上的数据中心,单个可用区可能由于各种自然灾害、网络故障而导致不可用,所以公有云应用部署高可用应用应时刻考虑跨可用区设计。

假如我们想要创建 N 台不同的云主机实例,在 Terraform 0.12 之前的版本中,我们只能用 count 配合模运算来达成这个目的

variable "az" {
  type    = list(string)
  default = [
    "cn-bj2-03",
    "cn-bj2-04",
  ]
}

variable "instance_count" {
  type    = number
  default = 4
}

data "ucloud_images" "centos" {
  name_regex = "^CentOS 7"
}

resource "ucloud_instance" "web" {
  count             = var.instance_count
  availability_zone = var.az[count.index % length(var.az)]
  image_id          = data.ucloud_images.centos.images[0].id
  instance_type     = "n-standard-1"
  charge_type       = "dynamic"
  name              = "${var.az[count.index % length(var.az)]}-${floor(count.index/length(var.az))}"
}

简单来说就是使用 count 创建多实例资源时,用 var.az[count.index % length(var.az)] 可以循环使用每个可用区,使得机器尽可能均匀分布在各个可用区。

$ terraform apply -auto-approve
data.ucloud_images.centos: Refreshing state...
ucloud_instance.web[2]: Creating...
ucloud_instance.web[0]: Creating...
ucloud_instance.web[1]: Creating...
ucloud_instance.web[3]: Creating...
ucloud_instance.web[2]: Still creating... [10s elapsed]
ucloud_instance.web[0]: Still creating... [10s elapsed]
ucloud_instance.web[1]: Still creating... [10s elapsed]
ucloud_instance.web[3]: Still creating... [10s elapsed]
ucloud_instance.web[2]: Still creating... [20s elapsed]
ucloud_instance.web[0]: Still creating... [20s elapsed]
ucloud_instance.web[1]: Still creating... [20s elapsed]
ucloud_instance.web[3]: Still creating... [20s elapsed]
ucloud_instance.web[2]: Creation complete after 22s [id=uhost-txa2owrp]
ucloud_instance.web[3]: Creation complete after 24s [id=uhost-v3qxdbju]
ucloud_instance.web[1]: Creation complete after 26s [id=uhost-td3x545p]
ucloud_instance.web[0]: Still creating... [30s elapsed]
ucloud_instance.web[0]: Still creating... [40s elapsed]
ucloud_instance.web[0]: Creation complete after 43s [id=uhost-scq1prqj]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

我们可以看一下创建的主机信息:

$ terraform show
# data.ucloud_images.centos:
data "ucloud_images" "centos" {
    id          = "475496684"
    ids         = [
        "uimage-22noyd",
        "uimage-3p0wg0",
        "uimage-4keil1",
        "uimage-aqvo5l",
        "uimage-f1chxn",
        "uimage-hq5elw",
        "uimage-rkn1v2",
    ]
    images      = [
        {
            availability_zone = "cn-bj2-02"
            create_time       = "2019-04-23T17:39:46+08:00"
            description       = ""
            features          = [
                "NetEnhanced",
                "HotPlug",
            ]
            id                = "uimage-rkn1v2"
            name              = "CentOS 7.0 64位"
            os_name           = "CentOS 7.0 64位"
            os_type           = "linux"
            size              = 20
            status            = "Available"
            type              = "base"
        },
        {
            availability_zone = "cn-bj2-02"
            create_time       = "2019-04-16T21:05:03+08:00"
            description       = ""
            features          = [
                "NetEnhanced",
                "HotPlug",
            ]
            id                = "uimage-f1chxn"
            name              = "CentOS 7.2 64位"
            os_name           = "CentOS 7.2 64位"
            os_type           = "linux"
            size              = 20
            status            = "Available"
            type              = "base"
        },
        {
            availability_zone = "cn-bj2-02"
            create_time       = "2019-09-09T11:40:31+08:00"
            description       = " "
            features          = [
                "NetEnhanced",
                "HotPlug",
            ]
            id                = "uimage-aqvo5l"
            name              = "CentOS 7.4 64位"
            os_name           = "CentOS 7.4 64位"
            os_type           = "linux"
            size              = 20
            status            = "Available"
            type              = "base"
        },
        {
            availability_zone = "cn-bj2-02"
            create_time       = "2020-05-07T17:40:42+08:00"
            description       = ""
            features          = [
                "NetEnhanced",
                "HotPlug",
                "CloudInit",
            ]
            id                = "uimage-hq5elw"
            name              = "CentOS 7.6 64位"
            os_name           = "CentOS 7.6 64位"
            os_type           = "linux"
            size              = 20
            status            = "Available"
            type              = "base"
        },
        {
            availability_zone = "cn-bj2-02"
            create_time       = "2019-04-16T21:05:05+08:00"
            description       = ""
            features          = [
                "NetEnhanced",
                "HotPlug",
            ]
            id                = "uimage-3p0wg0"
            name              = "CentOS 7.3 64位"
            os_name           = "CentOS 7.3 64位"
            os_type           = "linux"
            size              = 20
            status            = "Available"
            type              = "base"
        },
        {
            availability_zone = "cn-bj2-02"
            create_time       = "2019-04-16T21:05:02+08:00"
            description       = ""
            features          = [
                "NetEnhanced",
                "HotPlug",
            ]
            id                = "uimage-4keil1"
            name              = "CentOS 7.1 64位"
            os_name           = "CentOS 7.1 64位"
            os_type           = "linux"
            size              = 20
            status            = "Available"
            type              = "base"
        },
        {
            availability_zone = "cn-bj2-02"
            create_time       = "2019-04-16T21:04:53+08:00"
            description       = ""
            features          = [
                "NetEnhanced",
                "HotPlug",
            ]
            id                = "uimage-22noyd"
            name              = "CentOS 7.5 64位"
            os_name           = "CentOS 7.5 64位"
            os_type           = "linux"
            size              = 20
            status            = "Available"
            type              = "base"
        },
    ]
    most_recent = false
    name_regex  = "^CentOS 7"
    total_count = 7
}

# ucloud_instance.web[1]:
resource "ucloud_instance" "web" {
    auto_renew        = true
    availability_zone = "cn-bj2-04"
    boot_disk_size    = 20
    boot_disk_type    = "local_normal"
    charge_type       = "dynamic"
    cpu               = 1
    cpu_platform      = "Intel/Broadwell"
    create_time       = "2020-11-28T23:09:04+08:00"
    disk_set          = [
        {
            id      = "df06380a-00e1-42df-8c07-eec67d817f97"
            is_boot = true
            size    = 20
            type    = "local_normal"
        },
    ]
    expire_time       = "2020-11-29T00:09:06+08:00"
    id                = "uhost-td3x545p"
    image_id          = "uimage-dhe5m2"
    instance_type     = "n-standard-1"
    ip_set            = [
        {
            internet_type = "Private"
            ip            = "10.9.44.37"
        },
    ]
    memory            = 4
    name              = "cn-bj2-04-0"
    private_ip        = "10.9.44.37"
    root_password     = (sensitive value)
    security_group    = "firewall-juhsrlvr"
    status            = "Running"
    subnet_id         = "subnet-dtu3dgpr"
    tag               = "Default"
    vpc_id            = "uvnet-f1c3jq2b"
}

# ucloud_instance.web[2]:
resource "ucloud_instance" "web" {
    auto_renew        = true
    availability_zone = "cn-bj2-03"
    boot_disk_size    = 20
    boot_disk_type    = "local_normal"
    charge_type       = "dynamic"
    cpu               = 1
    cpu_platform      = "Intel/IvyBridge"
    create_time       = "2020-11-28T23:09:01+08:00"
    disk_set          = [
        {
            id      = "1d7f07c9-7342-431b-85bb-d3ee0022063d"
            is_boot = true
            size    = 20
            type    = "local_normal"
        },
    ]
    expire_time       = "2020-11-29T00:09:02+08:00"
    id                = "uhost-txa2owrp"
    image_id          = "uimage-pxplaj"
    instance_type     = "n-standard-1"
    ip_set            = [
        {
            internet_type = "Private"
            ip            = "10.9.45.234"
        },
    ]
    memory            = 4
    name              = "cn-bj2-03-1"
    private_ip        = "10.9.45.234"
    root_password     = (sensitive value)
    security_group    = "firewall-juhsrlvr"
    status            = "Running"
    subnet_id         = "subnet-dtu3dgpr"
    tag               = "Default"
    vpc_id            = "uvnet-f1c3jq2b"
}

# ucloud_instance.web[3]:
resource "ucloud_instance" "web" {
    auto_renew        = true
    availability_zone = "cn-bj2-04"
    boot_disk_size    = 20
    boot_disk_type    = "local_normal"
    charge_type       = "dynamic"
    cpu               = 1
    cpu_platform      = "Intel/Broadwell"
    create_time       = "2020-11-28T23:09:04+08:00"
    disk_set          = [
        {
            id      = "31e2cad6-79a1-4475-a9f5-2c5c95605b18"
            is_boot = true
            size    = 20
            type    = "local_normal"
        },
    ]
    expire_time       = "2020-11-29T00:09:04+08:00"
    id                = "uhost-v3qxdbju"
    image_id          = "uimage-dhe5m2"
    instance_type     = "n-standard-1"
    ip_set            = [
        {
            internet_type = "Private"
            ip            = "10.9.85.40"
        },
    ]
    memory            = 4
    name              = "cn-bj2-04-1"
    private_ip        = "10.9.85.40"
    root_password     = (sensitive value)
    security_group    = "firewall-juhsrlvr"
    status            = "Running"
    subnet_id         = "subnet-dtu3dgpr"
    tag               = "Default"
    vpc_id            = "uvnet-f1c3jq2b"
}

# ucloud_instance.web[0]:
resource "ucloud_instance" "web" {
    auto_renew        = true
    availability_zone = "cn-bj2-03"
    boot_disk_size    = 20
    boot_disk_type    = "local_normal"
    charge_type       = "dynamic"
    cpu               = 1
    cpu_platform      = "Intel/IvyBridge"
    create_time       = "2020-11-28T23:09:04+08:00"
    disk_set          = [
        {
            id      = "da27595d-9645-4883-bf95-87b9076ab7e4"
            is_boot = true
            size    = 20
            type    = "local_normal"
        },
    ]
    expire_time       = "2020-11-29T00:09:04+08:00"
    id                = "uhost-scq1prqj"
    image_id          = "uimage-pxplaj"
    instance_type     = "n-standard-1"
    ip_set            = [
        {
            internet_type = "Private"
            ip            = "10.9.107.152"
        },
    ]
    memory            = 4
    name              = "cn-bj2-03-0"
    private_ip        = "10.9.107.152"
    root_password     = (sensitive value)
    security_group    = "firewall-juhsrlvr"
    status            = "Running"
    subnet_id         = "subnet-dtu3dgpr"
    tag               = "Default"
    vpc_id            = "uvnet-f1c3jq2b"
}

可以看到,主机的确是均匀地分散在两个可用区了。

但是这样做在调整可用区时会发生大问题,例如:

variable "az" {
  type = list(string)
  default = [
    "cn-bj2-03",
#    "cn-bj2-04",
  ]
}

我们禁用了 cn-bj2-04 可用区,按道理我们期待的变更计划应该是将两台原本属于 cn-bj2-04 的主机删除,在 cn-bj2-03 可用区新增两台主机。让我们看看会发生什么:

$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.ucloud_images.centos: Refreshing state... [id=475496684]
ucloud_instance.web[0]: Refreshing state... [id=uhost-scq1prqj]
ucloud_instance.web[3]: Refreshing state... [id=uhost-v3qxdbju]
ucloud_instance.web[2]: Refreshing state... [id=uhost-txa2owrp]
ucloud_instance.web[1]: Refreshing state... [id=uhost-td3x545p]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # ucloud_instance.web[1] must be replaced
-/+ resource "ucloud_instance" "web" {
      ~ auto_renew        = true -> (known after apply)
      ~ availability_zone = "cn-bj2-04" -> "cn-bj2-03" # forces replacement
      ~ boot_disk_size    = 20 -> (known after apply)
      ~ boot_disk_type    = "local_normal" -> (known after apply)
        charge_type       = "dynamic"
      ~ cpu               = 1 -> (known after apply)
      ~ cpu_platform      = "Intel/Broadwell" -> (known after apply)
      ~ create_time       = "2020-11-28T23:09:04+08:00" -> (known after apply)
      + data_disk_size    = (known after apply)
      + data_disk_type    = (known after apply)
      ~ disk_set          = [
          - {
              - id      = "df06380a-00e1-42df-8c07-eec67d817f97"
              - is_boot = true
              - size    = 20
              - type    = "local_normal"
            },
        ] -> (known after apply)
      ~ expire_time       = "2020-11-29T00:09:06+08:00" -> (known after apply)
      ~ id                = "uhost-td3x545p" -> (known after apply)
      ~ image_id          = "uimage-dhe5m2" -> "uimage-rkn1v2"
        instance_type     = "n-standard-1"
      ~ ip_set            = [
          - {
              - internet_type = "Private"
              - ip            = "10.9.44.37"
            },
        ] -> (known after apply)
      + isolation_group   = (known after apply)
      ~ memory            = 4 -> (known after apply)
      ~ name              = "cn-bj2-04-0" -> "cn-bj2-03-1"
      ~ private_ip        = "10.9.44.37" -> (known after apply)
      + remark            = (known after apply)
      ~ root_password     = (sensitive value)
      ~ security_group    = "firewall-juhsrlvr" -> (known after apply)
      ~ status            = "Running" -> (known after apply)
      ~ subnet_id         = "subnet-dtu3dgpr" -> (known after apply)
        tag               = "Default"
      ~ vpc_id            = "uvnet-f1c3jq2b" -> (known after apply)
    }

  # ucloud_instance.web[2] will be updated in-place
  ~ resource "ucloud_instance" "web" {
        auto_renew        = true
        availability_zone = "cn-bj2-03"
        boot_disk_size    = 20
        boot_disk_type    = "local_normal"
        charge_type       = "dynamic"
        cpu               = 1
        cpu_platform      = "Intel/IvyBridge"
        create_time       = "2020-11-28T23:09:01+08:00"
        disk_set          = [
            {
                id      = "1d7f07c9-7342-431b-85bb-d3ee0022063d"
                is_boot = true
                size    = 20
                type    = "local_normal"
            },
        ]
        expire_time       = "2020-11-29T00:09:02+08:00"
        id                = "uhost-txa2owrp"
        image_id          = "uimage-pxplaj"
        instance_type     = "n-standard-1"
        ip_set            = [
            {
                internet_type = "Private"
                ip            = "10.9.45.234"
            },
        ]
        memory            = 4
      ~ name              = "cn-bj2-03-1" -> "cn-bj2-03-2"
        private_ip        = "10.9.45.234"
        root_password     = (sensitive value)
        security_group    = "firewall-juhsrlvr"
        status            = "Running"
        subnet_id         = "subnet-dtu3dgpr"
        tag               = "Default"
        vpc_id            = "uvnet-f1c3jq2b"
    }

  # ucloud_instance.web[3] must be replaced
-/+ resource "ucloud_instance" "web" {
      ~ auto_renew        = true -> (known after apply)
      ~ availability_zone = "cn-bj2-04" -> "cn-bj2-03" # forces replacement
      ~ boot_disk_size    = 20 -> (known after apply)
      ~ boot_disk_type    = "local_normal" -> (known after apply)
        charge_type       = "dynamic"
      ~ cpu               = 1 -> (known after apply)
      ~ cpu_platform      = "Intel/Broadwell" -> (known after apply)
      ~ create_time       = "2020-11-28T23:09:04+08:00" -> (known after apply)
      + data_disk_size    = (known after apply)
      + data_disk_type    = (known after apply)
      ~ disk_set          = [
          - {
              - id      = "31e2cad6-79a1-4475-a9f5-2c5c95605b18"
              - is_boot = true
              - size    = 20
              - type    = "local_normal"
            },
        ] -> (known after apply)
      ~ expire_time       = "2020-11-29T00:09:04+08:00" -> (known after apply)
      ~ id                = "uhost-v3qxdbju" -> (known after apply)
      ~ image_id          = "uimage-dhe5m2" -> "uimage-rkn1v2"
        instance_type     = "n-standard-1"
      ~ ip_set            = [
          - {
              - internet_type = "Private"
              - ip            = "10.9.85.40"
            },
        ] -> (known after apply)
      + isolation_group   = (known after apply)
      ~ memory            = 4 -> (known after apply)
      ~ name              = "cn-bj2-04-1" -> "cn-bj2-03-3"
      ~ private_ip        = "10.9.85.40" -> (known after apply)
      + remark            = (known after apply)
      ~ root_password     = (sensitive value)
      ~ security_group    = "firewall-juhsrlvr" -> (known after apply)
      ~ status            = "Running" -> (known after apply)
      ~ subnet_id         = "subnet-dtu3dgpr" -> (known after apply)
        tag               = "Default"
      ~ vpc_id            = "uvnet-f1c3jq2b" -> (known after apply)
    }

Plan: 2 to add, 1 to change, 2 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

变更计划与期望略有不同。我们仔细看细节:

  # ucloud_instance.web[2] will be updated in-place
  ~ resource "ucloud_instance" "web" {
        auto_renew        = true
        availability_zone = "cn-bj2-03"
        boot_disk_size    = 20
        boot_disk_type    = "local_normal"
        charge_type       = "dynamic"
        cpu               = 1
        cpu_platform      = "Intel/IvyBridge"
        create_time       = "2020-11-28T23:09:01+08:00"
        disk_set          = [
            {
                id      = "1d7f07c9-7342-431b-85bb-d3ee0022063d"
                is_boot = true
                size    = 20
                type    = "local_normal"
            },
        ]
        expire_time       = "2020-11-29T00:09:02+08:00"
        id                = "uhost-txa2owrp"
        image_id          = "uimage-pxplaj"
        instance_type     = "n-standard-1"
        ip_set            = [
            {
                internet_type = "Private"
                ip            = "10.9.45.234"
            },
        ]
        memory            = 4
      ~ name              = "cn-bj2-03-1" -> "cn-bj2-03-2"
        private_ip        = "10.9.45.234"
        root_password     = (sensitive value)
        security_group    = "firewall-juhsrlvr"
        status            = "Running"
        subnet_id         = "subnet-dtu3dgpr"
        tag               = "Default"
        vpc_id            = "uvnet-f1c3jq2b"
    }

原本名为 cn-bj2-03-1 的主机被更名为 cn-bj2-03-2 了,原本属于 cn-bj2-04 的第一台主机的变更计划是:

  # ucloud_instance.web[1] must be replaced
-/+ resource "ucloud_instance" "web" {
      ~ auto_renew        = true -> (known after apply)
      ~ availability_zone = "cn-bj2-04" -> "cn-bj2-03" # forces replacement
      ~ boot_disk_size    = 20 -> (known after apply)
      ~ boot_disk_type    = "local_normal" -> (known after apply)
        charge_type       = "dynamic"
      ~ cpu               = 1 -> (known after apply)
      ~ cpu_platform      = "Intel/Broadwell" -> (known after apply)
      ~ create_time       = "2020-11-28T23:09:04+08:00" -> (known after apply)
      + data_disk_size    = (known after apply)
      + data_disk_type    = (known after apply)
      ~ disk_set          = [
          - {
              - id      = "df06380a-00e1-42df-8c07-eec67d817f97"
              - is_boot = true
              - size    = 20
              - type    = "local_normal"
            },
        ] -> (known after apply)
      ~ expire_time       = "2020-11-29T00:09:06+08:00" -> (known after apply)
      ~ id                = "uhost-td3x545p" -> (known after apply)
      ~ image_id          = "uimage-dhe5m2" -> "uimage-rkn1v2"
        instance_type     = "n-standard-1"
      ~ ip_set            = [
          - {
              - internet_type = "Private"
              - ip            = "10.9.44.37"
            },
        ] -> (known after apply)
      + isolation_group   = (known after apply)
      ~ memory            = 4 -> (known after apply)
      ~ name              = "cn-bj2-04-0" -> "cn-bj2-03-1"
      ~ private_ip        = "10.9.44.37" -> (known after apply)
      + remark            = (known after apply)
      ~ root_password     = (sensitive value)
      ~ security_group    = "firewall-juhsrlvr" -> (known after apply)
      ~ status            = "Running" -> (known after apply)
      ~ subnet_id         = "subnet-dtu3dgpr" -> (known after apply)
        tag               = "Default"
      ~ vpc_id            = "uvnet-f1c3jq2b" -> (known after apply)
    }

它的名字从 cn-bj2-04-0 变成了 cn-bj2-03-1

仔细想想,实际上这是一个比较低效的变更计划。原本属于 cn-bj2-03 的两台主机应该不做任何变更,只需要删除 cn-bj2-04 的主机,再补充两台 cn-bj2-03 的主机即可。这是因为我们使用的是 count,而 count 只看元素在列表中的序号。当我们删除一个可用区时,实际上会引起主机序号的重大变化,导致出现大量低效的变更,这就是我们在讲 countfor_each 时强调过的,如果创建的资源实例彼此之间几乎完全一致,那么 count 比较合适。否则,那么使用 for_each 会更加安全。

让我们尝试使用 for_each 改写这段逻辑:

variable "az" {
  type    = list(string)
  default = [
    "cn-bj2-03",
    "cn-bj2-04",
  ]
}

variable "instance_count" {
  type    = number
  default = 4
}

locals {
  instance_names = [for i in range(var.instance_count):"${var.az[i%length(var.az)]}-${floor(i/length(var.az))}"]
}

data "ucloud_images" "centos" {
  name_regex = "^CentOS 7"
}

resource "ucloud_instance" "web" {
  for_each          = toset(local.instance_names)
  name              = each.value
  availability_zone = var.az[index(local.instance_names, each.value) % length(var.az)]
  image_id          = data.ucloud_images.centos.images[0].id
  instance_type     = "n-standard-1"
  charge_type       = "dynamic"
}

为了生成主机独一无二的名字,我们首先用 range 函数生成了一个序号集合,比如目标主机数是 4,那么 range(4) 的结果就是 [0, 1, 2, 3];然后我们通过取模运算使得名字前缀在可用区列表之间循环递增,最后用 floor(i/length(var.az)) 计算出当前序号对应在当前可用区是第几台。例如 4 号主机在第二个可用区就是第二台,生成的名字应该就是 cn-bj-04-1

执行结果是:

$ terraform apply -auto-approve
data.ucloud_images.centos: Refreshing state...
ucloud_instance.web["cn-bj2-03-1"]: Creating...
ucloud_instance.web["cn-bj2-03-0"]: Creating...
ucloud_instance.web["cn-bj2-04-0"]: Creating...
ucloud_instance.web["cn-bj2-04-1"]: Creating...
ucloud_instance.web["cn-bj2-03-1"]: Still creating... [10s elapsed]
ucloud_instance.web["cn-bj2-03-0"]: Still creating... [10s elapsed]
ucloud_instance.web["cn-bj2-04-0"]: Still creating... [10s elapsed]
ucloud_instance.web["cn-bj2-04-1"]: Still creating... [10s elapsed]
ucloud_instance.web["cn-bj2-03-1"]: Still creating... [20s elapsed]
ucloud_instance.web["cn-bj2-03-0"]: Still creating... [20s elapsed]
ucloud_instance.web["cn-bj2-04-0"]: Still creating... [20s elapsed]
ucloud_instance.web["cn-bj2-04-1"]: Still creating... [20s elapsed]
ucloud_instance.web["cn-bj2-04-1"]: Creation complete after 21s [id=uhost-fjci1i4o]
ucloud_instance.web["cn-bj2-04-0"]: Creation complete after 23s [id=uhost-bkkhmref]
ucloud_instance.web["cn-bj2-03-1"]: Creation complete after 26s [id=uhost-amosgdaa]
ucloud_instance.web["cn-bj2-03-0"]: Still creating... [30s elapsed]
ucloud_instance.web["cn-bj2-03-0"]: Still creating... [40s elapsed]
ucloud_instance.web["cn-bj2-03-0"]: Creation complete after 45s [id=uhost-kltudgnf]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

如果我们去掉一个可用区:

variable "az" {
  type = list(string)
  default = [
    "cn-bj2-03",
#    "cn-bj2-04",
  ]
}

我们可以检查一下执行计划:

$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.ucloud_images.centos: Refreshing state... [id=475496684]
ucloud_instance.web["cn-bj2-03-1"]: Refreshing state... [id=uhost-amosgdaa]
ucloud_instance.web["cn-bj2-04-0"]: Refreshing state... [id=uhost-bkkhmref]
ucloud_instance.web["cn-bj2-03-0"]: Refreshing state... [id=uhost-kltudgnf]
ucloud_instance.web["cn-bj2-04-1"]: Refreshing state... [id=uhost-fjci1i4o]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  # ucloud_instance.web["cn-bj2-03-2"] will be created
  + resource "ucloud_instance" "web" {
      + auto_renew        = (known after apply)
      + availability_zone = "cn-bj2-03"
      + boot_disk_size    = (known after apply)
      + boot_disk_type    = (known after apply)
      + charge_type       = "dynamic"
      + cpu               = (known after apply)
      + cpu_platform      = (known after apply)
      + create_time       = (known after apply)
      + data_disk_size    = (known after apply)
      + data_disk_type    = (known after apply)
      + disk_set          = (known after apply)
      + expire_time       = (known after apply)
      + id                = (known after apply)
      + image_id          = "uimage-rkn1v2"
      + instance_type     = "n-standard-1"
      + ip_set            = (known after apply)
      + isolation_group   = (known after apply)
      + memory            = (known after apply)
      + name              = "cn-bj2-03-2"
      + private_ip        = (known after apply)
      + remark            = (known after apply)
      + root_password     = (sensitive value)
      + security_group    = (known after apply)
      + status            = (known after apply)
      + subnet_id         = (known after apply)
      + tag               = "Default"
      + vpc_id            = (known after apply)
    }

  # ucloud_instance.web["cn-bj2-03-3"] will be created
  + resource "ucloud_instance" "web" {
      + auto_renew        = (known after apply)
      + availability_zone = "cn-bj2-03"
      + boot_disk_size    = (known after apply)
      + boot_disk_type    = (known after apply)
      + charge_type       = "dynamic"
      + cpu               = (known after apply)
      + cpu_platform      = (known after apply)
      + create_time       = (known after apply)
      + data_disk_size    = (known after apply)
      + data_disk_type    = (known after apply)
      + disk_set          = (known after apply)
      + expire_time       = (known after apply)
      + id                = (known after apply)
      + image_id          = "uimage-rkn1v2"
      + instance_type     = "n-standard-1"
      + ip_set            = (known after apply)
      + isolation_group   = (known after apply)
      + memory            = (known after apply)
      + name              = "cn-bj2-03-3"
      + private_ip        = (known after apply)
      + remark            = (known after apply)
      + root_password     = (sensitive value)
      + security_group    = (known after apply)
      + status            = (known after apply)
      + subnet_id         = (known after apply)
      + tag               = "Default"
      + vpc_id            = (known after apply)
    }

  # ucloud_instance.web["cn-bj2-04-0"] will be destroyed
  - resource "ucloud_instance" "web" {
      - auto_renew        = true -> null
      - availability_zone = "cn-bj2-04" -> null
      - boot_disk_size    = 20 -> null
      - boot_disk_type    = "local_normal" -> null
      - charge_type       = "dynamic" -> null
      - cpu               = 1 -> null
      - cpu_platform      = "Intel/Broadwell" -> null
      - create_time       = "2020-11-28T22:35:53+08:00" -> null
      - disk_set          = [
          - {
              - id      = "b214d840-ffec-4958-a3da-3580846fd2a3"
              - is_boot = true
              - size    = 20
              - type    = "local_normal"
            },
        ] -> null
      - expire_time       = "2020-11-28T23:35:53+08:00" -> null
      - id                = "uhost-bkkhmref" -> null
      - image_id          = "uimage-dhe5m2" -> null
      - instance_type     = "n-standard-1" -> null
      - ip_set            = [
          - {
              - internet_type = "Private"
              - ip            = "10.9.48.82"
            },
        ] -> null
      - memory            = 4 -> null
      - name              = "cn-bj2-04-0" -> null
      - private_ip        = "10.9.48.82" -> null
      - root_password     = (sensitive value)
      - security_group    = "firewall-juhsrlvr" -> null
      - status            = "Running" -> null
      - subnet_id         = "subnet-dtu3dgpr" -> null
      - tag               = "Default" -> null
      - vpc_id            = "uvnet-f1c3jq2b" -> null
    }

  # ucloud_instance.web["cn-bj2-04-1"] will be destroyed
  - resource "ucloud_instance" "web" {
      - auto_renew        = true -> null
      - availability_zone = "cn-bj2-04" -> null
      - boot_disk_size    = 20 -> null
      - boot_disk_type    = "local_normal" -> null
      - charge_type       = "dynamic" -> null
      - cpu               = 1 -> null
      - cpu_platform      = "Intel/Broadwell" -> null
      - create_time       = "2020-11-28T22:35:53+08:00" -> null
      - disk_set          = [
          - {
              - id      = "6a3f274f-e072-4a46-90f8-edc7dbaa27f7"
              - is_boot = true
              - size    = 20
              - type    = "local_normal"
            },
        ] -> null
      - expire_time       = "2020-11-28T23:35:53+08:00" -> null
      - id                = "uhost-fjci1i4o" -> null
      - image_id          = "uimage-dhe5m2" -> null
      - instance_type     = "n-standard-1" -> null
      - ip_set            = [
          - {
              - internet_type = "Private"
              - ip            = "10.9.176.28"
            },
        ] -> null
      - memory            = 4 -> null
      - name              = "cn-bj2-04-1" -> null
      - private_ip        = "10.9.176.28" -> null
      - root_password     = (sensitive value)
      - security_group    = "firewall-juhsrlvr" -> null
      - status            = "Running" -> null
      - subnet_id         = "subnet-dtu3dgpr" -> null
      - tag               = "Default" -> null
      - vpc_id            = "uvnet-f1c3jq2b" -> null
    }

Plan: 2 to add, 0 to change, 2 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

可以看到,原来属于 cn-bj2-03 的两台主机原封不动,删除了属于 cn-bj2-04 的两台主机,并且在 cn-bj2-03 可用区新增两台主机。

results matching ""

    No results matching ""