Merge branch 'master' into fast-dev-dp
This commit is contained in:
commit
60a0009726
|
@ -62,3 +62,8 @@ jobs:
|
|||
id: documentation-links-fabric
|
||||
run: |
|
||||
python3 tools/check_links.py .
|
||||
|
||||
- name: Check name length (fast)
|
||||
id: name-length-fast
|
||||
run: |
|
||||
python3 tools/check_names.py --prefix-length=10 fast/stages
|
||||
|
|
|
@ -66,7 +66,7 @@ We are intentionally not supporting random prefix/suffixes for names, as that is
|
|||
|
||||
What is implemented here is a fairly common convention, composed of tokens ordered by relative importance:
|
||||
|
||||
- a static prefix (e.g. `myco` or `myco-gcp`)
|
||||
- a static prefix less or equal to 9 characters (e.g. `myco` or `myco-gcp`)
|
||||
- an environment identifier (e.g. `prod`)
|
||||
- a team/owner identifier (e.g. `sec` for Security)
|
||||
- a context identifier (e.g. `core` or `kms`)
|
||||
|
@ -169,7 +169,7 @@ Then make sure you have configured the correct values for the following variable
|
|||
- `organization.id`, `organization.domain`, `organization.customer_id`
|
||||
the id, domain and customer id of your organization, derived from the Cloud Console UI or by running `gcloud organizations list`
|
||||
- `prefix`
|
||||
the fixed prefix used in your naming convention
|
||||
the fixed prefix used in your naming, maximum 9 characters long
|
||||
|
||||
You can also adapt the example that follows to your needs:
|
||||
|
||||
|
@ -337,7 +337,7 @@ Names used in internal references (e.g. `module.foo-prod.id`) are only used by T
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [billing_account](variables.tf#L17) | Billing account id and organization id ('nnnnnnnn' or null). | <code title="object({ id = string organization_id = number })">object({…})</code> | ✓ | | |
|
||||
| [organization](variables.tf#L96) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | |
|
||||
| [prefix](variables.tf#L111) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | |
|
||||
| [prefix](variables.tf#L111) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | |
|
||||
| [bootstrap_user](variables.tf#L25) | Email of the nominal user running this stage for the first time. | <code>string</code> | | <code>null</code> | |
|
||||
| [custom_role_names](variables.tf#L31) | Names of custom roles defined at the org level. | <code title="object({ organization_iam_admin = string service_project_network_admin = string })">object({…})</code> | | <code title="{ organization_iam_admin = "organizationIamAdmin" service_project_network_admin = "serviceProjectNetworkAdmin" }">{…}</code> | |
|
||||
| [groups](variables.tf#L43) | Group names to grant organization-level permissions. | <code>map(string)</code> | | <code title="{ gcp-billing-admins = "gcp-billing-admins", gcp-devops = "gcp-devops", gcp-network-admins = "gcp-network-admins" gcp-organization-admins = "gcp-organization-admins" gcp-security-admins = "gcp-security-admins" gcp-support = "gcp-support" }">{…}</code> | |
|
||||
|
|
|
@ -31,7 +31,7 @@ module "billing-export-project" {
|
|||
source = "../../../modules/project"
|
||||
count = local.billing_org ? 1 : 0
|
||||
billing_account = var.billing_account.id
|
||||
name = "billing-export-0"
|
||||
name = "billing-exp-0"
|
||||
parent = "organizations/${var.organization.id}"
|
||||
prefix = local.prefix
|
||||
iam = {
|
||||
|
|
|
@ -109,6 +109,11 @@ variable "outputs_location" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resources that need unique names."
|
||||
description = "Prefix used for resources that need unique names. Use 9 characters or less."
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = try(length(var.prefix), 0) < 10
|
||||
error_message = "Use a maximum of 9 characters for prefix."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,12 +166,12 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
|
|||
| [automation_project_id](variables.tf#L29) | Project id for the automation project created by the bootstrap stage. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L20) | Billing account id and organization id ('nnnnnnnn' or null). | <code title="object({ id = string organization_id = number })">object({…})</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [organization](variables.tf#L57) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L81) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L81) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [custom_roles](variables.tf#L35) | Custom roles defined at the org level, in key => id format. | <code>map(string)</code> | | <code>{}</code> | <code>00-bootstrap</code> |
|
||||
| [groups](variables.tf#L42) | Group names to grant organization-level permissions. | <code>map(string)</code> | | <code title="{ gcp-billing-admins = "gcp-billing-admins", gcp-devops = "gcp-devops", gcp-network-admins = "gcp-network-admins" gcp-organization-admins = "gcp-organization-admins" gcp-security-admins = "gcp-security-admins" gcp-support = "gcp-support" }">{…}</code> | <code>00-bootstrap</code> |
|
||||
| [organization_policy_configs](variables.tf#L67) | Organization policies customization. | <code title="object({ allowed_policy_member_domains = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [outputs_location](variables.tf#L75) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [team_folders](variables.tf#L87) | Team folders to be created. Format is described in a code comment. | <code title="map(object({ descriptive_name = string group_iam = map(list(string)) impersonation_groups = list(string) }))">map(object({…}))</code> | | <code>null</code> | |
|
||||
| [team_folders](variables.tf#L92) | Team folders to be created. Format is described in a code comment. | <code title="map(object({ descriptive_name = string group_iam = map(list(string)) impersonation_groups = list(string) }))">map(object({…}))</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -43,16 +43,16 @@ module "branch-network-folder" {
|
|||
module "branch-network-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-networking-0"
|
||||
name = "prod-resman-net-0"
|
||||
description = "Terraform resman networking service account."
|
||||
prefix = local.prefixes.prod
|
||||
prefix = var.prefix
|
||||
}
|
||||
|
||||
module "branch-network-gcs" {
|
||||
source = "../../../modules/gcs"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-networking-0"
|
||||
prefix = local.prefixes.prod
|
||||
name = "prod-resman-net-0"
|
||||
prefix = var.prefix
|
||||
versioning = true
|
||||
iam = {
|
||||
"roles/storage.objectAdmin" = [module.branch-network-sa.iam_email]
|
||||
|
|
|
@ -42,8 +42,8 @@ module "branch-sandbox-folder" {
|
|||
module "branch-sandbox-gcs" {
|
||||
source = "../../../modules/gcs"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-sandbox-0"
|
||||
prefix = local.prefixes.dev
|
||||
name = "dev-resman-sbox-0"
|
||||
prefix = var.prefix
|
||||
versioning = true
|
||||
iam = {
|
||||
"roles/storage.objectAdmin" = [module.branch-sandbox-sa.iam_email]
|
||||
|
@ -53,7 +53,7 @@ module "branch-sandbox-gcs" {
|
|||
module "branch-sandbox-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-sandbox-0"
|
||||
name = "dev-resman-sbox-0"
|
||||
description = "Terraform resman sandbox service account."
|
||||
prefix = local.prefixes.dev
|
||||
prefix = var.prefix
|
||||
}
|
||||
|
|
|
@ -44,16 +44,16 @@ module "branch-security-folder" {
|
|||
module "branch-security-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-security-0"
|
||||
name = "prod-resman-sec-0"
|
||||
description = "Terraform resman security service account."
|
||||
prefix = local.prefixes.prod
|
||||
prefix = var.prefix
|
||||
}
|
||||
|
||||
module "branch-security-gcs" {
|
||||
source = "../../../modules/gcs"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-security-0"
|
||||
prefix = local.prefixes.prod
|
||||
name = "prod-resman-sec-0"
|
||||
prefix = var.prefix
|
||||
versioning = true
|
||||
iam = {
|
||||
"roles/storage.objectAdmin" = [module.branch-security-sa.iam_email]
|
||||
|
|
|
@ -27,9 +27,9 @@ module "branch-teams-folder" {
|
|||
module "branch-teams-prod-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-teams-0"
|
||||
name = "prod-resman-teams-0"
|
||||
description = "Terraform resman production service account."
|
||||
prefix = local.prefixes.prod
|
||||
prefix = var.prefix
|
||||
}
|
||||
|
||||
# Team-level folders, service accounts and buckets for each individual team
|
||||
|
@ -46,9 +46,9 @@ module "branch-teams-team-sa" {
|
|||
source = "../../../modules/iam-service-account"
|
||||
for_each = coalesce(var.team_folders, {})
|
||||
project_id = var.automation_project_id
|
||||
name = "teams-${each.key}-0"
|
||||
name = "prod-teams-${each.key}-0"
|
||||
description = "Terraform team ${each.key} service account."
|
||||
prefix = local.prefixes.prod
|
||||
prefix = var.prefix
|
||||
iam = {
|
||||
"roles/iam.serviceAccountTokenCreator" = (
|
||||
each.value.impersonation_groups == null
|
||||
|
@ -62,8 +62,8 @@ module "branch-teams-team-gcs" {
|
|||
source = "../../../modules/gcs"
|
||||
for_each = coalesce(var.team_folders, {})
|
||||
project_id = var.automation_project_id
|
||||
name = "teams-${each.key}-0"
|
||||
prefix = local.prefixes.prod
|
||||
name = "prod-teams-${each.key}-0"
|
||||
prefix = var.prefix
|
||||
versioning = true
|
||||
iam = {
|
||||
"roles/storage.objectAdmin" = [module.branch-teams-team-sa[each.key].iam_email]
|
||||
|
@ -103,17 +103,17 @@ module "branch-teams-team-dev-folder" {
|
|||
module "branch-teams-dev-projectfactory-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-pf-0"
|
||||
name = "dev-resman-pf-0"
|
||||
# naming: environment in description
|
||||
description = "Terraform project factory development service account."
|
||||
prefix = local.prefixes.dev
|
||||
prefix = var.prefix
|
||||
}
|
||||
|
||||
module "branch-teams-dev-projectfactory-gcs" {
|
||||
source = "../../../modules/gcs"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-pf-0"
|
||||
prefix = local.prefixes.dev
|
||||
name = "dev-resman-pf-0"
|
||||
prefix = var.prefix
|
||||
versioning = true
|
||||
iam = {
|
||||
"roles/storage.objectAdmin" = [module.branch-teams-dev-projectfactory-sa.iam_email]
|
||||
|
@ -153,17 +153,17 @@ module "branch-teams-team-prod-folder" {
|
|||
module "branch-teams-prod-projectfactory-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-pf-0"
|
||||
name = "prod-resman-pf-0"
|
||||
# naming: environment in description
|
||||
description = "Terraform project factory production service account."
|
||||
prefix = local.prefixes.prod
|
||||
prefix = var.prefix
|
||||
}
|
||||
|
||||
module "branch-teams-prod-projectfactory-gcs" {
|
||||
source = "../../../modules/gcs"
|
||||
project_id = var.automation_project_id
|
||||
name = "resman-pf-0"
|
||||
prefix = local.prefixes.prod
|
||||
name = "prod-resman-pf-0"
|
||||
prefix = var.prefix
|
||||
versioning = true
|
||||
iam = {
|
||||
"roles/storage.objectAdmin" = [module.branch-teams-prod-projectfactory-sa.iam_email]
|
||||
|
|
|
@ -27,9 +27,4 @@ locals {
|
|||
for k, v in local.groups :
|
||||
k => "group:${v}"
|
||||
}
|
||||
# naming: environment names
|
||||
prefixes = {
|
||||
dev = "${var.prefix}-dev"
|
||||
prod = "${var.prefix}-prod"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,8 +80,13 @@ variable "outputs_location" {
|
|||
|
||||
variable "prefix" {
|
||||
# tfdoc:variable:source 00-bootstrap
|
||||
description = "Prefix used for resources that need unique names."
|
||||
description = "Prefix used for resources that need unique names. Use 9 characters or less."
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = try(length(var.prefix), 0) < 10
|
||||
error_message = "Use a maximum of 9 characters for prefix."
|
||||
}
|
||||
}
|
||||
|
||||
variable "team_folders" {
|
||||
|
|
|
@ -366,17 +366,17 @@ Don't forget to add a peering zone in the landing project and point it to the ne
|
|||
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L59) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code>map(string)</code> | ✓ | | <code>01-resman</code> |
|
||||
| [organization](variables.tf#L91) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L107) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L107) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [custom_adv](variables.tf#L23) | Custom advertisement definitions in name => range format. | <code>map(string)</code> | | <code title="{ cloud_dns = "35.199.192.0/19" gcp_all = "10.128.0.0/16" gcp_dev_ew1 = "10.128.128.0/19" gcp_dev_ew4 = "10.128.160.0/19" gcp_landing_trusted_ew1 = "10.128.64.0/19" gcp_landing_trusted_ew4 = "10.128.96.0/19" gcp_landing_untrusted_ew1 = "10.128.0.0/19" gcp_landing_untrusted_ew4 = "10.128.32.0/19" gcp_prod_ew1 = "10.128.192.0/19" gcp_prod_ew4 = "10.128.224.0/19" googleapis_private = "199.36.153.8/30" googleapis_restricted = "199.36.153.4/30" rfc_1918_10 = "10.0.0.0/8" rfc_1918_172 = "172.16.0.0/12" rfc_1918_192 = "192.168.0.0/16" }">{…}</code> | |
|
||||
| [data_dir](variables.tf#L45) | Relative path for the folder storing configuration data for network resources. | <code>string</code> | | <code>"data"</code> | |
|
||||
| [dns](variables.tf#L51) | Onprem DNS resolvers | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [l7ilb_subnets](variables.tf#L65) | Subnets used for L7 ILBs. | <code title="map(list(object({ ip_cidr_range = string region = string })))">map(list(object({…})))</code> | | <code title="{ dev = [ { ip_cidr_range = "10.128.159.0/24", region = "europe-west1" }, { ip_cidr_range = "10.128.191.0/24", region = "europe-west4" } ] prod = [ { ip_cidr_range = "10.128.223.0/24", region = "europe-west1" }, { ip_cidr_range = "10.128.255.0/24", region = "europe-west4" } ] }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L83) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L101) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [project_factory_sa](variables.tf#L113) | IAM emails for project factory service accounts | <code>map(string)</code> | | <code>{}</code> | <code>01-resman</code> |
|
||||
| [psa_ranges](variables.tf#L120) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code>map(map(string))</code> | | <code title="{ dev = { cloudsql-mysql-ew1 = "10.128.157.0/24" cloudsql-mysql-ew4 = "10.128.189.0/24" cloudsql-sqlserver-ew1 = "10.128.158.0/24" cloudsql-sqlserver-ew4 = "10.128.190.0/24" } prod = { cloudsql-mysql-ew1 = "10.128.221.0/24" cloudsql-mysql-ew4 = "10.128.253.0/24" cloudsql-sqlserver-ew1 = "10.128.222.0/24" cloudsql-sqlserver-ew4 = "10.128.254.0/24" } }">{…}</code> | |
|
||||
| [router_configs](variables.tf#L139) | Configurations for CRs and onprem routers. | <code title="map(object({ adv = object({ custom = list(string) default = bool }) asn = number }))">map(object({…}))</code> | | <code title="{ landing-trusted-ew1 = { asn = "64512" adv = null } landing-trusted-ew4 = { asn = "64512" adv = null } }">{…}</code> | |
|
||||
| [vpn_onprem_configs](variables.tf#L162) | VPN gateway configuration for onprem interconnection. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) peer_external_gateway = object({ redundancy_type = string interfaces = list(object({ id = number ip_address = string })) }) tunnels = list(object({ peer_asn = number peer_external_gateway_interface = number secret = string session_range = string vpn_gateway_interface = number })) }))">map(object({…}))</code> | | <code title="{ landing-trusted-ew1 = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = [ { id = 0, ip_address = "8.8.8.8" }, ] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } landing-trusted-ew4 = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = [ { id = 0, ip_address = "8.8.8.8" }, ] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } }">{…}</code> | |
|
||||
| [project_factory_sa](variables.tf#L118) | IAM emails for project factory service accounts | <code>map(string)</code> | | <code>{}</code> | <code>01-resman</code> |
|
||||
| [psa_ranges](variables.tf#L125) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code>map(map(string))</code> | | <code title="{ dev = { cloudsql-mysql-ew1 = "10.128.157.0/24" cloudsql-mysql-ew4 = "10.128.189.0/24" cloudsql-sqlserver-ew1 = "10.128.158.0/24" cloudsql-sqlserver-ew4 = "10.128.190.0/24" } prod = { cloudsql-mysql-ew1 = "10.128.221.0/24" cloudsql-mysql-ew4 = "10.128.253.0/24" cloudsql-sqlserver-ew1 = "10.128.222.0/24" cloudsql-sqlserver-ew4 = "10.128.254.0/24" } }">{…}</code> | |
|
||||
| [router_configs](variables.tf#L144) | Configurations for CRs and onprem routers. | <code title="map(object({ adv = object({ custom = list(string) default = bool }) asn = number }))">map(object({…}))</code> | | <code title="{ landing-trusted-ew1 = { asn = "64512" adv = null } landing-trusted-ew4 = { asn = "64512" adv = null } }">{…}</code> | |
|
||||
| [vpn_onprem_configs](variables.tf#L167) | VPN gateway configuration for onprem interconnection. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) peer_external_gateway = object({ redundancy_type = string interfaces = list(object({ id = number ip_address = string })) }) tunnels = list(object({ peer_asn = number peer_external_gateway_interface = number secret = string session_range = string vpn_gateway_interface = number })) }))">map(object({…}))</code> | | <code title="{ landing-trusted-ew1 = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = [ { id = 0, ip_address = "8.8.8.8" }, ] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } landing-trusted-ew4 = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = [ { id = 0, ip_address = "8.8.8.8" }, ] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } }">{…}</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -106,8 +106,13 @@ variable "outputs_location" {
|
|||
|
||||
variable "prefix" {
|
||||
# tfdoc:variable:source 00-bootstrap
|
||||
description = "Prefix used for resources that need unique names."
|
||||
description = "Prefix used for resources that need unique names. Use 9 characters or less."
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = try(length(var.prefix), 0) < 10
|
||||
error_message = "Use a maximum of 9 characters for prefix."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_factory_sa" {
|
||||
|
|
|
@ -311,18 +311,18 @@ DNS configurations are centralised in the `dns.tf` file. Spokes delegate DNS res
|
|||
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L61) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code>map(string)</code> | ✓ | | <code>01-resman</code> |
|
||||
| [organization](variables.tf#L85) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L101) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L101) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [custom_adv](variables.tf#L23) | Custom advertisement definitions in name => range format. | <code>map(string)</code> | | <code title="{ cloud_dns = "35.199.192.0/19" gcp_all = "10.128.0.0/16" gcp_dev = "10.128.32.0/19" gcp_landing = "10.128.0.0/19" gcp_prod = "10.128.64.0/19" googleapis_private = "199.36.153.8/30" googleapis_restricted = "199.36.153.4/30" rfc_1918_10 = "10.0.0.0/8" rfc_1918_172 = "172.16.0.0/12" rfc_1918_192 = "192.168.0.0/16" }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L40) | Custom roles defined at the org level, in key => id format. | <code>map(string)</code> | | <code>{}</code> | <code>00-bootstrap</code> |
|
||||
| [data_dir](variables.tf#L47) | Relative path for the folder storing configuration data for network resources. | <code>string</code> | | <code>"data"</code> | |
|
||||
| [dns](variables.tf#L53) | Onprem DNS resolvers. | <code>map(list(string))</code> | | <code title="{ onprem = ["10.0.200.3"] }">{…}</code> | |
|
||||
| [l7ilb_subnets](variables.tf#L67) | Subnets used for L7 ILBs. | <code title="map(list(object({ ip_cidr_range = string region = string })))">map(list(object({…})))</code> | | <code title="{ prod = [ { ip_cidr_range = "10.128.92.0/24", region = "europe-west1" }, { ip_cidr_range = "10.128.93.0/24", region = "europe-west4" } ] dev = [ { ip_cidr_range = "10.128.60.0/24", region = "europe-west1" }, { ip_cidr_range = "10.128.61.0/24", region = "europe-west4" } ] }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L95) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [project_factory_sa](variables.tf#L107) | IAM emails for project factory service accounts. | <code>map(string)</code> | | <code>{}</code> | <code>01-resman</code> |
|
||||
| [psa_ranges](variables.tf#L114) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code>map(map(string))</code> | | <code title="{ prod = { cloudsql-mysql = "10.128.94.0/24" cloudsql-sqlserver = "10.128.95.0/24" } dev = { cloudsql-mysql = "10.128.62.0/24" cloudsql-sqlserver = "10.128.63.0/24" } }">{…}</code> | |
|
||||
| [router_configs](variables.tf#L129) | Configurations for CRs and onprem routers. | <code title="map(object({ adv = object({ custom = list(string) default = bool }) asn = number }))">map(object({…}))</code> | | <code title="{ onprem-ew1 = { asn = "65534" adv = null } landing-ew1 = { asn = "64512", adv = null } landing-ew4 = { asn = "64512", adv = null } spoke-dev-ew1 = { asn = "64513", adv = null } spoke-dev-ew4 = { asn = "64513", adv = null } spoke-prod-ew1 = { asn = "64514", adv = null } spoke-prod-ew4 = { asn = "64514", adv = null } }">{…}</code> | |
|
||||
| [vpn_onprem_configs](variables.tf#L153) | VPN gateway configuration for onprem interconnection. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) peer_external_gateway = object({ redundancy_type = string interfaces = list(object({ id = number ip_address = string })) }) tunnels = list(object({ peer_asn = number peer_external_gateway_interface = number secret = string session_range = string vpn_gateway_interface = number })) }))">map(object({…}))</code> | | <code title="{ landing-ew1 = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = [ { id = 0, ip_address = "8.8.8.8" }, ] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } }">{…}</code> | |
|
||||
| [vpn_spoke_configs](variables.tf#L209) | VPN gateway configuration for spokes. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) session_range = string }))">map(object({…}))</code> | | <code title="{ landing-ew1 = { adv = { default = false custom = ["rfc_1918_10", "rfc_1918_172", "rfc_1918_192"] } session_range = null } landing-ew4 = { adv = { default = false custom = ["rfc_1918_10", "rfc_1918_172", "rfc_1918_192"] } session_range = null } dev-ew1 = { adv = { default = false custom = ["gcp_dev"] } session_range = "169.254.0.0/27" } prod-ew1 = { adv = { default = false custom = ["gcp_prod"] } session_range = "169.254.0.64/27" } prod-ew4 = { adv = { default = false custom = ["gcp_prod"] } session_range = "169.254.0.96/27" } }">{…}</code> | |
|
||||
| [project_factory_sa](variables.tf#L112) | IAM emails for project factory service accounts. | <code>map(string)</code> | | <code>{}</code> | <code>01-resman</code> |
|
||||
| [psa_ranges](variables.tf#L119) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code>map(map(string))</code> | | <code title="{ prod = { cloudsql-mysql = "10.128.94.0/24" cloudsql-sqlserver = "10.128.95.0/24" } dev = { cloudsql-mysql = "10.128.62.0/24" cloudsql-sqlserver = "10.128.63.0/24" } }">{…}</code> | |
|
||||
| [router_configs](variables.tf#L134) | Configurations for CRs and onprem routers. | <code title="map(object({ adv = object({ custom = list(string) default = bool }) asn = number }))">map(object({…}))</code> | | <code title="{ onprem-ew1 = { asn = "65534" adv = null } landing-ew1 = { asn = "64512", adv = null } landing-ew4 = { asn = "64512", adv = null } spoke-dev-ew1 = { asn = "64513", adv = null } spoke-dev-ew4 = { asn = "64513", adv = null } spoke-prod-ew1 = { asn = "64514", adv = null } spoke-prod-ew4 = { asn = "64514", adv = null } }">{…}</code> | |
|
||||
| [vpn_onprem_configs](variables.tf#L158) | VPN gateway configuration for onprem interconnection. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) peer_external_gateway = object({ redundancy_type = string interfaces = list(object({ id = number ip_address = string })) }) tunnels = list(object({ peer_asn = number peer_external_gateway_interface = number secret = string session_range = string vpn_gateway_interface = number })) }))">map(object({…}))</code> | | <code title="{ landing-ew1 = { adv = { default = false custom = [ "cloud_dns", "googleapis_private", "googleapis_restricted", "gcp_all" ] } peer_external_gateway = { redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" interfaces = [ { id = 0, ip_address = "8.8.8.8" }, ] } tunnels = [ { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.0/30" vpn_gateway_interface = 0 }, { peer_asn = 65534 peer_external_gateway_interface = 0 secret = "foobar" session_range = "169.254.1.4/30" vpn_gateway_interface = 1 } ] } }">{…}</code> | |
|
||||
| [vpn_spoke_configs](variables.tf#L214) | VPN gateway configuration for spokes. | <code title="map(object({ adv = object({ default = bool custom = list(string) }) session_range = string }))">map(object({…}))</code> | | <code title="{ landing-ew1 = { adv = { default = false custom = ["rfc_1918_10", "rfc_1918_172", "rfc_1918_192"] } session_range = null } landing-ew4 = { adv = { default = false custom = ["rfc_1918_10", "rfc_1918_172", "rfc_1918_192"] } session_range = null } dev-ew1 = { adv = { default = false custom = ["gcp_dev"] } session_range = "169.254.0.0/27" } prod-ew1 = { adv = { default = false custom = ["gcp_prod"] } session_range = "169.254.0.64/27" } prod-ew4 = { adv = { default = false custom = ["gcp_prod"] } session_range = "169.254.0.96/27" } }">{…}</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -100,8 +100,13 @@ variable "outputs_location" {
|
|||
|
||||
variable "prefix" {
|
||||
# tfdoc:variable:source 00-bootstrap
|
||||
description = "Prefix used for resources that need unique names."
|
||||
description = "Prefix used for resources that need unique names. Use 9 characters or less."
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = try(length(var.prefix), 0) < 10
|
||||
error_message = "Use a maximum of 9 characters for prefix."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_factory_sa" {
|
||||
|
|
|
@ -288,19 +288,19 @@ Some references that might be useful in setting up this stage:
|
|||
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | | <code>bootstrap</code> |
|
||||
| [folder_id](variables.tf#L23) | Folder to be used for the networking resources in folders/nnnn format. | <code>string</code> | ✓ | | <code>resman</code> |
|
||||
| [organization](variables.tf#L73) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>bootstrap</code> |
|
||||
| [prefix](variables.tf#L89) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | |
|
||||
| [prefix](variables.tf#L89) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [groups](variables.tf#L29) | Group names to grant organization-level permissions. | <code>map(string)</code> | | <code title="{ gcp-billing-admins = "gcp-billing-admins", gcp-devops = "gcp-devops", gcp-network-admins = "gcp-network-admins" gcp-organization-admins = "gcp-organization-admins" gcp-security-admins = "gcp-security-admins" gcp-support = "gcp-support" }">{…}</code> | <code>bootstrap</code> |
|
||||
| [kms_defaults](variables.tf#L44) | Defaults used for KMS keys. | <code title="object({ locations = list(string) rotation_period = string })">object({…})</code> | | <code title="{ locations = ["europe", "europe-west1", "europe-west3", "global"] rotation_period = "7776000s" }">{…}</code> | |
|
||||
| [kms_keys](variables.tf#L56) | KMS keys to create, keyed by name. Null attributes will be interpolated with defaults. | <code title="map(object({ iam = map(list(string)) labels = map(string) locations = list(string) rotation_period = string }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [kms_restricted_admins](variables.tf#L67) | Map of environment => [identities] who can assign the encrypt/decrypt roles on keys. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [outputs_location](variables.tf#L83) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [vpc_sc_access_levels](variables.tf#L94) | VPC SC access level definitions. | <code title="map(object({ combining_function = string conditions = list(object({ ip_subnetworks = list(string) members = list(string) negate = bool regions = list(string) required_access_levels = list(string) })) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_egress_policies](variables.tf#L109) | VPC SC egress policy defnitions. | <code title="map(object({ egress_from = object({ identity_type = string identities = list(string) }) egress_to = object({ operations = list(object({ method_selectors = list(string) service_name = string })) resources = list(string) }) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_ingress_policies](variables.tf#L127) | VPC SC ingress policy defnitions. | <code title="map(object({ ingress_from = object({ identity_type = string identities = list(string) source_access_levels = list(string) source_resources = list(string) }) ingress_to = object({ operations = list(object({ method_selectors = list(string) service_name = string })) resources = list(string) }) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_perimeter_access_levels](variables.tf#L147) | VPC SC perimeter access_levels. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_egress_policies](variables.tf#L157) | VPC SC egress policies per perimeter, values reference keys defined in the `vpc_sc_ingress_policies` variable. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_ingress_policies](variables.tf#L167) | VPC SC ingress policies per perimeter, values reference keys defined in the `vpc_sc_ingress_policies` variable. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_projects](variables.tf#L177) | VPC SC perimeter resources. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_access_levels](variables.tf#L100) | VPC SC access level definitions. | <code title="map(object({ combining_function = string conditions = list(object({ ip_subnetworks = list(string) members = list(string) negate = bool regions = list(string) required_access_levels = list(string) })) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_egress_policies](variables.tf#L115) | VPC SC egress policy defnitions. | <code title="map(object({ egress_from = object({ identity_type = string identities = list(string) }) egress_to = object({ operations = list(object({ method_selectors = list(string) service_name = string })) resources = list(string) }) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_ingress_policies](variables.tf#L133) | VPC SC ingress policy defnitions. | <code title="map(object({ ingress_from = object({ identity_type = string identities = list(string) source_access_levels = list(string) source_resources = list(string) }) ingress_to = object({ operations = list(object({ method_selectors = list(string) service_name = string })) resources = list(string) }) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_perimeter_access_levels](variables.tf#L153) | VPC SC perimeter access_levels. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_egress_policies](variables.tf#L163) | VPC SC egress policies per perimeter, values reference keys defined in the `vpc_sc_ingress_policies` variable. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_ingress_policies](variables.tf#L173) | VPC SC ingress policies per perimeter, values reference keys defined in the `vpc_sc_ingress_policies` variable. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_projects](variables.tf#L183) | VPC SC perimeter resources. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -87,8 +87,14 @@ variable "outputs_location" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resources that need unique names."
|
||||
# tfdoc:variable:source 00-bootstrap
|
||||
description = "Prefix used for resources that need unique names. Use 9 characters or less."
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = try(length(var.prefix), 0) < 10
|
||||
error_message = "Use a maximum of 9 characters for prefix."
|
||||
}
|
||||
}
|
||||
|
||||
variable "vpc_sc_access_levels" {
|
||||
|
|
|
@ -108,12 +108,12 @@ terraform apply
|
|||
| name | description | type | required | default | producer |
|
||||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [billing_account_id](variables.tf#L19) | Billing account id. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L44) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L44) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [data_dir](variables.tf#L25) | Relative path for the folder storing configuration data. | <code>string</code> | | <code>"data/projects"</code> | |
|
||||
| [defaults_file](variables.tf#L38) | Relative path for the file storing the project factory configuration. | <code>string</code> | | <code>"data/defaults.yaml"</code> | |
|
||||
| [environment_dns_zone](variables.tf#L31) | DNS zone suffix for environment. | <code>string</code> | | <code>null</code> | <code>02-networking</code> |
|
||||
| [shared_vpc_self_link](variables.tf#L50) | Self link for the shared VPC. | <code>string</code> | | <code>null</code> | <code>02-networking</code> |
|
||||
| [vpc_host_project](variables.tf#L57) | Host project for the shared VPC. | <code>string</code> | | <code>null</code> | <code>02-networking</code> |
|
||||
| [shared_vpc_self_link](variables.tf#L55) | Self link for the shared VPC. | <code>string</code> | | <code>null</code> | <code>02-networking</code> |
|
||||
| [vpc_host_project](variables.tf#L62) | Host project for the shared VPC. | <code>string</code> | | <code>null</code> | <code>02-networking</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -43,8 +43,13 @@ variable "defaults_file" {
|
|||
|
||||
variable "prefix" {
|
||||
# tfdoc:variable:source 00-bootstrap
|
||||
description = "Prefix used for resources that need unique names."
|
||||
description = "Prefix used for resources that need unique names. Use 9 characters or less."
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = try(length(var.prefix), 0) < 10
|
||||
error_message = "Use a maximum of 9 characters for prefix."
|
||||
}
|
||||
}
|
||||
|
||||
variable "shared_vpc_self_link" {
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
'Parse names from specific Terraform resources and optionally check length.'
|
||||
|
||||
import collections
|
||||
import enum
|
||||
import logging
|
||||
import pathlib
|
||||
import re
|
||||
|
||||
import click
|
||||
|
||||
|
||||
BASEDIR = pathlib.Path(__file__).resolve().parents[1]
|
||||
LOGGER = logging.getLogger()
|
||||
MOD_TOKENS = [
|
||||
('NAME', r'\s*module\s*"([^"]+)"\s*\{\s*'),
|
||||
('SOURCE', r'\s*source\s*=\s*"([^"]+)"\s*'),
|
||||
('VALUE', r'\s*name\s*=\s*"([^"]+)"\s*'),
|
||||
('REST', r'(.*)')
|
||||
]
|
||||
MOD = enum.Enum('MOD', ' '.join(name for name, _ in MOD_TOKENS))
|
||||
MOD_RE = re.compile('|'.join(f'(?:{pattern})' for _, pattern in MOD_TOKENS))
|
||||
MOD_LIMITS = {
|
||||
'project': 30, 'iam-service-account': 30, 'gcs': 63
|
||||
}
|
||||
|
||||
Name = collections.namedtuple('Name', 'source name value length')
|
||||
|
||||
|
||||
def get_names(dir_name):
|
||||
dir_path = BASEDIR / dir_name
|
||||
for tf_path in sorted(dir_path.glob('**/*.tf')):
|
||||
if '.terraform' in str(tf_path):
|
||||
continue
|
||||
LOGGER.debug(f'file {tf_path}')
|
||||
doc = tf_path.read_text()
|
||||
name = source = None
|
||||
for m in MOD_RE.finditer(doc):
|
||||
token_type = MOD(m.lastindex)
|
||||
if token_type == MOD.REST:
|
||||
continue
|
||||
value = m.group(m.lastindex).strip()
|
||||
LOGGER.debug(f'{token_type}: {value}')
|
||||
if token_type == MOD.NAME:
|
||||
if name:
|
||||
LOGGER.debug(f'module {name} already open ({value})')
|
||||
name = value
|
||||
source = None
|
||||
elif token_type == MOD.SOURCE:
|
||||
source = value.split('/')[-1]
|
||||
LOGGER.debug(f'{name} {source}')
|
||||
elif token_type == MOD.VALUE:
|
||||
if name is None or source not in MOD_LIMITS:
|
||||
continue
|
||||
if '$' in value:
|
||||
LOGGER.debug(f'interpolation in {name} ({value}), skipping')
|
||||
else:
|
||||
yield Name(source, name, value, len(value))
|
||||
name = source = None
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.argument('dirs', type=str, nargs=-1)
|
||||
@click.option('--prefix-length', default=7, type=int)
|
||||
def main(dirs, prefix_length=None):
|
||||
'Parse names in dirs.'
|
||||
import json
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
names = []
|
||||
for dir_name in dirs:
|
||||
for name in get_names(dir_name):
|
||||
names.append(name)
|
||||
names.sort()
|
||||
source_just = max(len(k) for k in MOD_LIMITS)
|
||||
name_just = max(len(n.name) for n in names)
|
||||
value_just = max(len(n.value) for n in names)
|
||||
for name in names:
|
||||
name_length = name.length + prefix_length
|
||||
flag = '✗' if name_length >= MOD_LIMITS[name.source] else '✓'
|
||||
print((
|
||||
f'[{flag}] {name.source.ljust(source_just)} '
|
||||
f'{name.name.ljust(name_just)} '
|
||||
f'{name.value.ljust(value_just)} '
|
||||
f'({name_length})'
|
||||
))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue