diff --git a/fast/stages/2-networking/README.md b/fast/stages/2-networking/README.md index 827800755..72153c266 100644 --- a/fast/stages/2-networking/README.md +++ b/fast/stages/2-networking/README.md @@ -313,30 +313,30 @@ Internally created resources are mapped to context namespaces, and use specific | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [automation](variables-fast.tf#L17) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | -| [billing_account](variables-fast.tf#L26) | Billing account id. | object({…}) | ✓ | | -| [organization](variables-fast.tf#L58) | Organization details. | object({…}) | ✓ | | -| [prefix](variables-fast.tf#L67) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | string | ✓ | | -| [context](variables.tf#L17) | Context-specific interpolations. | object({…}) | | {} | -| [custom_roles](variables-fast.tf#L34) | Custom roles defined at the org level, in key => id format. | map(string) | | {} | -| [factories_config](variables.tf#L32) | Configuration for the resource factories or external data. | object({…}) | | {} | -| [folder_ids](variables-fast.tf#L42) | Folders created in the bootstrap stage. | map(string) | | {} | -| [iam_principals](variables-fast.tf#L50) | IAM-format principals. | map(string) | | {} | -| [outputs_location](variables.tf#L49) | Path where tfvars files for the following stages are written. Leave empty to disable. | string | | null | -| [project_ids](variables-fast.tf#L77) | Projects created in the bootstrap stage. | map(string) | | {} | -| [service_accounts](variables-fast.tf#L85) | Service accounts created in the bootstrap stage. | map(string) | | {} | -| [tag_keys](variables-fast.tf#L93) | FAST-managed resource manager tag keys. | map(string) | | {} | -| [tag_values](variables-fast.tf#L101) | FAST-managed resource manager tag values. | map(string) | | {} | -| [universe](variables.tf#L55) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | object({…}) | | null | +| [billing_account](variables-fast.tf#L17) | Billing account id. | object({…}) | ✓ | | +| [organization](variables-fast.tf#L49) | Organization details. | object({…}) | ✓ | | +| [prefix](variables-fast.tf#L66) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | string | ✓ | | +| [context](variables.tf#L17) | Context-specific interpolations. | object({…}) | | {} | +| [custom_roles](variables-fast.tf#L25) | Custom roles defined at the org level, in key => id format. | map(string) | | {} | +| [factories_config](variables.tf#L36) | Configuration for the resource factories or external data. | object({…}) | | {} | +| [folder_ids](variables-fast.tf#L33) | Folders created in the bootstrap stage. | map(string) | | {} | +| [iam_principals](variables-fast.tf#L41) | IAM-format principals. | map(string) | | {} | +| [perimeters](variables-fast.tf#L58) | Optional VPC-SC perimeter ids. | map(string) | | {} | +| [project_ids](variables-fast.tf#L76) | Projects created in the bootstrap stage. | map(string) | | {} | +| [service_accounts](variables-fast.tf#L84) | Service accounts created in the bootstrap stage. | map(string) | | {} | +| [storage_buckets](variables-fast.tf#L92) | Storage buckets created in the bootstrap stage. | map(string) | | {} | +| [tag_keys](variables-fast.tf#L100) | FAST-managed resource manager tag keys. | map(string) | | {} | +| [tag_values](variables-fast.tf#L108) | FAST-managed resource manager tag values. | map(string) | | {} | +| [universe](variables.tf#L53) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | object({…}) | | null | ## Outputs | name | description | sensitive | |---|---|:---:| -| [host_project_ids](outputs.tf#L65) | Project IDs. | | -| [host_project_numbers](outputs.tf#L70) | Project numbers. | | -| [subnet_proxy_only_self_links](outputs.tf#L75) | Subnet proxy-only self-links. | | -| [subnet_psc_self_links](outputs.tf#L80) | Subnet PSC self-links. | | -| [subnet_self_links](outputs.tf#L85) | Subnet self-links. | | -| [vpc_self_links](outputs.tf#L90) | VPC self-links. | | +| [host_project_ids](outputs.tf#L68) | Project IDs. | | +| [host_project_numbers](outputs.tf#L73) | Project numbers. | | +| [subnet_proxy_only_self_links](outputs.tf#L78) | Subnet proxy-only self-links. | | +| [subnet_psc_self_links](outputs.tf#L83) | Subnet PSC self-links. | | +| [subnet_self_links](outputs.tf#L88) | Subnet self-links. | | +| [vpc_self_links](outputs.tf#L93) | VPC self-links. | | diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-ncc/defaults.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-ncc/defaults.yaml index baa14c8b2..868c922a4 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-ncc/defaults.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-ncc/defaults.yaml @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# yaml-language-server: $schema=../../schemas/defaults.schema.json + context: cidr_ranges_sets: healthchecks: @@ -27,13 +29,15 @@ context: primary: europe-west8 secondary: europe-west12 iam_principals: {} - projects: defaults: locations: storage: eu - vpcs: auto_create_subnetworks: false delete_default_route_on_create: true mtu: 1500 +output_files: + # local path is optional but recommended when starting + # local_path: ~/fast-config/fast-test-00 + storage_bucket: $storage_buckets:iac-0/iac-outputs diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-nva/defaults.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-nva/defaults.yaml index baa14c8b2..868c922a4 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-nva/defaults.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-nva/defaults.yaml @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# yaml-language-server: $schema=../../schemas/defaults.schema.json + context: cidr_ranges_sets: healthchecks: @@ -27,13 +29,15 @@ context: primary: europe-west8 secondary: europe-west12 iam_principals: {} - projects: defaults: locations: storage: eu - vpcs: auto_create_subnetworks: false delete_default_route_on_create: true mtu: 1500 +output_files: + # local path is optional but recommended when starting + # local_path: ~/fast-config/fast-test-00 + storage_bucket: $storage_buckets:iac-0/iac-outputs diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/defaults.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/defaults.yaml index baa14c8b2..868c922a4 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/defaults.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/defaults.yaml @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# yaml-language-server: $schema=../../schemas/defaults.schema.json + context: cidr_ranges_sets: healthchecks: @@ -27,13 +29,15 @@ context: primary: europe-west8 secondary: europe-west12 iam_principals: {} - projects: defaults: locations: storage: eu - vpcs: auto_create_subnetworks: false delete_default_route_on_create: true mtu: 1500 +output_files: + # local path is optional but recommended when starting + # local_path: ~/fast-config/fast-test-00 + storage_bucket: $storage_buckets:iac-0/iac-outputs diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-vpns/defaults.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-vpns/defaults.yaml index baa14c8b2..868c922a4 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-vpns/defaults.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-vpns/defaults.yaml @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# yaml-language-server: $schema=../../schemas/defaults.schema.json + context: cidr_ranges_sets: healthchecks: @@ -27,13 +29,15 @@ context: primary: europe-west8 secondary: europe-west12 iam_principals: {} - projects: defaults: locations: storage: eu - vpcs: auto_create_subnetworks: false delete_default_route_on_create: true mtu: 1500 +output_files: + # local path is optional but recommended when starting + # local_path: ~/fast-config/fast-test-00 + storage_bucket: $storage_buckets:iac-0/iac-outputs diff --git a/fast/stages/2-networking/factory-dns.tf b/fast/stages/2-networking/factory-dns.tf index 267589d47..aa74552b8 100644 --- a/fast/stages/2-networking/factory-dns.tf +++ b/fast/stages/2-networking/factory-dns.tf @@ -25,7 +25,7 @@ locals { }) ] dns_zones = { - for zone_config in local._dns_preprocess : "${zone_config.key}" => merge( + for zone_config in local._dns_preprocess : zone_config.key => merge( zone_config, { project_id = zone_config.project_id @@ -85,7 +85,7 @@ locals { ) ] dns_response_policies = { - for policy_config in local._dns_response_policies_preprocess : "${policy_config.key}" => { + for policy_config in local._dns_response_policies_preprocess : policy_config.key => { project_id = policy_config.project_id name = policy_config.key networks = policy_config.networks diff --git a/fast/stages/2-networking/factory-projects.tf b/fast/stages/2-networking/factory-projects.tf index fb1b97402..d88ecefc5 100644 --- a/fast/stages/2-networking/factory-projects.tf +++ b/fast/stages/2-networking/factory-projects.tf @@ -23,19 +23,6 @@ locals { ctx_projects = { project_ids = merge(local.ctx.project_ids, module.projects.project_ids) } - project_defaults = { - defaults = merge( - { - billing_account = var.billing_account.id - prefix = var.prefix - }, - lookup(var.folder_ids, local.defaults.folder_name, null) == null ? {} : { - parent = lookup(var.folder_ids, local.defaults.folder_name, null) - }, - try(local._defaults.projects.defaults, {}) - ) - overrides = try(local._defaults.projects.overrides, {}) - } } moved { @@ -44,10 +31,15 @@ moved { } module "projects" { - source = "../../../modules/project-factory" - data_defaults = local.project_defaults.defaults - data_overrides = local.project_defaults.overrides - context = local.ctx + source = "../../../modules/project-factory" + data_defaults = local.project_defaults.defaults + data_overrides = merge( + { + universe = var.universe + }, + local.project_defaults.overrides + ) + context = local.ctx factories_config = { folders = var.factories_config.folders projects = var.factories_config.projects diff --git a/fast/stages/2-networking/factory-vpcs.tf b/fast/stages/2-networking/factory-vpcs.tf index a98245810..a60fd6b87 100644 --- a/fast/stages/2-networking/factory-vpcs.tf +++ b/fast/stages/2-networking/factory-vpcs.tf @@ -49,7 +49,7 @@ locals { } vpcs = { for k, v in local._vpcs : k => merge( - local.defaults.vpcs, v, + local.vpc_defaults, v, { project_id = v.project_id description = try(v.description, "Terraform managed") @@ -78,7 +78,6 @@ locals { } ) } - vpc_defaults = try(local._defaults.vpcs.defaults, {}) } module "vpcs" { diff --git a/fast/stages/2-networking/main.tf b/fast/stages/2-networking/main.tf index 865ee6602..33290c5e0 100644 --- a/fast/stages/2-networking/main.tf +++ b/fast/stages/2-networking/main.tf @@ -17,40 +17,67 @@ locals { paths = { for k, v in var.factories_config : k => try(pathexpand(v), null) } + _ctx = { + for k, v in var.context : k => merge( + v, try(local._defaults.context[k], {}) + ) + } + # dereferencing for outputs bucket + _ctx_buckets = { + for k, v in local.ctx.storage_buckets : "$storage_buckets:${k}" => v + } # fail if we have no valid defaults _defaults = yamldecode(file(local.paths.defaults)) - ctx = merge(var.context, { - cidr_ranges_sets = try(local._defaults.context.cidr_ranges_sets, {}) - folder_ids = merge( - var.folder_ids, var.context.folder_ids - ) + ctx = merge(local._ctx, { + custom_roles = merge(var.custom_roles, local._ctx.custom_roles) + folder_ids = merge(var.folder_ids, var.context.folder_ids) iam_principals = merge( var.iam_principals, { for k, v in var.service_accounts : "service_accounts/${k}" => "serviceAccount:${v}" }, - var.context.iam_principals, - try(local._defaults.context.iam_principals, {}) + local._ctx.iam_principals ) - locations = merge( - var.context.locations, - try(local._defaults.context.locations, {}) - ) - project_ids = merge(var.project_ids, var.context.project_ids) - tag_keys = merge(var.tag_keys, var.context.tag_keys) - tag_values = merge(var.tag_values, var.context.tag_values) + perimeters = merge(var.perimeters, local._ctx.vpc_sc_perimeters) + project_ids = merge(var.project_ids, local._ctx.project_ids) + storage_buckets = merge(var.storage_buckets, local._ctx.storage_buckets) + tag_keys = merge(var.tag_keys, local._ctx.tag_keys) + tag_values = merge(var.tag_values, local._ctx.tag_values) }) - + # normalize defaults defaults = { folder_name = try(local._defaults.global.folder_id, "networking") stage_name = try(local._defaults.global.stage_name, "2-networking") - vpcs = try(local._defaults.vpcs, {}) } output_files = { - local_path = try(local._defaults.output_files.local_path, null) - storage_bucket = try(local._defaults.output_files.storage_bucket, null) - providers = try(local._defaults.output_files.providers, {}) + local_path = try(local._defaults.output_files.local_path, null) + storage_bucket = try( + local._ctx_buckets[local._defaults.output_files.storage_bucket], + local._defaults.output_files.storage_bucket, + null + ) } + project_defaults = { + defaults = merge( + { + billing_account = var.billing_account.id + prefix = var.prefix + }, + lookup(var.folder_ids, local.defaults.folder_name, null) == null ? {} : { + parent = lookup(var.folder_ids, local.defaults.folder_name, null) + }, + try(local._defaults.projects.defaults, {}) + ) + overrides = try(local._defaults.projects.overrides, {}) + } + vpc_defaults = merge( + { + auto_create_subnetworks = false + delete_default_route_on_create = true + mtu = 1500 + }, + try(local._defaults.vpcs, {}) + ) } diff --git a/fast/stages/2-networking/outputs.tf b/fast/stages/2-networking/outputs.tf index c68bb1870..43e8faa65 100644 --- a/fast/stages/2-networking/outputs.tf +++ b/fast/stages/2-networking/outputs.tf @@ -39,25 +39,28 @@ locals { # generate tfvars file for subsequent stages +resource "google_storage_bucket_object" "version" { + count = ( + local.output_files.storage_bucket != null && + fileexists("fast_version.txt") ? 1 : 0 + ) + bucket = local.output_files.storage_bucket + name = "versions/${local.defaults.stage_name}-version.txt" + source = "fast_version.txt" +} + resource "local_file" "tfvars" { - for_each = var.outputs_location == null ? {} : { 1 = 1 } + for_each = local.output_files.local_path == null ? {} : { 1 = 1 } file_permission = "0644" - filename = "${try(pathexpand(var.outputs_location), "")}tfvars/2-networking.auto.tfvars.json" + filename = "${pathexpand(local.output_files.local_path)}/tfvars/${local.defaults.stage_name}.auto.tfvars.json" content = jsonencode(local.tfvars) } resource "google_storage_bucket_object" "tfvars" { - for_each = try(var.automation.outputs_bucket, null) == null ? {} : { 1 = 1 } - bucket = var.automation.outputs_bucket - name = "tfvars/2-networking.auto.tfvars.json" - content = jsonencode(local.tfvars) -} - -resource "google_storage_bucket_object" "version" { - for_each = try(var.automation.outputs_bucket, null) == null || !fileexists("fast_version.txt") ? {} : { 1 = 1 } - bucket = var.automation.outputs_bucket - name = "versions/2-networking-version.txt" - source = "fast_version.txt" + count = local.output_files.storage_bucket != null ? 1 : 0 + bucket = local.output_files.storage_bucket + name = "tfvars/${local.defaults.stage_name}.auto.tfvars.json" + content = jsonencode(local.tfvars) } # outputs diff --git a/fast/stages/2-networking/schemas/defaults.schema.json b/fast/stages/2-networking/schemas/defaults.schema.json new file mode 100644 index 000000000..89f6400df --- /dev/null +++ b/fast/stages/2-networking/schemas/defaults.schema.json @@ -0,0 +1,730 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Bootstrap Defaults", + "type": "object", + "additionalProperties": false, + "properties": { + "global": { + "type": "object", + "additionalProperties": false, + "properties": { + "folder_name": { + "type": "string", + "default": "networking" + }, + "stage_name": { + "type": "string", + "default": "2-networking" + } + }, + "required": [] + }, + "projects": { + "type": "object", + "additionalProperties": false, + "properties": { + "defaults": { + "type": "object", + "additionalProperties": false, + "properties": { + "billing_account": { + "type": "string" + }, + "bucket": { + "type": "object", + "additionalProperties": false, + "properties": { + "force_destroy": { + "type": "boolean" + } + } + }, + "contacts": { + "type": "object", + "default": {}, + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "deletion_policy": { + "type": "string", + "enum": [ + "PREVENT", + "DELETE", + "ABANDON" + ] + }, + "labels": { + "type": "object", + "default": {}, + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "locations": { + "type": "object", + "additionalProperties": false, + "properties": { + "bigquery": { + "type": "string" + }, + "logging": { + "type": "string" + }, + "storage": { + "type": "string" + } + } + }, + "logging_data_access": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "object", + "properties": { + "ADMIN_READ": { + "type": "object", + "properties": { + "exempted_members": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "DATA_READ": { + "type": "object", + "properties": { + "exempted_members": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "DATA_WRITE": { + "type": "object", + "properties": { + "exempted_members": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "metric_scopes": { + "type": "array", + "default": [], + "items": { + "type": "string" + } + }, + "parent": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "project_reuse": { + "type": "object", + "additionalProperties": false, + "properties": { + "use_data_source": { + "type": "boolean", + "default": true + }, + "attributes": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "number": { + "type": "number" + }, + "services_enabled": { + "type": "array", + "default": [], + "items": { + "type": "string" + } + } + }, + "required": [ + "name", + "number" + ] + } + } + }, + "service_encryption_key_ids": { + "type": "object", + "default": {}, + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "services": { + "type": "array", + "default": [], + "items": { + "type": "string" + } + }, + "shared_vpc_service_config": { + "type": "object", + "additionalProperties": false, + "properties": { + "host_project": { + "type": "string" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "network_users": { + "type": "array", + "default": [], + "items": { + "type": "string" + } + }, + "service_agent_iam": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "service_agent_subnet_iam": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "service_iam_grants": { + "type": "array", + "default": [], + "items": { + "type": "string" + } + }, + "network_subnet_users": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "required": [ + "host_project" + ] + }, + "tag_bindings": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "service_accounts": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "object", + "properties": { + "display_name": { + "type": "string", + "default": "Terraform-managed." + }, + "iam_self_roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "universe": { + "type": "object", + "additionalProperties": false, + "required": [ + "domain", + "prefix" + ], + "properties": { + "domain": { + "type": "string" + }, + "forced_jit_service_identities": { + "type": "array", + "items": { + "type": "string" + } + }, + "prefix": { + "type": "string" + }, + "unavailable_service_identities": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "vpc_sc": { + "type": "object", + "properties": { + "perimeter_name": { + "type": "string" + }, + "is_dry_run": { + "type": "boolean", + "default": false + } + }, + "required": [ + "perimeter_name" + ] + } + } + }, + "overrides": { + "type": "object", + "additionalProperties": false, + "properties": { + "billing_account": { + "type": "string" + }, + "bucket": { + "type": "object", + "additionalProperties": false, + "properties": { + "force_destroy": { + "type": "boolean" + } + } + }, + "contacts": { + "type": "object", + "default": {}, + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "deletion_policy": { + "type": "string", + "enum": [ + "PREVENT", + "DELETE", + "ABANDON" + ] + }, + "locations": { + "type": "object", + "additionalProperties": false, + "properties": { + "bigquery": { + "type": "string" + }, + "logging": { + "type": "string" + }, + "storage": { + "type": "string" + } + } + }, + "logging_data_access": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "object", + "properties": { + "ADMIN_READ": { + "type": "object", + "properties": { + "exempted_members": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "DATA_READ": { + "type": "object", + "properties": { + "exempted_members": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "DATA_WRITE": { + "type": "object", + "properties": { + "exempted_members": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "parent": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "service_encryption_key_ids": { + "type": "object", + "default": {}, + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "tag_bindings": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "service_accounts": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "object", + "properties": { + "display_name": { + "type": "string", + "default": "Terraform-managed." + }, + "iam_self_roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "universe": { + "type": "object", + "additionalProperties": false, + "required": [ + "domain", + "prefix" + ], + "properties": { + "domain": { + "type": "string" + }, + "forced_jit_service_identities": { + "type": "array", + "items": { + "type": "string" + } + }, + "prefix": { + "type": "string" + }, + "unavailable_service_identities": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "vpc_sc": { + "type": "object", + "properties": { + "perimeter_name": { + "type": "string" + }, + "is_dry_run": { + "type": "boolean", + "default": false + } + }, + "required": [ + "perimeter_name" + ] + } + } + } + } + }, + "vpcs": { + "type": "object", + "additionalProperties": false, + "properties": { + "auto_create_subnetworks": { + "type": "boolean", + "default": false + }, + "delete_default_route_on_create": { + "type": "boolean", + "default": true + }, + "mtu": { + "type": "number", + "default": 1500 + } + } + }, + "context": { + "type": "object", + "additionalProperties": false, + "properties": { + "cidr_ranges_sets": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "custom_roles": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "folder_ids": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "kms_keys": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "iam_principals": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "locations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "project_ids": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "storage_buckets": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "tag_keys": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "tag_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "vpc_sc_perimeters": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "output_files": { + "type": "object", + "additionalProperties": false, + "properties": { + "local_path": { + "type": "string" + }, + "storage_bucket": { + "type": "string" + } + } + } + }, + "$defs": { + "iam": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^(?:roles/|\\$custom_roles:)": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:||\\$iam_principals:[a-z0-9_-]+)" + } + } + } + }, + "iam_bindings": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "members": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)" + } + }, + "role": { + "type": "string", + "pattern": "^(?:roles/|\\$custom_roles:)" + }, + "condition": { + "type": "object", + "additionalProperties": false, + "required": [ + "expression", + "title" + ], + "properties": { + "expression": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + } + } + }, + "iam_bindings_additive": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "member": { + "type": "string", + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)" + }, + "role": { + "type": "string", + "pattern": "^(?:roles/|\\$custom_roles:)" + }, + "condition": { + "type": "object", + "additionalProperties": false, + "required": [ + "expression", + "title" + ], + "properties": { + "expression": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + } + } + }, + "iam_by_principals": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:roles/|\\$custom_roles:)" + } + } + } + } + } +} \ No newline at end of file diff --git a/fast/stages/2-networking/variables-fast.tf b/fast/stages/2-networking/variables-fast.tf index 5e8d0aa5f..dc0fdf608 100644 --- a/fast/stages/2-networking/variables-fast.tf +++ b/fast/stages/2-networking/variables-fast.tf @@ -14,15 +14,6 @@ * limitations under the License. */ -variable "automation" { - # tfdoc:variable:source 0-org-setup - description = "Automation resources created by the bootstrap stage." - type = object({ - outputs_bucket = string - }) - nullable = false -} - variable "billing_account" { # tfdoc:variable:source 0-org-setup description = "Billing account id." @@ -64,6 +55,14 @@ variable "organization" { nullable = false } +variable "perimeters" { + # tfdoc:variable:source 1-vpcsc + description = "Optional VPC-SC perimeter ids." + type = map(string) + nullable = false + default = {} +} + variable "prefix" { # tfdoc:variable:source 0-org-setup description = "Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants." @@ -90,6 +89,14 @@ variable "service_accounts" { default = {} } +variable "storage_buckets" { + # tfdoc:variable:source 0-org-setup + description = "Storage buckets created in the bootstrap stage." + type = map(string) + nullable = false + default = {} +} + variable "tag_keys" { # tfdoc:variable:source 0-org-setup description = "FAST-managed resource manager tag keys." diff --git a/fast/stages/2-networking/variables.tf b/fast/stages/2-networking/variables.tf index 883f524cb..47b47f910 100644 --- a/fast/stages/2-networking/variables.tf +++ b/fast/stages/2-networking/variables.tf @@ -17,13 +17,17 @@ variable "context" { description = "Context-specific interpolations." type = object({ - custom_roles = optional(map(string), {}) - folder_ids = optional(map(string), {}) - iam_principals = optional(map(string), {}) - locations = optional(map(string), {}) - project_ids = optional(map(string), {}) - tag_keys = optional(map(string), {}) - tag_values = optional(map(string), {}) + cidr_ranges_sets = optional(map(list(string)), {}) + custom_roles = optional(map(string), {}) + folder_ids = optional(map(string), {}) + kms_keys = optional(map(string), {}) + iam_principals = optional(map(string), {}) + locations = optional(map(string), {}) + project_ids = optional(map(string), {}) + storage_buckets = optional(map(string), {}) + tag_keys = optional(map(string), {}) + tag_values = optional(map(string), {}) + vpc_sc_perimeters = optional(map(string), {}) }) default = {} nullable = false @@ -46,12 +50,6 @@ variable "factories_config" { default = {} } -variable "outputs_location" { - description = "Path where tfvars files for the following stages are written. Leave empty to disable." - type = string - default = null -} - variable "universe" { # tfdoc:variable:source 0-org-setup description = "GCP universe where to deploy projects. The prefix will be prepended to the project id." diff --git a/fast/stages/2-security/main.tf b/fast/stages/2-security/main.tf index 3bcd564ec..c407cbc2f 100644 --- a/fast/stages/2-security/main.tf +++ b/fast/stages/2-security/main.tf @@ -41,7 +41,6 @@ locals { }, local._ctx.iam_principals ) - locations = local._ctx.locations perimeters = merge(var.perimeters, local._ctx.vpc_sc_perimeters) project_ids = merge(var.project_ids, local._ctx.project_ids) storage_buckets = merge(var.storage_buckets, local._ctx.storage_buckets) diff --git a/tests/fast/stages/s2_networking/ncc.tfvars b/tests/fast/stages/s2_networking/ncc.tfvars index 38ecbb82f..06b587ee0 100644 --- a/tests/fast/stages/s2_networking/ncc.tfvars +++ b/tests/fast/stages/s2_networking/ncc.tfvars @@ -32,6 +32,9 @@ service_accounts = { "iac-0/iac-pf-rw" = "iac-pf-rw@test.iam.gserviceaccount.com" "iac-0/iac-pf-ro" = "iac-pf-ro@test.iam.gserviceaccount.com" } +storage_buckets = { + "iac-0/iac-outputs" = "test" +} tag_values = { "environment/development" = "tagValues/12345" "environment/production" = "tagValues/12346" diff --git a/tests/fast/stages/s2_networking/ncc.yaml b/tests/fast/stages/s2_networking/ncc.yaml index 7c45c41d6..b634c983a 100644 --- a/tests/fast/stages/s2_networking/ncc.yaml +++ b/tests/fast/stages/s2_networking/ncc.yaml @@ -123,7 +123,7 @@ values: terraform_labels: goog-terraform-provisioned: "true" timeouts: null - google_storage_bucket_object.tfvars["1"]: + google_storage_bucket_object.tfvars[0]: bucket: test cache_control: null content_disposition: null @@ -141,7 +141,7 @@ values: source_md5hash: null temporary_hold: null timeouts: null - google_storage_bucket_object.version["1"]: + google_storage_bucket_object.version[0]: bucket: test cache_control: null content_disposition: null diff --git a/tests/fast/stages/s2_networking/nva.tfvars b/tests/fast/stages/s2_networking/nva.tfvars index 0b4d15f99..45d37181d 100644 --- a/tests/fast/stages/s2_networking/nva.tfvars +++ b/tests/fast/stages/s2_networking/nva.tfvars @@ -32,6 +32,9 @@ service_accounts = { "iac-0/iac-pf-rw" = "iac-pf-rw@test.iam.gserviceaccount.com" "iac-0/iac-pf-ro" = "iac-pf-ro@test.iam.gserviceaccount.com" } +storage_buckets = { + "iac-0/iac-outputs" = "test" +} tag_values = { "environment/development" = "tagValues/12345" "environment/production" = "tagValues/12346" diff --git a/tests/fast/stages/s2_networking/peerings.tfvars b/tests/fast/stages/s2_networking/simple.tfvars similarity index 96% rename from tests/fast/stages/s2_networking/peerings.tfvars rename to tests/fast/stages/s2_networking/simple.tfvars index 0345f7157..411d0a0f4 100644 --- a/tests/fast/stages/s2_networking/peerings.tfvars +++ b/tests/fast/stages/s2_networking/simple.tfvars @@ -32,6 +32,9 @@ service_accounts = { "iac-0/iac-pf-rw" = "iac-pf-rw@test.iam.gserviceaccount.com" "iac-0/iac-pf-ro" = "iac-pf-ro@test.iam.gserviceaccount.com" } +storage_buckets = { + "iac-0/iac-outputs" = "test" +} tag_values = { "environment/development" = "tagValues/12345" "environment/production" = "tagValues/12346" diff --git a/tests/fast/stages/s2_networking/peerings.yaml b/tests/fast/stages/s2_networking/simple.yaml similarity index 99% rename from tests/fast/stages/s2_networking/peerings.yaml rename to tests/fast/stages/s2_networking/simple.yaml index 789f496cf..cad7ef689 100644 --- a/tests/fast/stages/s2_networking/peerings.yaml +++ b/tests/fast/stages/s2_networking/simple.yaml @@ -77,7 +77,7 @@ values: project: fast-prod-net-core-0 region: europe-west8 timeouts: null - google_storage_bucket_object.tfvars["1"]: + google_storage_bucket_object.tfvars[0]: bucket: test cache_control: null content_disposition: null @@ -95,7 +95,7 @@ values: source_md5hash: null temporary_hold: null timeouts: null - google_storage_bucket_object.version["1"]: + google_storage_bucket_object.version[0]: bucket: test cache_control: null content_disposition: null diff --git a/tests/fast/stages/s2_networking/tftest.yaml b/tests/fast/stages/s2_networking/tftest.yaml index 709653eb6..6115c268c 100644 --- a/tests/fast/stages/s2_networking/tftest.yaml +++ b/tests/fast/stages/s2_networking/tftest.yaml @@ -15,7 +15,8 @@ module: fast/stages/2-networking tests: - peerings: + # peering is renamed to simple so as to trigger tflint + simple: ncc: nva: vpns: diff --git a/tests/fast/stages/s2_networking/vpns.tfvars b/tests/fast/stages/s2_networking/vpns.tfvars index 3f9585bd5..243983668 100644 --- a/tests/fast/stages/s2_networking/vpns.tfvars +++ b/tests/fast/stages/s2_networking/vpns.tfvars @@ -32,6 +32,9 @@ service_accounts = { "iac-0/iac-pf-rw" = "iac-pf-rw@test.iam.gserviceaccount.com" "iac-0/iac-pf-ro" = "iac-pf-ro@test.iam.gserviceaccount.com" } +storage_buckets = { + "iac-0/iac-outputs" = "test" +} tag_values = { "environment/development" = "tagValues/12345" "environment/production" = "tagValues/12346" diff --git a/tests/fast/stages/s2_networking/vpns.yaml b/tests/fast/stages/s2_networking/vpns.yaml index 457ac8c41..19ddf84bb 100644 --- a/tests/fast/stages/s2_networking/vpns.yaml +++ b/tests/fast/stages/s2_networking/vpns.yaml @@ -131,7 +131,7 @@ values: project: fast-prod-net-prod-0 region: europe-west8 timeouts: null - google_storage_bucket_object.tfvars["1"]: + google_storage_bucket_object.tfvars[0]: bucket: test cache_control: null content_disposition: null @@ -149,7 +149,7 @@ values: source_md5hash: null temporary_hold: null timeouts: null - google_storage_bucket_object.version["1"]: + google_storage_bucket_object.version[0]: bucket: test cache_control: null content_disposition: null