0
votes

I'm trying to run a terraform script which accepts the parameter of VM size, network details and image details to spin up a new VM from the user. If I run the script second time, it destroys the resources created the first time, which I don't want. What could be the possible solution to keep the resources it created the first time?

Just a glimpse of what I'm running through:

resource "google_compute_network" "custom" {
  name = "test-ntwrk"
  auto_create_subnetworks = false,
}

resource "google_compute_subnetwork" "custom-subnet" {
  count = "${var.count}"
  name = "${var.name[count.index]}",
  ip_cidr_range = "${var.cidrs[count.index]}",
  region = "asia-south1",
  network = "${google_compute_network.custom.self_link}"
}

This makes the subnet with the given range, which, lets say ["10.0.1.0/24", "10.0.2.0/24"].

When I re-run the same script to add 2 more subnets with CIDR range ["10.0.3.0/24, 10.0.4.0/24] to the already created script, the terraform plan shows me something like this:

Google_compute_subnetwork.custom-subnet[0] (new resource required)
      id:                        "asia-south1/subnet-tf-0" => <computed> (forces new resource)
      creation_timestamp:        "2019-02-06T11:34:34.371-08:00" => <computed>
      gateway_address:           "10.0.1.1" => <computed>
      ip_cidr_range:             "10.0.1.0/24" => "10.3.0.0/24" (forces new resource)
      name:                      "subnet-tf-0" => "subnet-tf-0"
      network:                   "https://www.googleapis.com/compute/v1/projects/cio-demopoc-project-228209/global/networks/test-ntwrk" => "https://www.googleapis.com/compute/v1/projects/cio-demopoc-project-228209/global/networks/test-ntwrk"
      project:                   "xxxxxxxxxx" => <computed>
      region:                    "asia-south1" => "asia-south1"
      secondary_ip_range.#:      "0" => <computed>
      self_link:                 "https://www.googleapis.com/compute/v1/projects/cio-demopoc-project-228209/regions/asia-south1/subnetworks/subnet-tf-0" => <computed>

-/+ google_compute_subnetwork.custom-subnet[1] (new resource required)
      id:                        "asia-south1/subnet-tf-1" => <computed> (forces new resource)
      creation_timestamp:        "2019-02-06T22:31:39.600-08:00" => <computed>
      fingerprint:               "rt9soQpV_Nw=" => <computed>
      gateway_address:           "10.0.2.1" => <computed>
      ip_cidr_range:             "10.0.2.0/24" => "10.0.4.0/24" (forces new resource)
      name:                      "subnet-tf-1" => "subnet-tf-1"
      network:                   "https://www.googleapis.com/compute/v1/projects/cio-demopoc-project-228209/global/networks/test-ntwrk" => "https://www.googleapis.com/compute/v1/projects/cio-demopoc-project-228209/global/networks/test-ntwrk"
      project:                   "xxxxxxxxxx" => <computed>
      region:                    "asia-south1" => "asia-south1"
      secondary_ip_range.#:      "0" => <computed>
      self_link:                 "https://www.googleapis.com/compute/v1/project

Running this script 2nd time, forces the creation of resources and replacing the existing one, which I don't want.

Expected output: All the 4 subnets should be created within the VPC.

1
Can you post the Terraform code and the plan output? If there's a lot of code it may be worth reducing it to a minimal reproducible example so that others can clearly see what the issue is.ydaetskcoR
We need to see the code - typically this happens because of the user data. Terraform has bug where in some OSs the userdata bug indicates that it has change all the time and destroys the vm.victor m
How are you adding the extra CIDR blocks? Are you appending to the list or replacing the existing ones? It looks like the latter from what you've described so far. It would help if you could show the exact, reproducible steps to get to your issue. So in your case you could show the code and the input variables from your first apply and then show the change to the variables for the next plan with the plan output shown as you have now.ydaetskcoR

1 Answers

0
votes

I'd need to see the Terraform Plan output in order to see exactly why resources get recreated. The changes in question will be marked as "(forces new resource)".

It may be the result of computed/generated values/parameters of which Terraform cannot see in advance what the output will be. Such as a randomised value being assigned to a variable, or usage of the "depends_on" variable in a resource. The latter can trigger Terraform to compute the values apply-time instead of plan-time, in which case it will always mark the dependent resource as having to be recreated.

I've also noticed that template files can cause this behaviour, because of line endings and what not in the source file, for which Terraform kept seeing a change between e.g. previously applied user data and the user data source file on disk.

Please run terraform plan and check for which variable forces the new resource. Going over these one by one and evaluating what's happening, will allow you to determine wether or not it is logical for Terraform to recreate the resource.

If you wish further help, please post the output here, preferably also the Terraform code.

UPDATE: Looking at your Terraform Plan output, it seems that the two new CIDR blocks are being assigned to your existing resources. Are you sure you added the two CIDR blocks to the previous ones, resulting in an array containing 4 CIDR blocks in total?

Terraform is not so much a script (as you refer to it) as it is a state; If you already applied your previous two subnets, changing the values in the Terraform code will cause those two subnets to be modified, instead of creating two additional subnets. Re-running the same Terraform code should result in exactly zero changes, not in the same resources being added again and again.