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