Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.0 release upgrade guide #127

Merged
merged 3 commits into from
Dec 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 54 additions & 116 deletions docs/upgrading_to_v2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,138 +7,41 @@ Because v2.x changed how the subnet resource is iterated on, resources in Terraf

## Migration Instructions

- Upgrade to the new version of this module.
First, upgrade to the new version of this module.

if you run `terraform plan` at this point. Terraform will inform you that it will attempt to delete and recreate your existing subnets. This is almost certainly not the behavior you want. For example:
```diff
module "kubernetes_engine_private_cluster" {
source = "terraform-google-modules/network/google"
- version = "~> 1.5"
+ version = "~> 2.0"

```Shell
Terraform will perform the following actions:

# module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork will be destroyed
- resource "google_compute_subnetwork" "subnetwork" {
- creation_timestamp = "2019-10-02T08:40:26.282-07:00" -> null
- enable_flow_logs = false -> null
- fingerprint = "f8LZx006zY4=" -> null
- gateway_address = "10.10.10.1" -> null
- id = "us-west1/simple-project-timh-subnet-01" -> null
- ip_cidr_range = "10.10.10.0/24" -> null
- name = "simple-project-timh-subnet-01" -> null
- network = "https://www.googleapis.com/compute/v1/projects/dev-xpn-networking/global/networks/simple-project-timh" -> null
- private_ip_google_access = false -> null
- project = "dev-xpn-networking" -> null
- region = "us-west1" -> null
- secondary_ip_range = [] -> null
- self_link = "https://www.googleapis.com/compute/v1/projects/dev-xpn-networking/regions/us-west1/subnetworks/simple-project-timh-subnet-01" -> null
}

# module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[1] will be destroyed
- resource "google_compute_subnetwork" "subnetwork" {
- creation_timestamp = "2019-10-02T08:40:26.292-07:00" -> null
- enable_flow_logs = true -> null
- fingerprint = "wOwStN9lK-Q=" -> null
- gateway_address = "10.10.20.1" -> null
- id = "us-west1/simple-project-timh-subnet-02" -> null
- ip_cidr_range = "10.10.20.0/24" -> null
- name = "simple-project-timh-subnet-02" -> null
- network = "https://www.googleapis.com/compute/v1/projects/dev-xpn-networking/global/networks/simple-project-timh" -> null
- private_ip_google_access = true -> null
- project = "dev-xpn-networking" -> null
- region = "us-west1" -> null
- secondary_ip_range = [] -> null
- self_link = "https://www.googleapis.com/compute/v1/projects/dev-xpn-networking/regions/us-west1/subnetworks/simple-project-timh-subnet-02" -> null
}

# module.example.module.test-vpc-module.google_compute_subnetwork.module.subnets.subnetwork["us-west1/simple-project-timh-subnet-01"] will be created
+ resource "google_compute_subnetwork" "subnetwork" {
+ creation_timestamp = (known after apply)
+ enable_flow_logs = false
+ fingerprint = (known after apply)
+ gateway_address = (known after apply)
+ id = (known after apply)
+ ip_cidr_range = "10.10.10.0/24"
+ name = "simple-project-timh-subnet-01"
+ network = "simple-project-timh"
+ private_ip_google_access = false
+ project = "dev-xpn-networking"
+ region = "us-west1"
+ secondary_ip_range = []
+ self_link = (known after apply)
}

# module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork["us-west1/simple-project-timh-subnet-02"] will be created
+ resource "google_compute_subnetwork" "subnetwork" {
+ creation_timestamp = (known after apply)
+ enable_flow_logs = true
+ fingerprint = (known after apply)
+ gateway_address = (known after apply)
+ id = (known after apply)
+ ip_cidr_range = "10.10.20.0/24"
+ name = "simple-project-timh-subnet-02"
+ network = "simple-project-timh"
+ private_ip_google_access = true
+ project = "dev-xpn-networking"
+ region = "us-west1"
+ secondary_ip_range = []
+ self_link = (known after apply)
}

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.
# ...
}
```

### Manual Migration Steps

In this example here are the commands used migrate the vpc and subnets created by the `simple_project` in the examples directory. _please note the need to escape the quotes on the new resource_. You may also use the migration script.

- `terraform state mv module.example.module.test-vpc-module.google_compute_network.network module.example.module.test-vpc-module.module.vpc.google_compute_subnetwork.network`

- `terraform state mv module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork`

- `terraform state mv module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork[0] module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-01\"]`

