Refactor vpc-sc support in project module, add support for dry run (#2229)

This commit is contained in:
Ludovico Magnocavallo 2024-04-22 10:28:01 +03:00 committed by GitHub
parent 0454fd681d
commit 309792c559
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 162 additions and 65 deletions

View File

@ -390,10 +390,10 @@ update_rules:
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [factories_config](variables.tf#L91) | Path to folder with YAML resource description data files. | <code title="object&#40;&#123;&#10; hierarchy &#61; optional&#40;object&#40;&#123;&#10; folders_data_path &#61; string&#10; parent_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; &#125;&#41;&#41;&#10; projects_data_path &#61; optional&#40;string&#41;&#10; budgets &#61; optional&#40;object&#40;&#123;&#10; billing_account &#61; string&#10; budgets_data_path &#61; string&#10; notification_channels &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [data_defaults](variables.tf#L17) | Optional default values used when corresponding project data from files are missing. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_perimeter_bridges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_perimeter_standard &#61; optional&#40;string&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; shared_vpc_service_config &#61; optional&#40;object&#40;&#123;&#10; host_project &#61; string&#10; network_users &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_identity_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_identity_subnet_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_iam_grants &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; network_subnet_users &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; &#125;&#41;, &#123; host_project &#61; null &#125;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_self_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [data_merges](variables.tf#L49) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | <code title="object&#40;&#123;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_perimeter_bridges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_self_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [data_overrides](variables.tf#L69) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; service_perimeter_bridges &#61; optional&#40;list&#40;string&#41;&#41;&#10; service_perimeter_standard &#61; optional&#40;string&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_self_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L96) | Path to folder with YAML resource description data files. | <code title="object&#40;&#123;&#10; hierarchy &#61; optional&#40;object&#40;&#123;&#10; folders_data_path &#61; string&#10; parent_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; &#125;&#41;&#41;&#10; projects_data_path &#61; optional&#40;string&#41;&#10; budgets &#61; optional&#40;object&#40;&#123;&#10; billing_account &#61; string&#10; budgets_data_path &#61; string&#10; notification_channels &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [data_defaults](variables.tf#L17) | Optional default values used when corresponding project data from files are missing. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; shared_vpc_service_config &#61; optional&#40;object&#40;&#123;&#10; host_project &#61; string&#10; network_users &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_identity_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_identity_subnet_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_iam_grants &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; network_subnet_users &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; &#125;&#41;, &#123; host_project &#61; null &#125;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_self_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; vpc_sc &#61; optional&#40;object&#40;&#123;&#10; perimeter_name &#61; string&#10; perimeter_bridges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; is_dry_run &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [data_merges](variables.tf#L52) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | <code title="object&#40;&#123;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_self_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [data_overrides](variables.tf#L71) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_self_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;&#41;&#10; vpc_sc &#61; optional&#40;object&#40;&#123;&#10; perimeter_name &#61; string&#10; perimeter_bridges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; is_dry_run &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
## Outputs

View File

@ -82,16 +82,6 @@ locals {
try(v.service_encryption_key_ids, null),
var.data_defaults.service_encryption_key_ids
)
service_perimeter_bridges = coalesce(
var.data_overrides.service_perimeter_bridges,
try(v.service_perimeter_bridges, null),
var.data_defaults.service_perimeter_bridges
)
service_perimeter_standard = try(coalesce(
var.data_overrides.service_perimeter_standard,
try(v.service_perimeter_standard, null),
var.data_defaults.service_perimeter_standard
), null)
services = coalesce(
var.data_overrides.services,
try(v.services, null),
@ -116,6 +106,11 @@ locals {
try(v.tag_bindings, null),
var.data_defaults.tag_bindings
)
vpc_sc = (
var.data_overrides.vpc_sc != null
? var.data_overrides.vpc_sc
: try(v.vpc_sc, var.data_defaults.vpc_sc, null)
)
# non-project resources
service_accounts = try(v.service_accounts, {})
})

View File

@ -77,11 +77,6 @@ module "projects" {
each.value.service_encryption_key_ids,
var.data_merges.service_encryption_key_ids
)
service_perimeter_bridges = distinct(concat(
each.value.service_perimeter_bridges,
var.data_merges.service_perimeter_bridges
))
service_perimeter_standard = each.value.service_perimeter_standard
services = distinct(concat(
each.value.services,
var.data_merges.services
@ -91,6 +86,7 @@ module "projects" {
each.value.tag_bindings,
var.data_merges.tag_bindings
)
vpc_sc = each.value.vpc_sc
}
module "service-accounts" {

View File

@ -24,8 +24,6 @@ variable "data_defaults" {
parent = optional(string)
prefix = optional(string)
service_encryption_key_ids = optional(map(list(string)), {})
service_perimeter_bridges = optional(list(string), [])
service_perimeter_standard = optional(string)
services = optional(list(string), [])
shared_vpc_service_config = optional(object({
host_project = string
@ -41,6 +39,11 @@ variable "data_defaults" {
display_name = optional(string, "Terraform-managed.")
iam_self_roles = optional(list(string))
})), {})
vpc_sc = optional(object({
perimeter_name = string
perimeter_bridges = optional(list(string), [])
is_dry_run = optional(bool, false)
}))
})
nullable = false
default = {}
@ -53,7 +56,6 @@ variable "data_merges" {
labels = optional(map(string), {})
metric_scopes = optional(list(string), [])
service_encryption_key_ids = optional(map(list(string)), {})
service_perimeter_bridges = optional(list(string), [])
services = optional(list(string), [])
tag_bindings = optional(map(string), {})
# non-project resources
@ -74,8 +76,6 @@ variable "data_overrides" {
parent = optional(string)
prefix = optional(string)
service_encryption_key_ids = optional(map(list(string)))
service_perimeter_bridges = optional(list(string))
service_perimeter_standard = optional(string)
tag_bindings = optional(map(string))
services = optional(list(string))
# non-project resources
@ -83,6 +83,11 @@ variable "data_overrides" {
display_name = optional(string, "Terraform-managed.")
iam_self_roles = optional(list(string))
})))
vpc_sc = optional(object({
perimeter_name = string
perimeter_bridges = optional(list(string), [])
is_dry_run = optional(bool, false)
}))
})
nullable = false
default = {}

