Project factory fixes

- Add GKE roles in the host project
- Use SA names from project module
- Add a few outputs
- Add prefix for project ids
This commit is contained in:
Julio Castillo 2022-02-07 11:33:03 +01:00 committed by Julio Castillo
parent 40142572f8
commit 82b181f34e
4 changed files with 66 additions and 53 deletions

View File

@ -218,26 +218,28 @@ vpc:
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | |
| [defaults](variables.tf#L35) | Project factory default values. | <code title="object&#40;&#123;&#10; billing_account_id &#61; string&#10; billing_alert &#61; object&#40;&#123;&#10; amount &#61; number&#10; thresholds &#61; object&#40;&#123;&#10; current &#61; list&#40;number&#41;&#10; forecasted &#61; list&#40;number&#41;&#10; &#125;&#41;&#10; credit_treatment &#61; string&#10; &#125;&#41;&#10; environment_dns_zone &#61; string&#10; essential_contacts &#61; list&#40;string&#41;&#10; labels &#61; map&#40;string&#41;&#10; notification_channels &#61; list&#40;string&#41;&#10; shared_vpc_self_link &#61; string&#10; vpc_host_project &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [folder_id](variables.tf#L68) | Folder ID for the folder where the project will be created. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L111) | Project id. | <code>string</code> | ✓ | |
| [folder_id](variables.tf#L69) | Folder ID for the folder where the project will be created. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L119) | Project id. | <code>string</code> | ✓ | |
| [billing_alert](variables.tf#L22) | Billing alert configuration. | <code title="object&#40;&#123;&#10; amount &#61; number&#10; thresholds &#61; object&#40;&#123;&#10; current &#61; list&#40;number&#41;&#10; forecasted &#61; list&#40;number&#41;&#10; &#125;&#41;&#10; credit_treatment &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [dns_zones](variables.tf#L56) | DNS private zones to create as child of var.defaults.environment_dns_zone. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [essential_contacts](variables.tf#L62) | Email contacts to be used for billing and GCP notifications. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [group_iam](variables.tf#L73) | Custom IAM settings in group => [role] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam](variables.tf#L79) | Custom IAM settings in role => [principal] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [kms_service_agents](variables.tf#L85) | KMS IAM configuration in as service => [key]. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [labels](variables.tf#L91) | Labels to be assigned at project level. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [org_policies](variables.tf#L97) | Org-policy overrides at project level. | <code title="object&#40;&#123;&#10; policy_boolean &#61; map&#40;bool&#41;&#10; policy_list &#61; map&#40;object&#40;&#123;&#10; inherit_from_parent &#61; bool&#10; suggested_value &#61; string&#10; status &#61; bool&#10; values &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [service_accounts](variables.tf#L116) | Service accounts to be created, and roles to assign them. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [services](variables.tf#L122) | Services to be enabled for the project. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [services_iam](variables.tf#L128) | Custom IAM settings for robot ServiceAccounts in service => [role] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [vpc](variables.tf#L134) | VPC configuration for the project. | <code title="object&#40;&#123;&#10; host_project &#61; string&#10; gke_setup &#61; object&#40;&#123;&#10; enable_security_admin &#61; bool&#10; enable_host_service_agent &#61; bool&#10; &#125;&#41;&#10; subnets_iam &#61; map&#40;list&#40;string&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [defaults](variables.tf#L35) | Project factory default values. | <code title="object&#40;&#123;&#10; billing_account_id &#61; string&#10; billing_alert &#61; object&#40;&#123;&#10; amount &#61; number&#10; thresholds &#61; object&#40;&#123;&#10; current &#61; list&#40;number&#41;&#10; forecasted &#61; list&#40;number&#41;&#10; &#125;&#41;&#10; credit_treatment &#61; string&#10; &#125;&#41;&#10; environment_dns_zone &#61; string&#10; essential_contacts &#61; list&#40;string&#41;&#10; labels &#61; map&#40;string&#41;&#10; notification_channels &#61; list&#40;string&#41;&#10; shared_vpc_self_link &#61; string&#10; vpc_host_project &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [dns_zones](variables.tf#L57) | DNS private zones to create as child of var.defaults.environment_dns_zone. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [essential_contacts](variables.tf#L63) | Email contacts to be used for billing and GCP notifications. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [group_iam](variables.tf#L74) | Custom IAM settings in group => [role] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam](variables.tf#L80) | Custom IAM settings in role => [principal] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [kms_service_agents](variables.tf#L86) | KMS IAM configuration in as service => [key]. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [labels](variables.tf#L92) | Labels to be assigned at project level. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [org_policies](variables.tf#L98) | Org-policy overrides at project level. | <code title="object&#40;&#123;&#10; policy_boolean &#61; map&#40;bool&#41;&#10; policy_list &#61; map&#40;object&#40;&#123;&#10; inherit_from_parent &#61; bool&#10; suggested_value &#61; string&#10; status &#61; bool&#10; values &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [prefix](variables.tf#L112) | Prefix used for the project id. | <code>string</code> | | <code>null</code> |
| [service_accounts](variables.tf#L124) | Service accounts to be created, and roles to assign them. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [services](variables.tf#L130) | Services to be enabled for the project. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [services_iam](variables.tf#L136) | Custom IAM settings for robot ServiceAccounts in service => [role] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [vpc](variables.tf#L142) | VPC configuration for the project. | <code title="object&#40;&#123;&#10; host_project &#61; string&#10; gke_setup &#61; object&#40;&#123;&#10; enable_security_admin &#61; bool&#10; enable_host_service_agent &#61; bool&#10; &#125;&#41;&#10; subnets_iam &#61; map&#40;list&#40;string&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
## Outputs
| name | description | sensitive |
|---|---|:---:|
| [project_id](outputs.tf#L19) | Project ID. | |
| [project](outputs.tf#L19) | The project resource as return by the `project` module | |
| [project_id](outputs.tf#L30) | Project ID. | |
<!-- END TFDOC -->

View File

@ -15,15 +15,12 @@
*/
locals {
_gke_iam_hsau = try(var.vpc.gke_setup.enable_security_admin, false) ? {
"roles/container.hostServiceAgentUser" = [
"serviceAccount:${local.service_accounts_robots["container-engine"]}"
] } : {}
_gke_iam_hsau = try(var.vpc.gke_setup.enable_host_service_agent, false) ? {
"roles/container.hostServiceAgentUser" = "serviceAccount:${module.project.service_accounts.robots.container-engine}"
} : {}
_gke_iam_securityadmin = try(var.vpc.gke_setup.enable_security_admin, false) ? {
"roles/compute.securityAdmin" = [
"serviceAccount:${local.service_accounts_robots["container-engine"]}"
] } : {}
"roles/compute.securityAdmin" = "serviceAccount:${module.project.service_accounts.robots.container-engine}"
} : {}
_group_iam = {
for r in local._group_iam_roles : r => [
for k, v in var.group_iam : "group:${k}" if try(index(v, r), null) != null
@ -47,59 +44,41 @@ locals {
_services_iam_roles = distinct(flatten(values(var.services_iam)))
_services_iam = {
for r in local._services_iam_roles : r => [
for k, v in var.services_iam : "serviceAccount:${local.service_accounts_robots[k]}" if try(index(v, r), null) != null
for k, v in var.services_iam : "serviceAccount:${module.project.service_accounts.robots[k]}" if try(index(v, r), null) != null
]
}
billing_account_id = coalesce(var.billing_account_id, var.defaults.billing_account_id)
billing_alert = var.billing_alert == null ? var.defaults.billing_alert : var.billing_alert
billing_account_id = coalesce(var.billing_account_id, try(var.defaults.billing_account_id, ""))
billing_alert = var.billing_alert == null ? try(var.defaults.billing_alert, null) : var.billing_alert
essential_contacts = concat(try(var.defaults.essential_contacts, []), var.essential_contacts)
host_project_bindings = merge(
local._gke_iam_hsau,
local._gke_iam_securityadmin
)
iam = {
for role in distinct(concat(
keys(var.iam),
keys(local._group_iam),
keys(local._gke_iam_hsau),
keys(local._gke_iam_securityadmin),
keys(local._service_accounts_iam),
keys(local._services_iam),
)) :
role => concat(
try(var.iam[role], []),
try(local._group_iam[role], []),
try(local._gke_iam_hsau[role], []),
try(local._gke_iam_securityadmin[role], []),
try(local._service_accounts_iam[role], []),
try(local._services_iam[role], []),
)
}
labels = merge(coalesce(var.labels, {}), coalesce(var.defaults.labels, {}))
labels = merge(coalesce(var.labels, {}), coalesce(try(var.defaults.labels, {}), {}))
network_user_service_accounts = concat(
contains(local.services, "compute.googleapis.com") ? [
"serviceAccount:${local.service_accounts_robots.compute}"
"serviceAccount:${module.project.service_accounts.robots.compute}"
] : [],
contains(local.services, "container.googleapis.com") ? [
"serviceAccount:${local.service_accounts_robots.container-engine}",
"serviceAccount:${local.service_accounts.cloud_services}"
"serviceAccount:${module.project.service_accounts.robots.container-engine}",
"serviceAccount:${module.project.service_accounts.cloud_services}"
] : [],
[])
services = distinct(concat(var.services, local._services))
service_accounts_robots = {
for service, name in local.service_accounts_robot_services :
service => "${service == "bq" ? "bq" : "service"}-${module.project.number}@${name}.iam.gserviceaccount.com"
}
service_accounts_robot_services = {
cloudasset = "gcp-sa-cloudasset"
cloudbuild = "gcp-sa-cloudbuild"
compute = "compute-system"
container-engine = "container-engine-robot"
containerregistry = "containerregistry"
dataflow = "dataflow-service-producer-prod"
dataproc = "dataproc-accounts"
gae-flex = "gae-api-prod"
gcf = "gcf-admin-robot"
pubsub = "gcp-sa-pubsub"
secretmanager = "gcp-sa-secretmanager"
storage = "gs-project-accounts"
}
services = distinct(concat(var.services, local._services))
vpc_host_project = try(var.vpc.host_project, var.defaults.vpc_host_project)
vpc_setup = var.vpc != null
}
@ -134,6 +113,7 @@ module "project" {
source = "../../../modules/project"
billing_account = local.billing_account_id
name = var.project_id
prefix = var.prefix
contacts = { for c in local.essential_contacts : c => ["ALL"] }
iam = local.iam
labels = local.labels
@ -155,6 +135,7 @@ module "service-accounts" {
project_id = module.project.project_id
}
# TODO(jccb): we should probably change this to non-authoritative bindings
resource "google_compute_subnetwork_iam_binding" "binding" {
for_each = local.vpc_setup ? coalesce(var.vpc.subnets_iam, {}) : {}
project = local.vpc_host_project
@ -163,3 +144,10 @@ resource "google_compute_subnetwork_iam_binding" "binding" {
role = "roles/compute.networkUser"
members = concat(each.value, local.network_user_service_accounts)
}
resource "google_project_iam_member" "host_project_bindings" {
for_each = local.host_project_bindings
project = local.vpc_host_project
role = each.key
member = each.value
}

View File

@ -16,7 +16,23 @@
# TODO(): proper outputs
output "project" {
description = "The project resource as return by the `project` module"
value = module.project
depends_on = [
google_compute_subnetwork_iam_binding.binding,
google_project_iam_member.host_project_bindings,
module.dns
]
}
output "project_id" {
description = "Project ID."
value = module.project.project_id
depends_on = [
google_compute_subnetwork_iam_binding.binding,
google_project_iam_member.host_project_bindings,
module.dns
]
}

View File

@ -51,6 +51,7 @@ variable "defaults" {
shared_vpc_self_link = string
vpc_host_project = string
})
default = null
}
variable "dns_zones" {
@ -108,6 +109,12 @@ variable "org_policies" {
default = null
}
variable "prefix" {
description = "Prefix used for the project id."
type = string
default = null
}
variable "project_id" {
description = "Project id."
type = string