add support for essential contacts to FAST (#2010)
This commit is contained in:
parent
853a9c23b5
commit
6d9b6403dd
|
@ -29,6 +29,9 @@ module "automation-project" {
|
|||
var.project_parent_ids.automation, "organizations/${var.organization.id}"
|
||||
)
|
||||
prefix = local.prefix
|
||||
contacts = {
|
||||
(local.groups.gcp-organization-admins) = ["ALL"]
|
||||
}
|
||||
# human (groups) IAM bindings
|
||||
group_iam = {
|
||||
(local.groups.gcp-devops) = [
|
||||
|
|
|
@ -46,6 +46,9 @@ module "billing-export-project" {
|
|||
var.project_parent_ids.billing, "organizations/${var.organization.id}"
|
||||
)
|
||||
prefix = local.prefix
|
||||
contacts = {
|
||||
(local.groups.gcp-organization-admins) = ["ALL"]
|
||||
}
|
||||
iam = {
|
||||
"roles/owner" = [module.automation-tf-bootstrap-sa.iam_email]
|
||||
"roles/viewer" = [module.automation-tf-bootstrap-r-sa.iam_email]
|
||||
|
|
|
@ -44,6 +44,9 @@ module "log-export-project" {
|
|||
)
|
||||
prefix = local.prefix
|
||||
billing_account = var.billing_account.id
|
||||
contacts = {
|
||||
(local.groups.gcp-organization-admins) = ["ALL"]
|
||||
}
|
||||
iam = {
|
||||
"roles/owner" = [module.automation-tf-bootstrap-sa.iam_email]
|
||||
"roles/viewer" = [module.automation-tf-bootstrap-r-sa.iam_email]
|
||||
|
|
|
@ -97,6 +97,7 @@ locals {
|
|||
iam_sa_bindings = {
|
||||
(module.automation-tf-bootstrap-sa.iam_email) = {
|
||||
authoritative = [
|
||||
"roles/essentialcontacts.admin",
|
||||
"roles/logging.admin",
|
||||
"roles/resourcemanager.organizationAdmin",
|
||||
"roles/resourcemanager.projectCreator",
|
||||
|
@ -115,6 +116,7 @@ locals {
|
|||
}
|
||||
(module.automation-tf-bootstrap-r-sa.iam_email) = {
|
||||
authoritative = [
|
||||
"roles/essentialcontacts.viewer",
|
||||
"roles/logging.viewer",
|
||||
"roles/resourcemanager.folderViewer",
|
||||
"roles/resourcemanager.tagViewer"
|
||||
|
|
|
@ -41,8 +41,8 @@ module "branch-dp-dev-folder" {
|
|||
(local.custom_roles.service_project_network_admin) = [
|
||||
module.branch-dp-dev-sa.0.iam_email
|
||||
]
|
||||
"roles/owner" = [module.branch-dp-dev-sa.0.iam_email]
|
||||
"roles/logging.admin" = [module.branch-dp-dev-sa.0.iam_email]
|
||||
"roles/owner" = [module.branch-dp-dev-sa.0.iam_email]
|
||||
"roles/resourcemanager.folderAdmin" = [module.branch-dp-dev-sa.0.iam_email]
|
||||
"roles/resourcemanager.projectCreator" = [module.branch-dp-dev-sa.0.iam_email]
|
||||
# read-only (plan) automation service account
|
||||
|
|
|
@ -136,6 +136,8 @@ module "branch-teams-team-dev-folder" {
|
|||
"roles/logging.admin" = local.branch_optional_sa_lists.pf-dev
|
||||
"roles/resourcemanager.folderAdmin" = local.branch_optional_sa_lists.pf-dev
|
||||
"roles/resourcemanager.projectCreator" = local.branch_optional_sa_lists.pf-dev
|
||||
"roles/resourcemanager.folderViewer" = local.branch_optional_r_sa_lists.pf-dev
|
||||
"roles/viewer" = local.branch_optional_r_sa_lists.pf-dev
|
||||
}
|
||||
tag_bindings = {
|
||||
environment = try(
|
||||
|
@ -161,6 +163,8 @@ module "branch-teams-team-prod-folder" {
|
|||
"roles/logging.admin" = local.branch_optional_sa_lists.pf-prod
|
||||
"roles/resourcemanager.folderAdmin" = local.branch_optional_sa_lists.pf-prod
|
||||
"roles/resourcemanager.projectCreator" = local.branch_optional_sa_lists.pf-prod
|
||||
"roles/resourcemanager.folderViewer" = local.branch_optional_r_sa_lists.pf-prod
|
||||
"roles/viewer" = local.branch_optional_r_sa_lists.pf-prod
|
||||
}
|
||||
tag_bindings = {
|
||||
environment = try(
|
||||
|
|
|
@ -390,18 +390,19 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L101) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L111) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L127) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [organization](variables.tf#L121) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L137) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L72) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L80) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L121) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [groups](variables.tf#L111) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | <code title="object({ gcp-network-admins = optional(string) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L131) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [peering_configs](variables-peerings.tf#L19) | Peering configurations. | <code title="object({ dev = optional(object({ export = optional(bool, true) import = optional(bool, true) public_export = optional(bool) public_import = optional(bool) }), {}) prod = optional(object({ export = optional(bool, true) import = optional(bool, true) public_export = optional(bool) public_import = optional(bool) }), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [psa_ranges](variables.tf#L138) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L157) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L169) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L183) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L148) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L167) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L179) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L193) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
# tfdoc:file:description Networking folder and hierarchical policy.
|
||||
|
||||
locals {
|
||||
groups = {
|
||||
for k, v in var.groups :
|
||||
k => can(regex(".*@.*", v)) ? v : "${v}@${var.organization.domain}"
|
||||
}
|
||||
# combine all regions from variables and subnets
|
||||
regions = distinct(concat(
|
||||
values(var.regions),
|
||||
|
@ -45,6 +49,9 @@ module "folder" {
|
|||
name = "Networking"
|
||||
folder_create = var.folder_ids.networking == null
|
||||
id = var.folder_ids.networking
|
||||
contacts = {
|
||||
(local.groups.gcp-network-admins) = ["ALL"]
|
||||
}
|
||||
firewall_policy = {
|
||||
name = "default"
|
||||
policy = module.firewall-policy-default.id
|
||||
|
|
|
@ -108,6 +108,16 @@ variable "folder_ids" {
|
|||
})
|
||||
}
|
||||
|
||||
variable "groups" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed."
|
||||
type = object({
|
||||
gcp-network-admins = optional(string)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "organization" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Organization details."
|
||||
|
|
|
@ -414,18 +414,19 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L101) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L111) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L127) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [organization](variables.tf#L121) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L137) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L72) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L80) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L121) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L138) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L157) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L169) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [groups](variables.tf#L111) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | <code title="object({ gcp-network-admins = optional(string) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L131) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L148) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L167) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L179) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_configs](variables-vpn.tf#L17) | Hub to spokes VPN configurations. | <code title="object({ dev = optional(object({ asn = optional(number, 65501) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }), {}) landing = optional(object({ asn = optional(number, 65500) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }), {}) prod = optional(object({ asn = optional(number, 65502) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [vpn_onprem_primary_config](variables.tf#L183) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_primary_config](variables.tf#L193) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
# tfdoc:file:description Networking folder and hierarchical policy.
|
||||
|
||||
locals {
|
||||
groups = {
|
||||
for k, v in var.groups :
|
||||
k => can(regex(".*@.*", v)) ? v : "${v}@${var.organization.domain}"
|
||||
}
|
||||
# combine all regions from variables and subnets
|
||||
regions = distinct(concat(
|
||||
values(var.regions),
|
||||
|
@ -45,6 +49,9 @@ module "folder" {
|
|||
name = "Networking"
|
||||
folder_create = var.folder_ids.networking == null
|
||||
id = var.folder_ids.networking
|
||||
contacts = {
|
||||
(local.groups.gcp-network-admins) = ["ALL"]
|
||||
}
|
||||
firewall_policy = {
|
||||
name = "default"
|
||||
policy = module.firewall-policy-default.id
|
||||
|
|
|
@ -108,6 +108,16 @@ variable "folder_ids" {
|
|||
})
|
||||
}
|
||||
|
||||
variable "groups" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed."
|
||||
type = object({
|
||||
gcp-network-admins = optional(string)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "organization" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Organization details."
|
||||
|
|
|
@ -459,20 +459,21 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L101) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L134) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L150) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [organization](variables.tf#L144) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L160) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L72) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L80) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [gcp_ranges](variables.tf#L111) | GCP address ranges in name => range format. | <code>map(string)</code> | | <code title="{ gcp_dev_primary = "10.68.0.0/16" gcp_dev_secondary = "10.84.0.0/16" gcp_landing_trusted_primary = "10.64.0.0/17" gcp_landing_trusted_secondary = "10.80.0.0/17" gcp_landing_untrusted_primary = "10.64.127.0/17" gcp_landing_untrusted_secondary = "10.80.127.0/17" gcp_prod_primary = "10.72.0.0/16" gcp_prod_secondary = "10.88.0.0/16" }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L126) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L144) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L161) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L180) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L192) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L206) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_secondary_config](variables.tf#L249) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [groups](variables.tf#L126) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | <code title="object({ gcp-network-admins = optional(string) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [onprem_cidr](variables.tf#L136) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L154) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L171) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L190) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L202) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L216) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_secondary_config](variables.tf#L259) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
locals {
|
||||
custom_roles = coalesce(var.custom_roles, {})
|
||||
groups = {
|
||||
for k, v in var.groups :
|
||||
k => can(regex(".*@.*", v)) ? v : "${v}@${var.organization.domain}"
|
||||
}
|
||||
# combine all regions from variables and subnets
|
||||
regions = distinct(concat(
|
||||
values(var.regions),
|
||||
|
@ -46,6 +50,9 @@ module "folder" {
|
|||
name = "Networking"
|
||||
folder_create = var.folder_ids.networking == null
|
||||
id = var.folder_ids.networking
|
||||
contacts = {
|
||||
(local.groups.gcp-network-admins) = ["ALL"]
|
||||
}
|
||||
firewall_policy = {
|
||||
name = "default"
|
||||
policy = module.firewall-policy-default.id
|
||||
|
|
|
@ -123,6 +123,16 @@ variable "gcp_ranges" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "groups" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed."
|
||||
type = object({
|
||||
gcp-network-admins = optional(string)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "onprem_cidr" {
|
||||
description = "Onprem addresses in name => range format."
|
||||
type = map(string)
|
||||
|
|
|
@ -333,18 +333,19 @@ Regions are defined via the `regions` variable which sets up a mapping between t
|
|||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L102) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L112) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L128) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [organization](variables.tf#L122) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L138) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L72) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ prod = ["10.0.1.1"] dev = ["10.0.2.1"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L81) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L122) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L139) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L158) | Region definitions. | <code title="object({ primary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L168) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_dev_primary_config](variables.tf#L182) | VPN gateway configuration for onprem interconnection from dev in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_prod_primary_config](variables.tf#L225) | VPN gateway configuration for onprem interconnection from prod in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [groups](variables.tf#L112) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | <code title="object({ gcp-network-admins = optional(string) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L132) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L149) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L168) | Region definitions. | <code title="object({ primary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L178) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_dev_primary_config](variables.tf#L192) | VPN gateway configuration for onprem interconnection from dev in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_prod_primary_config](variables.tf#L235) | VPN gateway configuration for onprem interconnection from prod in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
locals {
|
||||
custom_roles = coalesce(var.custom_roles, {})
|
||||
groups = {
|
||||
for k, v in var.groups :
|
||||
k => can(regex(".*@.*", v)) ? v : "${v}@${var.organization.domain}"
|
||||
}
|
||||
# combine all regions from variables and subnets
|
||||
regions = distinct(concat(
|
||||
values(var.regions),
|
||||
|
@ -41,6 +45,9 @@ module "folder" {
|
|||
name = "Networking"
|
||||
folder_create = var.folder_ids.networking == null
|
||||
id = var.folder_ids.networking
|
||||
contacts = {
|
||||
(local.groups.gcp-network-admins) = ["ALL"]
|
||||
}
|
||||
firewall_policy = {
|
||||
name = "default"
|
||||
policy = module.firewall-policy-default.id
|
||||
|
|
|
@ -109,6 +109,16 @@ variable "folder_ids" {
|
|||
})
|
||||
}
|
||||
|
||||
variable "groups" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed."
|
||||
type = object({
|
||||
gcp-network-admins = optional(string)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "organization" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Organization details."
|
||||
|
|
|
@ -485,22 +485,23 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L101) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L145) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L161) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [organization](variables.tf#L155) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L171) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [dns](variables.tf#L72) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [factories_config](variables.tf#L80) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [gcp_ranges](variables.tf#L111) | GCP address ranges in name => range format. | <code>map(string)</code> | | <code title="{ gcp_dev_primary = "10.68.0.0/16" gcp_dev_secondary = "10.84.0.0/16" gcp_landing_trusted_primary = "10.64.0.0/17" gcp_landing_trusted_secondary = "10.80.0.0/17" gcp_landing_untrusted_primary = "10.64.127.0/17" gcp_landing_untrusted_secondary = "10.80.127.0/17" gcp_prod_primary = "10.72.0.0/16" gcp_prod_secondary = "10.88.0.0/16" }">{…}</code> | |
|
||||
| [ncc_asn](variables.tf#L126) | The NCC Cloud Routers ASN configuration. | <code>map(number)</code> | | <code title="{ nva_primary = 64513 nva_secondary = 64514 trusted = 64515 untrusted = 64512 }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L137) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L155) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L172) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L191) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L203) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L217) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_secondary_config](variables.tf#L260) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [zones](variables.tf#L303) | Zones in which NVAs are deployed. | <code>list(string)</code> | | <code>["b", "c"]</code> | |
|
||||
| [groups](variables.tf#L126) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | <code title="object({ gcp-network-admins = optional(string) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [ncc_asn](variables.tf#L136) | The NCC Cloud Routers ASN configuration. | <code>map(number)</code> | | <code title="{ nva_primary = 64513 nva_secondary = 64514 trusted = 64515 untrusted = 64512 }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L147) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L165) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L182) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L201) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L213) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L227) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_secondary_config](variables.tf#L270) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [zones](variables.tf#L313) | Zones in which NVAs are deployed. | <code>list(string)</code> | | <code>["b", "c"]</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
locals {
|
||||
custom_roles = coalesce(var.custom_roles, {})
|
||||
groups = {
|
||||
for k, v in var.groups :
|
||||
k => can(regex(".*@.*", v)) ? v : "${v}@${var.organization.domain}"
|
||||
}
|
||||
# combine all regions from variables and subnets
|
||||
regions = distinct(concat(
|
||||
values(var.regions),
|
||||
|
@ -46,6 +50,9 @@ module "folder" {
|
|||
name = "Networking"
|
||||
folder_create = var.folder_ids.networking == null
|
||||
id = var.folder_ids.networking
|
||||
contacts = {
|
||||
(local.groups.gcp-network-admins) = ["ALL"]
|
||||
}
|
||||
firewall_policy = {
|
||||
name = "default"
|
||||
policy = module.firewall-policy-default.id
|
||||
|
|
|
@ -123,6 +123,16 @@ variable "gcp_ranges" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "groups" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed."
|
||||
type = object({
|
||||
gcp-network-admins = optional(string)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "ncc_asn" {
|
||||
description = "The NCC Cloud Routers ASN configuration."
|
||||
type = map(number)
|
||||
|
|
|
@ -283,7 +283,7 @@ Some references that might be useful in setting up this stage:
|
|||
|---|---|---|---|
|
||||
| [core-dev.tf](./core-dev.tf) | None | <code>kms</code> · <code>project</code> | |
|
||||
| [core-prod.tf](./core-prod.tf) | None | <code>kms</code> · <code>project</code> | |
|
||||
| [main.tf](./main.tf) | Module-level locals and resources. | | |
|
||||
| [main.tf](./main.tf) | Module-level locals and resources. | <code>folder</code> | |
|
||||
| [outputs.tf](./outputs.tf) | Module outputs. | | <code>google_storage_bucket_object</code> · <code>local_file</code> |
|
||||
| [variables.tf](./variables.tf) | Module variables. | | |
|
||||
| [vpc-sc.tf](./vpc-sc.tf) | None | <code>vpc-sc</code> | |
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
*/
|
||||
|
||||
locals {
|
||||
groups = {
|
||||
for k, v in var.groups :
|
||||
k => can(regex(".*@.*", v)) ? v : "${v}@${var.organization.domain}"
|
||||
}
|
||||
# additive IAM binding for delegated KMS admins
|
||||
kms_restricted_admin_template = {
|
||||
role = "roles/cloudkms.admin"
|
||||
|
@ -53,3 +57,14 @@ locals {
|
|||
"stackdriver.googleapis.com"
|
||||
]
|
||||
}
|
||||
|
||||
module "folder" {
|
||||
source = "../../../modules/folder"
|
||||
parent = "organizations/${var.organization.id}"
|
||||
name = "Security"
|
||||
folder_create = var.folder_ids.security == null
|
||||
id = var.folder_ids.security
|
||||
contacts = {
|
||||
(local.groups.gcp-security-admins) = ["ALL"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -364,6 +364,6 @@ module "folder" {
|
|||
|---|---|:---:|
|
||||
| [folder](outputs.tf#L17) | Folder resource. | |
|
||||
| [id](outputs.tf#L22) | Fully qualified folder id. | |
|
||||
| [name](outputs.tf#L32) | Folder name. | |
|
||||
| [sink_writer_identities](outputs.tf#L37) | Writer identities created for each sink. | |
|
||||
| [name](outputs.tf#L33) | Folder name. | |
|
||||
| [sink_writer_identities](outputs.tf#L38) | Writer identities created for each sink. | |
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -40,6 +40,11 @@ resource "google_essential_contacts_contact" "contact" {
|
|||
email = each.key
|
||||
language_tag = "en"
|
||||
notification_category_subscriptions = each.value
|
||||
depends_on = [
|
||||
google_folder_iam_binding.authoritative,
|
||||
google_folder_iam_binding.bindings,
|
||||
google_folder_iam_member.bindings
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_compute_firewall_policy_association" "default" {
|
||||
|
|
|
@ -25,6 +25,7 @@ output "id" {
|
|||
depends_on = [
|
||||
google_folder_iam_binding.authoritative,
|
||||
google_folder_iam_binding.bindings,
|
||||
google_folder_iam_member.bindings,
|
||||
google_org_policy_policy.default,
|
||||
]
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@ resource "google_essential_contacts_contact" "contact" {
|
|||
email = each.key
|
||||
language_tag = "en"
|
||||
notification_category_subscriptions = each.value
|
||||
depends_on = [
|
||||
google_organization_iam_binding.authoritative,
|
||||
google_organization_iam_binding.bindings,
|
||||
google_organization_iam_member.bindings
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -87,6 +87,11 @@ resource "google_essential_contacts_contact" "contact" {
|
|||
email = each.key
|
||||
language_tag = "en"
|
||||
notification_category_subscriptions = each.value
|
||||
depends_on = [
|
||||
google_project_iam_binding.authoritative,
|
||||
google_project_iam_binding.bindings,
|
||||
google_project_iam_member.bindings
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_monitoring_monitored_project" "primary" {
|
||||
|
|
|
@ -359,10 +359,11 @@ values:
|
|||
counts:
|
||||
google_bigquery_dataset: 1
|
||||
google_bigquery_default_service_account: 3
|
||||
google_essential_contacts_contact: 3
|
||||
google_logging_organization_sink: 3
|
||||
google_logging_project_bucket_config: 3
|
||||
google_org_policy_policy: 16
|
||||
google_organization_iam_binding: 23
|
||||
google_organization_iam_binding: 25
|
||||
google_organization_iam_custom_role: 6
|
||||
google_organization_iam_member: 35
|
||||
google_project: 3
|
||||
|
@ -380,4 +381,4 @@ counts:
|
|||
google_tags_tag_key: 1
|
||||
google_tags_tag_value: 1
|
||||
modules: 16
|
||||
resources: 180
|
||||
resources: 185
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
counts:
|
||||
google_bigquery_dataset: 1
|
||||
google_bigquery_default_service_account: 3
|
||||
google_essential_contacts_contact: 3
|
||||
google_logging_organization_sink: 3
|
||||
google_logging_project_bucket_config: 3
|
||||
google_org_policy_policy: 16
|
||||
google_organization_iam_binding: 23
|
||||
google_organization_iam_binding: 25
|
||||
google_organization_iam_custom_role: 6
|
||||
google_organization_iam_member: 22
|
||||
google_project: 3
|
||||
|
@ -37,7 +38,7 @@ counts:
|
|||
google_tags_tag_value: 1
|
||||
local_file: 7
|
||||
modules: 15
|
||||
resources: 171
|
||||
resources: 176
|
||||
|
||||
outputs:
|
||||
custom_roles:
|
||||
|
|
|
@ -12,6 +12,9 @@ folder_ids = {
|
|||
networking-dev = null
|
||||
networking-prod = null
|
||||
}
|
||||
groups = {
|
||||
gcp-network-admins = "gcp-network-admins"
|
||||
}
|
||||
service_accounts = {
|
||||
data-platform-dev = "string"
|
||||
data-platform-prod = "string"
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
|
||||
counts:
|
||||
modules: 28
|
||||
resources: 147
|
||||
resources: 148
|
||||
|
|
|
@ -12,6 +12,9 @@ folder_ids = {
|
|||
networking-dev = null
|
||||
networking-prod = null
|
||||
}
|
||||
groups = {
|
||||
gcp-network-admins = "gcp-network-admins"
|
||||
}
|
||||
service_accounts = {
|
||||
data-platform-dev = "string"
|
||||
data-platform-prod = "string"
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
|
||||
counts:
|
||||
modules: 30
|
||||
resources: 184
|
||||
resources: 185
|
||||
|
|
|
@ -12,6 +12,9 @@ folder_ids = {
|
|||
networking-dev = null
|
||||
networking-prod = null
|
||||
}
|
||||
groups = {
|
||||
gcp-network-admins = "gcp-network-admins"
|
||||
}
|
||||
service_accounts = {
|
||||
data-platform-dev = "string"
|
||||
data-platform-prod = "string"
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
|
||||
counts:
|
||||
modules: 42
|
||||
resources: 194
|
||||
resources: 195
|
||||
|
|
|
@ -12,6 +12,9 @@ folder_ids = {
|
|||
networking-dev = null
|
||||
networking-prod = null
|
||||
}
|
||||
groups = {
|
||||
gcp-network-admins = "gcp-network-admins"
|
||||
}
|
||||
service_accounts = {
|
||||
data-platform-dev = "string"
|
||||
data-platform-prod = "string"
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
|
||||
counts:
|
||||
modules: 21
|
||||
resources: 169
|
||||
resources: 170
|
||||
|
|
|
@ -12,6 +12,9 @@ folder_ids = {
|
|||
networking-dev = null
|
||||
networking-prod = null
|
||||
}
|
||||
groups = {
|
||||
gcp-network-admins = "gcp-network-admins"
|
||||
}
|
||||
service_accounts = {
|
||||
data-platform-dev = "string"
|
||||
data-platform-prod = "string"
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
|
||||
counts:
|
||||
modules: 36
|
||||
resources: 205
|
||||
resources: 206
|
||||
|
|
Loading…
Reference in New Issue