View File

@ -24,6 +24,7 @@ This module implements the creation and management of one GCP project including
- [Custom Roles Factory](#custom-roles-factory)
- [Quotas](#quotas)
- [Quotas factory](#quotas-factory)
- [VPC Service Controls](#vpc-service-controls)
- [Outputs](#outputs)
- [Managing project related configuration without creating it](#managing-project-related-configuration-without-creating-it)
- [Files](#files)
@ -802,6 +803,7 @@ includedPermissions:
## Quotas
Project and regional quotas can be managed via the `quotas` variable. Keep in mind, that metrics returned by `gcloud compute regions describe` do not match `quota_id`s. To get a list of quotas in the project use the API call, for example to get quotas for `compute.googleapis.com` use:
```bash
curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
@ -874,6 +876,52 @@ cpus-ew8:
region: europe-west8
```
## VPC Service Controls
This module also allows managing project membership in VPC Service Controls perimeters. When using this functionality care should be taken so that perimeter management (e.g. via the `vpc-sc` module) does not try reconciling resources, to avoid permadiffs and related violations.
```hcl
module "project" {
source = "./fabric/modules/project"
billing_account = var.billing_account_id
name = "project"
parent = var.folder_id
prefix = var.prefix
services = [
"container.googleapis.com",
"stackdriver.googleapis.com"
]
vpc_sc = {
perimeter_name = "accessPolicies/1234567890/servicePerimeters/default"
}
}
# tftest modules=1 resources=4 inventory=vpc-sc.yaml
```
Perimeter bridges and dry run configuration are also supported.
```hcl
module "project" {
source = "./fabric/modules/project"
billing_account = var.billing_account_id
name = "project"
parent = var.folder_id
prefix = var.prefix
services = [
"container.googleapis.com",
"stackdriver.googleapis.com"
]
vpc_sc = {
perimeter_name = "accessPolicies/1234567890/servicePerimeters/default"
perimeter_bridges = [
"accessPolicies/1234567890/servicePerimeters/b1",
"accessPolicies/1234567890/servicePerimeters/b2",
]
is_dry_run = true
}
}
# tftest modules=1 resources=6
```
## Outputs
@ -1131,7 +1179,7 @@ module "bucket" {
| [variables-tags.tf](./variables-tags.tf) | None | |
| [variables.tf](./variables.tf) | Module variables. | |
| [versions.tf](./versions.tf) | Version pins. | |
| [vpc-sc.tf](./vpc-sc.tf) | VPC-SC project-level perimeter configuration. | <code>google_access_context_manager_service_perimeter_resource</code> |
| [vpc-sc.tf](./vpc-sc.tf) | VPC-SC project-level perimeter configuration. | <code>google_access_context_manager_service_perimeter_dry_run_resource</code> · <code>google_access_context_manager_service_perimeter_resource</code> |
## Variables
@ -1164,14 +1212,13 @@ module "bucket" {
| [quotas](variables-quotas.tf#L17) | Service quota configuration. | <code title="map&#40;object&#40;&#123;&#10; service &#61; string&#10; quota_id &#61; string&#10; preferred_value &#61; number&#10; dimensions &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; justification &#61; optional&#40;string&#41;&#10; contact_email &#61; optional&#40;string&#41;&#10; annotations &#61; optional&#40;map&#40;string&#41;&#41;&#10; ignore_safety_checks &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [service_config](variables.tf#L211) | Configure service API activation. | <code title="object&#40;&#123;&#10; disable_on_destroy &#61; bool&#10; disable_dependent_services &#61; bool&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; disable_on_destroy &#61; false&#10; disable_dependent_services &#61; false&#10;&#125;">&#123;&#8230;&#125;</code> |
| [service_encryption_key_ids](variables.tf#L223) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [service_perimeter_bridges](variables.tf#L230) | Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format. | <code>list&#40;string&#41;</code> | | <code>null</code> |
| [service_perimeter_standard](variables.tf#L237) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | <code>string</code> | | <code>null</code> |
| [services](variables.tf#L243) | Service APIs to enable. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [shared_vpc_host_config](variables.tf#L249) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | <code title="object&#40;&#123;&#10; enabled &#61; bool&#10; service_projects &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [shared_vpc_service_config](variables.tf#L258) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | <code title="object&#40;&#123;&#10; host_project &#61; string&#10; network_users &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_identity_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_identity_subnet_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_iam_grants &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; network_subnet_users &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; host_project &#61; null&#10;&#125;">&#123;&#8230;&#125;</code> |
| [skip_delete](variables.tf#L286) | Allows the underlying resources to be destroyed without destroying the project itself. | <code>bool</code> | | <code>false</code> |
| [services](variables.tf#L229) | Service APIs to enable. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [shared_vpc_host_config](variables.tf#L235) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | <code title="object&#40;&#123;&#10; enabled &#61; bool&#10; service_projects &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [shared_vpc_service_config](variables.tf#L244) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | <code title="object&#40;&#123;&#10; host_project &#61; string&#10; network_users &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_identity_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_identity_subnet_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_iam_grants &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; network_subnet_users &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; host_project &#61; null&#10;&#125;">&#123;&#8230;&#125;</code> |
| [skip_delete](variables.tf#L272) | Allows the underlying resources to be destroyed without destroying the project itself. | <code>bool</code> | | <code>false</code> |
| [tag_bindings](variables-tags.tf#L45) | Tag bindings for this project, in key => tag value id format. | <code>map&#40;string&#41;</code> | | <code>null</code> |
| [tags](variables-tags.tf#L51) | Tags by key name. If `id` is provided, key or value creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | <code title="map&#40;object&#40;&#123;&#10; description &#61; optional&#40;string, &#34;Managed by the Terraform project module.&#34;&#41;&#10; iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; id &#61; optional&#40;string&#41;&#10; values &#61; optional&#40;map&#40;object&#40;&#123;&#10; description &#61; optional&#40;string, &#34;Managed by the Terraform project module.&#34;&#41;&#10; iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; id &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [vpc_sc](variables.tf#L278) | VPC-SC configuration for the project, use when `ignore_changes` for resources is set in the VPC-SC module. | <code title="object&#40;&#123;&#10; perimeter_name &#61; string&#10; perimeter_bridges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; is_dry_run &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
## Outputs

View File

@ -226,20 +226,6 @@ variable "service_encryption_key_ids" {
default = {}
}
# accessPolicies/ACCESS_POLICY_NAME/servicePerimeters/PERIMETER_NAME
variable "service_perimeter_bridges" {
description = "Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format."
type = list(string)
default = null
}
# accessPolicies/ACCESS_POLICY_NAME/servicePerimeters/PERIMETER_NAME
variable "service_perimeter_standard" {
description = "Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format."
type = string
default = null
}
variable "services" {
description = "Service APIs to enable."
type = list(string)
@ -288,3 +274,13 @@ variable "skip_delete" {
type = bool
default = false
}
variable "vpc_sc" {
description = "VPC-SC configuration for the project, use when `ignore_changes` for resources is set in the VPC-SC module."
type = object({
perimeter_name = string
perimeter_bridges = optional(list(string), [])
is_dry_run = optional(bool, false)
})
default = null
}

View File

@ -16,30 +16,28 @@
# tfdoc:file:description VPC-SC project-level perimeter configuration.
moved {
from = google_access_context_manager_service_perimeter_resource.service-perimeter-resource-standard
to = google_access_context_manager_service_perimeter_resource.standard
locals {
vpc_sc_perimeters = compact(concat(
[try(var.vpc_sc.perimeter_name, null)],
try(var.vpc_sc.perimeter_bridges, [])
))
vpc_sc_dry_run = try(var.vpc_sc.is_dry_run, false) == true
}
resource "google_access_context_manager_service_perimeter_resource" "standard" {
count = var.service_perimeter_standard != null ? 1 : 0
# this needs an additional lifecycle block in the vpc module on the
# google_access_context_manager_service_perimeter resource
perimeter_name = var.service_perimeter_standard
resource = "projects/${local.project.number}"
}
# use only if the vpc-sc module has a lifecycle block to ignore resources
moved {
from = google_access_context_manager_service_perimeter_resource.service-perimeter-resource-bridges
to = google_access_context_manager_service_perimeter_resource.bridge
}
resource "google_access_context_manager_service_perimeter_resource" "bridge" {
resource "google_access_context_manager_service_perimeter_resource" "default" {
for_each = toset(
var.service_perimeter_bridges != null ? var.service_perimeter_bridges : []
local.vpc_sc_dry_run ? [] : local.vpc_sc_perimeters
)
# this needs an additional lifecycle block in the vpc module on the
# google_access_context_manager_service_perimeter resource
perimeter_name = each.value
perimeter_name = each.key
resource = "projects/${local.project.number}"
}
resource "google_access_context_manager_service_perimeter_dry_run_resource" "default" {
for_each = toset(
local.vpc_sc_dry_run ? local.vpc_sc_perimeters : []
)
perimeter_name = each.key
resource = "projects/${local.project.number}"
}

View File

@ -0,0 +1,33 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
values:
? module.project.google_access_context_manager_service_perimeter_dry_run_resource.default["accessPolicies/1234567890/servicePerimeters/b1"]
: perimeter_name: accessPolicies/1234567890/servicePerimeters/b1
timeouts: null
? module.project.google_access_context_manager_service_perimeter_dry_run_resource.default["accessPolicies/1234567890/servicePerimeters/b2"]
: perimeter_name: accessPolicies/1234567890/servicePerimeters/b2
timeouts: null
? module.project.google_access_context_manager_service_perimeter_dry_run_resource.default["accessPolicies/1234567890/servicePerimeters/default"]
: perimeter_name: accessPolicies/1234567890/servicePerimeters/default
timeouts: null
counts:
google_access_context_manager_service_perimeter_dry_run_resource: 3
google_project: 1
google_project_service: 2
modules: 1
resources: 6
outputs: {}

View File

@ -0,0 +1,27 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
values:
? module.project.google_access_context_manager_service_perimeter_resource.default["accessPolicies/1234567890/servicePerimeters/default"]
: perimeter_name: accessPolicies/1234567890/servicePerimeters/default
timeouts: null
counts:
google_access_context_manager_service_perimeter_resource: 1
google_project: 1
google_project_service: 2
modules: 1
resources: 4
outputs: {}