title: Is there a way to prevent the Terraform google_container_cluster from being destroyed and recreated when nothing changes?
body: <p>I know there are similar issues on Github for the Terraform google provider, regarding the idempotency of google_container_cluster; however, none seem to match my simple example.  Any attempt to apply a Terraform plan wants to destroy and recreate my cluster, which is a 6+ minute operation.  </p>
  
  <p>There are no obvious changes to the cluster, but the terraform state suggests that the id of the cluster is the cluster's name, but that the new id is computed; thus, the cluster must be recreated.  Can I prevent this?</p>
  
  <p>I am following the recommended example for setting up a cluster: defining a cluster with <code>remove_initial_node_pool=true</code> and <code>initial_node_count=1</code>, and then creating an explicit node pool as a dependent resource.  I have also tried creating a default cluster using the initial node pool. I am not specifying any additional attributes that others have associated with idempotency issue (such as master_ipv4_cidr_block).</p>
  
  <p>Here is the basic Terraform setup.  I am using Terraform v0.11.13 and provider.google v2.6.0.</p>
  
  <pre><code>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)}"
  }
  </code></pre>
  
  <p>And so on.  Not shown are service account and cluster role binding to enable a Helm service account, and Helm release.  I don't think those matter here.</p>
  
  <p>If I do <code>terraform apply</code> twice, the second invocation wants to destroy and create a new cluster.  Nothing's changed, so this shouldn't happen.<br>
  This would be OK, normally, except that I tend to see lots of timeouts from the terraform provider, and have to re-apply, which gets me nowhere, since reapplying causes the cluster to be destroyed and recreated.  </p>
  
  <p>Output from <code>terraform apply</code> looks like this:</p>
  
  <pre><code>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" =&gt; &lt;computed&gt; (forces new resource)
        additional_zones.#:                              "3" =&gt; &lt;computed&gt;
        addons_config.#:                                 "1" =&gt; &lt;computed&gt;
        cluster_autoscaling.#:                           "0" =&gt; &lt;computed&gt;
        cluster_ipv4_cidr:                               "10.20.0.0/14" =&gt; &lt;computed&gt;
        enable_binary_authorization:                     "" =&gt; &lt;computed&gt;
        enable_kubernetes_alpha:                         "false" =&gt; "false"
        enable_legacy_abac:                              "false" =&gt; "false"
        enable_tpu:                                      "" =&gt; &lt;computed&gt;
        endpoint:                                        "34.66.113.0" =&gt; &lt;computed&gt;
        initial_node_count:                              "1" =&gt; "1"
        instance_group_urls.#:                           "0" =&gt; &lt;computed&gt;
        ip_allocation_policy.#:                          "0" =&gt; &lt;computed&gt;
        location:                                        "us-central1" =&gt; "us-central1"
        logging_service:                                 "logging.googleapis.com" =&gt; &lt;computed&gt;
        master_auth.#:                                   "1" =&gt; "1"
        master_auth.0.client_certificate:                "" =&gt; &lt;computed&gt;
        master_auth.0.client_certificate_config.#:       "1" =&gt; "0" (forces new resource)
        master_auth.0.client_key:                        &lt;sensitive&gt; =&gt; &lt;computed&gt; (attribute changed)
  
  </code></pre>