Skip to content

Commit

Permalink
small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
simonebruzzechesse committed Dec 15, 2023
1 parent c866114 commit 1b8eed3
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 51 deletions.
6 changes: 3 additions & 3 deletions blueprints/factories/project-factory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ shared_vpc_service_config:
- cloudrun
"roles/container.hostServiceAgentUser":
- container-engine
service_identity_subnets_iam:
service_identity_subnet_iam:
europe-west1/prod-default-ew1:
- cloudservices
- container-engine
subnets_iam:
network_subnet_users:
europe-west1/prod-default-ew1:
- group:[email protected]

Expand All @@ -134,7 +134,7 @@ services:
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [factory_data_path](variables.tf#L91) | Path to folder with YAML project description data files. | <code>string</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; host_project_iam &#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_subnets_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; subnets_iam &#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_project_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_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_project_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_project_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_project_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> |

Expand Down
10 changes: 5 additions & 5 deletions blueprints/factories/project-factory/factory.tf
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ locals {
try(v.shared_vpc_service_config, null) != null
? merge(
{
host_project_iam = []
service_identity_iam = {}
service_identity_subnets_iam = {}
service_iam_grants = []
subnets_iam = {}
network_users = []
service_identity_iam = {}
service_identity_subnet_iam = {}
service_iam_grants = []
network_subnet_users = {}
},
v.shared_vpc_service_config
)
Expand Down
12 changes: 6 additions & 6 deletions blueprints/factories/project-factory/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ variable "data_defaults" {
service_perimeter_standard = optional(string)
services = optional(list(string), [])
shared_vpc_service_config = optional(object({
host_project = string
host_project_iam = optional(list(string), [])
service_identity_iam = optional(map(list(string)), {})
service_identity_subnets_iam = optional(map(list(string)), {})
service_iam_grants = optional(list(string), [])
subnets_iam = optional(map(list(string)), {})
host_project = string
network_users = optional(list(string), [])
service_identity_iam = optional(map(list(string)), {})
service_identity_subnet_iam = optional(map(list(string)), {})
service_iam_grants = optional(list(string), [])
network_subnet_users = optional(map(list(string)), {})
}), { host_project = null })
tag_bindings = optional(map(string), {})
# non-project resources
Expand Down
28 changes: 13 additions & 15 deletions modules/project/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ The module allows managing Shared VPC status for both hosts and service projects
Project service association for VPC host projects can be

- authoritatively managed in the host project by enabling Shared VPC and specifying the set of service projects, or
- additively managed in service projects by by enabling Shared VPC in the host project and then "attaching" each service project independently
- additively managed in service projects by enabling Shared VPC in the host project and then "attaching" each service project independently

IAM bindings in the host project for API service identities can be managed from service projects in two different ways:

Expand Down Expand Up @@ -317,9 +317,9 @@ module "service-project" {
# tftest modules=2 resources=9 inventory=shared-vpc-auto-grants.yaml e2e
```

The 'networkUser' role for identities other than API services (e.g. users, groups or service accounts) can be managed via the `host_project_iam` attribute, by specifying the list of identities.
The `compute.networkUser` role for identities other than API services (e.g. users, groups or service accounts) can be managed via the `network_users` attribute, by specifying the list of identities.

Note that this configuration grants the 'networkUser' role at project level which results in the identity being able to configure resources on all the VPCs and subnets belonging to the host project without further restrictions. It is possible, or better recommended, to restrict which subnets can be used on the newly created project using an Org Policy. The latter applied at project level can restrict access to a list of subnets from the host project. For more information on the Org Policy configuration check the corresponding [Organization Policy section](#organization-policies). The following example details this configuration.
Note that this configuration grants the role at project level which results in the identities being able to configure resources on all the VPCs and subnets belonging to the host project. The most reliable way to restrict which subnets can be used on the newly created project is via the `compute.restrictSharedVpcSubnetworks` organization policy. For more information on the Org Policy configuration check the corresponding [Organization Policy section](#organization-policies). The following example details this configuration.

```hcl
module "host-project" {
Expand Down Expand Up @@ -352,18 +352,16 @@ module "service-project" {
"container.googleapis.com",
]
shared_vpc_service_config = {
host_project = module.host-project.project_id
host_project_iam = ["group:[email protected]"]
host_project = module.host-project.project_id
network_users = ["group:[email protected]"]
# reuse the list of services from the module's outputs
service_iam_grants = module.service-project.services
}
}
# tftest modules=2 resources=11 inventory=shared-vpc-host-project-iam.yaml e2e
```

In specific cases it might make sense to selectively grant the `compute.networkUser` role for all kind of identities at the subnet level, although you can restrict access via org policies this is also supported by this module.

In this example, Compute service identity and `[email protected]` Google Group will be granted compute.networkUser in the `gce` subnet defined in `europe-west1` region via the `service_identity_subnets_iam` and `subnets_iam` attributes.
In specific cases it might make sense to selectively grant the `compute.networkUser` role for service identities at the subnet level, and while that is best done via org policies it's also supported by this module. In this example, Compute service identity and `[email protected]` Google Group will be granted compute.networkUser in the `gce` subnet defined in `europe-west1` region via the `service_identity_subnet_iam` and `network_subnet_users` attributes.

```hcl
module "host-project" {
Expand All @@ -388,10 +386,10 @@ module "service-project" {
]
shared_vpc_service_config = {
host_project = module.host-project.project_id
service_identity_subnets_iam = {
service_identity_subnet_iam = {
"europe-west1/gce" = ["compute"]
}
subnets_iam = {
network_subnet_users = {
"europe-west1/gce" = ["group:[email protected]"]
}
}
Expand Down Expand Up @@ -439,10 +437,10 @@ module "service-project" {
service_identity_iam = {
"roles/container.hostServiceAgentUser" = ["container-engine"]
}
service_identity_subnets_iam = {
service_identity_subnet_iam = {
"europe-west1/gce" = ["cloudservices", "container-engine"]
}
subnets_iam = {
network_subnet_users = {
"europe-west1/gce" = ["group:[email protected]"]
}
}
Expand Down Expand Up @@ -1027,9 +1025,9 @@ module "bucket" {
| [service_perimeter_standard](variables.tf#L280) | 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#L286) | Service APIs to enable. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [shared_vpc_host_config](variables.tf#L292) | 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#L301) | 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; host_project_iam &#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_subnets_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; subnets_iam &#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#L328) | Allows the underlying resources to be destroyed without destroying the project itself. | <code>bool</code> | | <code>false</code> |
| [tag_bindings](variables.tf#L334) | Tag bindings for this project, in key => tag value id format. | <code>map&#40;string&#41;</code> | | <code>null</code> |
| [shared_vpc_service_config](variables.tf#L301) | 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#L329) | Allows the underlying resources to be destroyed without destroying the project itself. | <code>bool</code> | | <code>false</code> |
| [tag_bindings](variables.tf#L335) | Tag bindings for this project, in key => tag value id format. | <code>map&#40;string&#41;</code> | | <code>null</code> |

## Outputs

Expand Down
26 changes: 13 additions & 13 deletions modules/project/shared-vpc.tf
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,25 @@ locals {
"${b.role}:${b.service}" => b
}
# normalize the service identity subnet IAM bindings
_svpc_service_subnets_iam = flatten([
for subnet, services in local._svpc.service_identity_subnets_iam : [
_svpc_service_subnet_iam = flatten([
for subnet, services in local._svpc.service_identity_subnet_iam : [
for service in services : [{
region = split("/", subnet)[0]
subnet = split("/", subnet)[1]
service = service
}]
]
])
svpc_service_subnets_iam = {
for v in local._svpc_service_subnets_iam :
svpc_service_subnet_iam = {
for v in local._svpc_service_subnet_iam :
"${v.region}:${v.subnet}:${v.service}" => v
}
# normalize the service identity subnet IAM bindings
_svpc_subnets_iam = (
local._svpc.subnets_iam == null || local._svpc.host_project == null
# normalize the network user subnet IAM binding
_svpc_network_user_subnet_iam = (
local._svpc.network_subnet_users == null || local._svpc.host_project == null
? []
: flatten([
for subnet, members in local._svpc.subnets_iam : [
for subnet, members in local._svpc.network_subnet_users : [
for member in members : {
region = split("/", subnet)[0]
subnet = split("/", subnet)[1]
Expand All @@ -82,8 +82,8 @@ locals {
]
])
)
svpc_subnets_iam = {
for v in local._svpc_subnets_iam :
svpc_network_user_subnet_iam = {
for v in local._svpc_network_user_subnet_iam :
"${v.region}:${v.subnet}:${v.member}" => v
}
}
Expand Down Expand Up @@ -130,15 +130,15 @@ resource "google_project_iam_member" "shared_vpc_host_robots" {
}

resource "google_project_iam_member" "shared_vpc_host_iam" {
for_each = toset(var.shared_vpc_service_config.host_project_iam)
for_each = toset(var.shared_vpc_service_config.network_users)
project = var.shared_vpc_service_config.host_project
role = "roles/compute.networkUser"
member = each.value
depends_on = []
}

resource "google_compute_subnetwork_iam_member" "shared_vpc_host_robots" {
for_each = local.svpc_service_subnets_iam
for_each = local.svpc_service_subnet_iam
project = var.shared_vpc_service_config.host_project
region = each.value.region
subnetwork = each.value.subnet
Expand All @@ -159,7 +159,7 @@ resource "google_compute_subnetwork_iam_member" "shared_vpc_host_robots" {
}

resource "google_compute_subnetwork_iam_member" "shared_vpc_host_subnets_iam" {
for_each = local.svpc_subnets_iam
for_each = local.svpc_network_user_subnet_iam
project = var.shared_vpc_service_config.host_project
region = each.value.region
subnetwork = each.value.subnet
Expand Down
Loading

0 comments on commit 1b8eed3

Please sign in to comment.