|
| 1 | +# Upgrading to v4.x |
| 2 | + |
| 3 | +The v4.x release is a backwards-incompatible release. |
| 4 | + |
| 5 | +The `resources` inside perimeters have been split into their [own Terraform resource](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/access_context_manager_service_perimeter_resource). |
| 6 | +This allows you to add resources (projects) to the perimeter from *outside* the module. |
| 7 | + |
| 8 | +However, this change has a few implications: |
| 9 | +1. Resources added to the perimeter out-of-band will no longer be removed by Terraform. |
| 10 | + You will need to develop an alternative system for dealing with these. |
| 11 | +2. The location of resources has moved in the state file. |
| 12 | +3. Because resources are now created using `for_each`, if the underlying project is created in the **same** |
| 13 | + Terraform configuration as the perimeter, you will need to provide a `resource_keys` variable. |
| 14 | + |
| 15 | +## Dynamic resources |
| 16 | +If resources are created inside the same configuration as the perimeter, you will received an error that their value cannot be determined until apply: |
| 17 | +``` |
| 18 | +│ Error: Invalid for_each argument |
| 19 | +│ |
| 20 | +│ on ../../modules/regular_service_perimeter/main.tf line 195, in resource "google_access_context_manager_service_perimeter_resource" "service_perimeter_resource": |
| 21 | +│ 195: for_each = local.resources |
| 22 | +│ ├──────────────── |
| 23 | +│ │ local.resources will be known only after apply |
| 24 | +``` |
| 25 | + |
| 26 | +To work around this, you need to provide a `resource_keys` variable input with keys for each resource. These keys are only used by Terraform and can be any alphanumeric string. |
| 27 | + |
| 28 | +```diff |
| 29 | + module "regular_service_perimeter_2" { |
| 30 | + source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter" |
| 31 | +- version = "~> 3.0" |
| 32 | ++ version = "~> 4.0" |
| 33 | + |
| 34 | + ... |
| 35 | + |
| 36 | + resources = [module.project_two.project_number, module.project_three.project_number] |
| 37 | ++ resource_keys = ["two", "three"] |
| 38 | +} |
| 39 | + |
| 40 | +module "bridge" { |
| 41 | + source = "terraform-google-modules/vpc-service-controls/google//modules/bridge_service_perimeter" |
| 42 | +- version = "~> 3.0" |
| 43 | ++ version = "~> 4.0" |
| 44 | + |
| 45 | + ... |
| 46 | + |
| 47 | + resources = concat( |
| 48 | + module.regular_service_perimeter_1.shared_resources["all"], |
| 49 | + module.regular_service_perimeter_2.shared_resources["all"], |
| 50 | + ) |
| 51 | ++ resource_keys = ["one", "two", "three"] |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +## State migration |
| 56 | + |
| 57 | +If you run `terraform plan` on an upgraded module, you will notice that Terraform wants to add `service_perimeter` resources. |
| 58 | + |
| 59 | +``` |
| 60 | +Terraform will perform the following actions: |
| 61 | +
|
| 62 | + # module.bridge.google_access_context_manager_service_perimeter_resource.service_perimeter_resource["projects/34502780858"] will be created |
| 63 | + + resource "google_access_context_manager_service_perimeter_resource" "service_perimeter_resource" { |
| 64 | + + id = (known after apply) |
| 65 | + + perimeter_name = "accessPolicies/209696272439/servicePerimeters/bridge_perimeter_1" |
| 66 | + + resource = "projects/34502780858" |
| 67 | + } |
| 68 | +
|
| 69 | + # module.bridge.google_access_context_manager_service_perimeter_resource.service_perimeter_resource["projects/843696391937"] will be created |
| 70 | + + resource "google_access_context_manager_service_perimeter_resource" "service_perimeter_resource" { |
| 71 | + + id = (known after apply) |
| 72 | + + perimeter_name = "accessPolicies/209696272439/servicePerimeters/bridge_perimeter_1" |
| 73 | + + resource = "projects/843696391937" |
| 74 | + } |
| 75 | +
|
| 76 | + # module.regular_service_perimeter_1.google_access_context_manager_service_perimeter_resource.service_perimeter_resource["34502780858"] will be created |
| 77 | + + resource "google_access_context_manager_service_perimeter_resource" "service_perimeter_resource" { |
| 78 | + + id = (known after apply) |
| 79 | + + perimeter_name = "accessPolicies/209696272439/servicePerimeters/regular_perimeter_1" |
| 80 | + + resource = "projects/34502780858" |
| 81 | + } |
| 82 | +
|
| 83 | +Plan: 3 to add, 0 to change, 0 to destroy. |
| 84 | +``` |
| 85 | + |
| 86 | +For each resource, you will need to import it into the Terraform config: |
| 87 | + |
| 88 | +``` |
| 89 | +terraform import 'module.bridge.google_access_context_manager_service_perimeter_resource.service_perimeter_resource["one"]' 'accessPolicies/209696272439/servicePerimeters/bridge_perimeter_1/projects/34502780858' |
| 90 | +terraform import 'module.bridge.google_access_context_manager_service_perimeter_resource.service_perimeter_resource["two"]' 'accessPolicies/209696272439/servicePerimeters/bridge_perimeter_1/projects/843696391937' |
| 91 | +terraform import 'module.regular_service_perimeter_1.google_access_context_manager_service_perimeter_resource.service_perimeter_resource["34502780858"]' 'accessPolicies/209696272439/servicePerimeters/regular_perimeter_1/projects/34502780858' |
| 92 | +``` |
0 commit comments