Есть ли способ предотвратить разрушение и воссоздание Terraform google_container_cluster, когда ничего не меняется? - PullRequest
0 голосов
/ 20 мая 2019

Я знаю, что на Github существуют аналогичные проблемы для поставщика Terraform google, касающиеся идемпотентности google_container_cluster;однако ни один из них не соответствует моему простому примеру.Любая попытка применить план Terraform хочет уничтожить и воссоздать мой кластер, что занимает более 6 минут.

Нет очевидных изменений в кластере, но состояние terraform предполагает, что id кластера является именем кластера, но что новый id вычисляется;таким образом, кластер должен быть воссоздан.Можно ли это предотвратить?

Я следую рекомендованному примеру для настройки кластера: определим кластер с remove_initial_node_pool=true и initial_node_count=1, а затем создадим явный пул узлов в качестве зависимого ресурса.Я также попытался создать кластер по умолчанию, используя начальный пул узлов.Я не указываю никаких дополнительных атрибутов, которые другие связывают с проблемой идемпотентности (например, master_ipv4_cidr_block).

Здесь приведены основные настройки Terraform.Я использую Terraform v0.11.13 и provider.google v2.6.0.

provider "google" {
  project     = "${var.google_project}"
  region      = "${var.google_region}"
  zone        = "${var.google_zone}"
}

resource "google_container_cluster" "cluster" {
  project                  = "${var.google_project}"
  name                     = "${var.cluster_name}"
  location                 = "${var.google_region}"

  remove_default_node_pool = true
  initial_node_count       = 1

  master_auth {
    username = ""
    password = ""
  }

  timeouts {
    create = "20m"
    update = "15m"
    delete = "15m"
  }

}

resource "google_container_node_pool" "cluster_nodes" {
  name       = "${var.cluster_name}-node-pool"
  cluster    = "${google_container_cluster.cluster.name}"
  node_count = "${var.cluster_node_count}"

  node_config {
    preemptible  = "${var.preemptible}"
    disk_size_gb = "${var.disk_size_gb}"
    disk_type    = "${var.disk_type}"
    machine_type = "${var.machine_type}"
    oauth_scopes = [
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
      "https://www.googleapis.com/auth/service.management.readonly",
      "https://www.googleapis.com/auth/servicecontrol",
      "https://www.googleapis.com/auth/trace.append",
      "https://www.googleapis.com/auth/compute",
      "https://www.googleapis.com/auth/cloud-platform",
    ]
  }

  timeouts {
    create = "20m"
    update = "15m"
    delete = "15m"
  }
}

output "cluster_ca_certificate" {
  value = "${google_container_cluster.cluster.master_auth.0.cluster_ca_certificate}"
}

output "host" {
  value = "${google_container_cluster.cluster.endpoint}"
}

provider "kubernetes" {
  host                   = "${google_container_cluster.cluster.endpoint}"
  client_certificate     = "${base64decode(google_container_cluster.cluster.master_auth.0.client_certificate)}"
  client_key             = "${base64decode(google_container_cluster.cluster.master_auth.0.client_key)}"
  cluster_ca_certificate = "${base64decode(google_container_cluster.cluster.master_auth.0.cluster_ca_certificate)}"
}

И так далее.Не показаны привязка учетной записи службы и роли кластера для включения учетной записи службы Helm и выпуска Helm.Я не думаю, что это имеет значение здесь.

Если я сделаю terraform apply дважды, второй вызов захочет уничтожить и создать новый кластер.Ничего не изменилось, так что это не должно происходить.
Это было бы нормально, за исключением того, что я склонен видеть много тайм-аутов от поставщика terraform, и мне приходится повторно применять, что никуда меня не приводит, так как повторное применение вызываеткластер подлежит уничтожению и воссозданию.

Вывод terraform apply выглядит следующим образом:

terraform-gke$ terraform apply
data.template_file.gke_values: Refreshing state...
google_container_cluster.cluster: Refreshing state... (ID: test-eric)

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

Terraform will perform the following actions:

-/+ google_container_cluster.cluster (new resource required)
      id:                                              "test-eric" => <computed> (forces new resource)
      additional_zones.#:                              "3" => <computed>
      addons_config.#:                                 "1" => <computed>
      cluster_autoscaling.#:                           "0" => <computed>
      cluster_ipv4_cidr:                               "10.20.0.0/14" => <computed>
      enable_binary_authorization:                     "" => <computed>
      enable_kubernetes_alpha:                         "false" => "false"
      enable_legacy_abac:                              "false" => "false"
      enable_tpu:                                      "" => <computed>
      endpoint:                                        "34.66.113.0" => <computed>
      initial_node_count:                              "1" => "1"
      instance_group_urls.#:                           "0" => <computed>
      ip_allocation_policy.#:                          "0" => <computed>
      location:                                        "us-central1" => "us-central1"
      logging_service:                                 "logging.googleapis.com" => <computed>
      master_auth.#:                                   "1" => "1"
      master_auth.0.client_certificate:                "" => <computed>
      master_auth.0.client_certificate_config.#:       "1" => "0" (forces new resource)
      master_auth.0.client_key:                        <sensitive> => <computed> (attribute changed)

Ответы [ 2 ]

0 голосов
/ 21 мая 2019

Итак, в конечном счете, это ошибка провайдера, но она была вызвана изменениями в поведении главной службы kubernetes, между версиями 1.11.x и 1.12.x, которые Google недавно выпустила в качестве значения по умолчанию для узлов GKE. , Он фиксируется в выпусках Github поставщика Google Terraform как # 3369 .

Обходной путь - сказать Terraform игнорировать изменения в master_auth и network:

resource google_container_cluster cluster {
  master_auth {
    username = ""
    password = ""
  }
  # Workaround for issue 3369 (until provider version 3.0.0?)
  # This is necessary when using GKE node version 1.12.x or later.
  # It is possible to make GKE use node version 1.11.x as an
  # alternative workaround.
  lifecycle {
    ignore_changes = [ "master_auth", "network" ]
  }
}

nb, Возможно, чтобы помочь другим с той же проблемой ... Трудно искать места, такие как Интернет и Github, чтобы найти соответствующие ответы на подобные проблемы, потому что авторы используют много разных терминов для описания такое поведение, которое проявлял Терраформ. Эта проблема иногда также описывается как проблема с идемпотентностью Terraform и изменениями Terraform.

0 голосов
/ 21 мая 2019

Кажется, вы переключились с базовой (имя пользователя / пароль) на авторизацию TLS, так как, согласно вашим журналам, у вас сгенерирован новый сертификат, и он вызывает новый кластер.

...