- `terraform state mv module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork[1] module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-02\"]`

*You'll notice that because of a terraform [issue](https://github.com/hashicorp/terraform/issues/22301), we need to move the whole resource collection first before renaming to the `for_each` keys*

`terraform plan` should now return a no-op and show no new changes.

```Shell
$ 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.
If you run `terraform plan` at this point, Terraform will inform you that it will attempt to delete and recreate your existing subnets. This is almost certainly not the behavior you want.

module.example.module.test-vpc-module.google_compute_network.network: Refreshing state... [id=simple-project-timh]
module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork["us-west1/simple-project-timh-subnet-02"]: Refreshing state... [id=us-west1/simple-project-timh-subnet-02]
module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork["us-west1/simple-project-timh-subnet-01"]: Refreshing state... [id=us-west1/simple-project-timh-subnet-01]

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

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
```
You will need to migrate your state, either [manually](#manual-migration-steps) or [automatically](#migration-script).

### Migration Script

1. Download the script
1. Download the script:

```sh
curl -O https://raw.githubusercontent.com/terraform-google-modules/terraform-google-network/master/helpers/migrate.py
chmod +x migrate.py
```

2. Back up your Terraform state:

```sh
terraform state pull >> state.bak
```

2. Run the script to output the migration commands:

```sh
$ ./migrate.py --dry-run
$ ./migrate.py --dryrun
terraform state mv 'module.example.module.test-vpc-module-02.google_compute_network.network[0]' 'module.example.module.test-vpc-module-02.module.vpc.google_compute_network.network'
terraform state mv 'module.example.module.test-vpc-module-02.google_compute_subnetwork.subnetwork' 'module.example.module.test-vpc-module-02.module.subnets.google_compute_subnetwork.subnetwork'
terraform state mv 'module.example.module.test-vpc-module-02.module.subnets.google_compute_subnetwork.subnetwork[0]' 'module.example.module.test-vpc-module-02.module.subnets.google_compute_subnetwork.subnetwork["us-west1/multi-vpc-a1-02-subnet-01"]'
Expand All @@ -149,7 +52,7 @@ actions need to be performed.

```

3. Execute the migration command
3. Execute the migration script:

```sh
$ ./migrate.py
Expand All @@ -175,6 +78,41 @@ actions need to be performed.

4. Run `terraform plan` to confirm no changes are expected.

### Manual Migration Steps

In this example here are the commands used migrate the vpc and subnets created by the `simple_project` in the examples directory. _please note the need to escape the quotes on the new resource_. You may also use the migration script.

- `terraform state mv module.example.module.test-vpc-module.google_compute_network.network module.example.module.test-vpc-module.module.vpc.google_compute_subnetwork.network`

- `terraform state mv module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork`

- `terraform state mv module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork[0] module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-01\"]`

- `terraform state mv module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork[1] module.example.module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-02\"]`

*You'll notice that because of a terraform [issue](https://github.com/hashicorp/terraform/issues/22301), we need to move the whole resource collection first before renaming to the `for_each` keys*

`terraform plan` should now return a no-op and show no new changes.

```Shell
$ 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.

module.example.module.test-vpc-module.google_compute_network.network: Refreshing state... [id=simple-project-timh]
module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork["us-west1/simple-project-timh-subnet-02"]: Refreshing state... [id=us-west1/simple-project-timh-subnet-02]
module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork["us-west1/simple-project-timh-subnet-01"]: Refreshing state... [id=us-west1/simple-project-timh-subnet-01]

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

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
```

### Known Issues

If your previous state only contains a **single** subnet or route then `terraform mv` will throw an error similar to the following during migration:
Expand Down
5 changes: 3 additions & 2 deletions helpers/migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
{
"resource_type": "google_compute_shared_vpc_host_project",
"name": "shared_vpc_host",
"module": ".module.vpc"
"module": ".module.vpc",
"new_plural": False
},
{
"resource_type": "google_compute_subnetwork",
Expand Down Expand Up @@ -280,7 +281,7 @@ def read_state(self):
def resource_value(self, resource, key):
# Find the resource in the state
state_resource_list = [r for r in self.state["resources"] if
r["module"] == resource.module and
r.get("module", "none") == resource.module and
r["type"] == resource.resource_type and
r["name"] == resource.name]

Expand Down