From 88d56442e0891e9617d9fdfcdfdbfd809cc32563 Mon Sep 17 00:00:00 2001 From: Charles Leon Date: Thu, 14 Mar 2024 15:21:16 -0700 Subject: [PATCH] Access Context Manager - make ingress and egress rules immutable (#10147) * Access Context Manager - make ingress and egress rules immutable * Move immutable state to top level resource --------- Co-authored-by: Charles Leon --- .../ServicePerimeterEgressPolicy.yaml | 10 ++++- .../ServicePerimeterIngressPolicy.yaml | 10 ++++- ...ger_service_perimeter_egress_policy.tf.erb | 36 +++++++++++++++++ ...er_service_perimeter_ingress_policy.tf.erb | 39 +++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 mmv1/templates/terraform/examples/access_context_manager_service_perimeter_egress_policy.tf.erb create mode 100644 mmv1/templates/terraform/examples/access_context_manager_service_perimeter_ingress_policy.tf.erb diff --git a/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml b/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml index 738ceefd98bd..5c26b6c85bc8 100644 --- a/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml +++ b/mmv1/products/accesscontextmanager/ServicePerimeterEgressPolicy.yaml @@ -18,6 +18,7 @@ self_link: '{{perimeter}}' create_verb: :PATCH delete_verb: :PATCH update_mask: true +immutable: true identity: - egressFrom - egressTo @@ -37,6 +38,14 @@ description: | within the ServicePerimeter to access a defined set of projects outside the perimeter in certain contexts (e.g. to read data from a Cloud Storage bucket or query against a BigQuery dataset). + + ~> **Note:** By default, updates to this resource will remove the EgressPolicy from the + from the perimeter and add it back in a non-atomic manner. To ensure that the new EgressPolicy + is added before the old one is removed, add a `lifecycle` block with `create_before_destroy = true` to this resource. +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'access_context_manager_service_perimeter_egress_policy' + skip_test: true autogen_async: true exclude_tgc: true # Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter @@ -54,7 +63,6 @@ parameters: description: | The name of the Service Perimeter to add this resource to. required: true - immutable: true url_param_only: true properties: - !ruby/object:Api::Type::NestedObject diff --git a/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml b/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml index 195b87db9bfa..c17f8a3e0471 100644 --- a/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml +++ b/mmv1/products/accesscontextmanager/ServicePerimeterIngressPolicy.yaml @@ -18,6 +18,7 @@ self_link: '{{perimeter}}' create_verb: :PATCH delete_verb: :PATCH update_mask: true +immutable: true identity: - ingressFrom - ingressTo @@ -38,6 +39,14 @@ description: | For access from private networks, using the project of the hosting network is required. Individual ingress policies can be limited by restricting which services and/ or actions they match using the ingressTo field. + + ~> **Note:** By default, updates to this resource will remove the IngressPolicy from the + from the perimeter and add it back in a non-atomic manner. To ensure that the new IngressPolicy + is added before the old one is removed, add a `lifecycle` block with `create_before_destroy = true` to this resource. +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'access_context_manager_service_perimeter_ingress_policy' + skip_test: true autogen_async: true exclude_tgc: true # Skipping the sweeper due to the non-standard base_url and because this is fine-grained under ServicePerimeter @@ -55,7 +64,6 @@ parameters: description: | The name of the Service Perimeter to add this resource to. required: true - immutable: true url_param_only: true properties: - !ruby/object:Api::Type::NestedObject diff --git a/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_egress_policy.tf.erb b/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_egress_policy.tf.erb new file mode 100644 index 000000000000..7ea39e59976f --- /dev/null +++ b/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_egress_policy.tf.erb @@ -0,0 +1,36 @@ +resource "google_access_context_manager_service_perimeter" "storage-perimeter" { + parent = "accesspolicies/${google_access_context_manager_access_policy.access-policy.name}" + name = "accesspolicies/${google_access_context_manager_access_policy.access-policy.name}/serviceperimeters/storage-perimeter" + title = "Storage Perimeter" + status { + restricted_services = ["storage.googleapis.com"] + } + lifecycle { + ignore_changes = [status[0].resources] + } +} + +resource "google_access_context_manager_service_perimeter_egress_policy" "egress_policy" { + perimeter = "${google_access_context_manager_service_perimeter.storage-perimeter.name}" + egress_from { + identity_type = "ANY_IDENTITY" + } + egress_to { + resources = ["*"] + operations { + service_name = "bigquery.googleapis.com" + method_selectors { + method = "*" + } + } + } + lifecycle { + create_before_destroy = true + } +} + + +resource "google_access_context_manager_access_policy" "access-policy" { + parent = "organizations/123456789" + title = "Storage Policy" +} diff --git a/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_ingress_policy.tf.erb b/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_ingress_policy.tf.erb new file mode 100644 index 000000000000..b54c62bcc207 --- /dev/null +++ b/mmv1/templates/terraform/examples/access_context_manager_service_perimeter_ingress_policy.tf.erb @@ -0,0 +1,39 @@ +resource "google_access_context_manager_service_perimeter" "storage-perimeter" { + parent = "accesspolicies/${google_access_context_manager_access_policy.access-policy.name}" + name = "accesspolicies/${google_access_context_manager_access_policy.access-policy.name}/serviceperimeters/storage-perimeter" + title = "Storage Perimeter" + status { + restricted_services = ["storage.googleapis.com"] + } + lifecycle { + ignore_changes = [status[0].resources] + } +} + +resource "google_access_context_manager_service_perimeter_ingress_policy" "ingress_policy" { + perimeter = "${google_access_context_manager_service_perimeter.storage-perimeter.name}" + ingress_from { + identity_type = "any_identity" + sources { + access_level = "*" + } + } + ingress_to { + resources = ["*"] + operations { + service_name = "bigquery.googleapis.com" + method_selectors { + method = "*" + } + } + } + lifecycle { + create_before_destroy = true + } +} + + +resource "google_access_context_manager_access_policy" "access-policy" { + parent = "organizations/123456789" + title = "Storage Policy" +}