Skip to content

Commit 630e7f4

Browse files
ludookarpok78
authored andcommitted
Implement FAST stage add-ons, refactor netsec as add-on (GoogleCloudPlatform#2800)
* security fixes * change netsec to be a virtual stage in resman * remove netsec bits from security stage, leave CAs in place * netsec - security profile groups * export regions to networking tfvars * netsec - trust stores * netsec refactor, untested * netsec plan working * netsec apply * netsec apply errors * netsec diagram * update diagram * move addon stages to addons folder * remove top-level assets folder * deprecate and remove fast plugins * addon tests * dynamic addon providers and cicd, untested * stage 1 addons in stage 0, refactor stage 0 cicd * addons and cicd refactor in stage 0 with tests * refactor stage 0 cicd * readd removed block * small bootstrap cicd fixes * refactor stage 1 cicd * resman tests * remove plugins from networking tests * fix fast tests * ngfw addon outputs * try to fix unrelated tflint error in bootstrap * remove common tfvars from bootstrap tests to fix linter errors * tfdoc * minimal readmes and links fixes * tfdoc * trim down test inventories * fix plan test * tfdoc * allow configuring output files names * fix tls inspection after adding count to project module * comment fixes * tfdoc
1 parent 919cc4f commit 630e7f4

File tree

136 files changed

+2521
-2756
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+2521
-2756
lines changed

fast/README.md

+3-10
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,11 @@ FAST uses YAML-based factories to deploy subnets and firewall rules and, as its
3838

3939
One of our objectives with FAST is to provide a lightweight reference design for the IaC repositories, and a built-in implementation for running our code in automated pipelines. Our CI/CD approach leverages [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation), and provides sample workflow configurations for several major providers. Refer to the [CI/CD section in the bootstrap stage](./stages/0-bootstrap/README.md#cicd) for more details. We also provide separate [optional small stages](./extras/) to help you configure your CI/CD provider.
4040

41+
<!-- TODO: move CI/CD documentation to its own file -->
42+
4143
### Multitenant organizations
4244

43-
FAST has built-in support for multitenancy implemented in [an optional stage 1](./stages/1-tenant-factory/). Tenants can optionally be created with FAST compatibility, allowing them independent use of stages 1+ in their own context.
45+
FAST has built-in support for multitenancy implemented in [an add-on stage](./addons/1-resman-tenants/). Tenants can optionally be created with FAST compatibility, allowing them independent use of stages 1+ in their own context.
4446

4547
The following diagram is a high-level overview of stages used with multitenancy.
4648

@@ -64,12 +66,3 @@ Since we expect users to customize FAST to their specific needs, we strive to ma
6466
We also recognize that FAST users don't need all of its features. Therefore, you don't need to use our project factory or our GKE implementation if you don't want to. Instead, remove those stages or pieces of code and keep what suits you.
6567

6668
Those familiar with Python will note that FAST follows many of the maxims in the [Zen of Python](https://www.python.org/dev/peps/pep-0020/#id2).
67-
68-
## Roadmap
69-
70-
Besides the features already described, FAST also includes:
71-
72-
- Stage to deploy environment-specific multitenant GKE clusters following Google's best practices
73-
- Stage to deploy a fully featured data platform
74-
- Reference implementation to use FAST in CI/CD pipelines
75-
- Static policy enforcement (planned)

fast/stages/1-tenant-factory/README.md renamed to fast/addons/1-resman-tenants/README.md

+19-17
Large diffs are not rendered by default.

fast/stages/1-tenant-factory/main.tf renamed to fast/addons/1-resman-tenants/main.tf

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616

1717
locals {
18+
default_environment = [
19+
for k, v in var.environments : v if v.is_default == true
20+
][0]
1821
tenants = {
1922
for k, v in var.tenant_configs : k => merge(v, {
2023
billing_account = merge(v.billing_account, {

fast/stages/1-tenant-factory/outputs-files.tf renamed to fast/addons/1-resman-tenants/outputs-files.tf

+7-7
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ resource "local_file" "providers-simple" {
2121
for k, v in local.tenants : k => local.tenant_data[k]
2222
}
2323
file_permission = "0644"
24-
filename = "${try(pathexpand(var.outputs_location), "")}/providers/tenant-${each.key}.tf"
24+
filename = "${try(pathexpand(var.outputs_location), "")}/providers/${var.names.output_files_prefix}-${each.key}.tf"
2525
content = templatefile(local._tpl_providers, {
2626
backend_extra = null
2727
bucket = each.value.gcs_bucket
@@ -35,21 +35,21 @@ resource "local_file" "tfvars-simple" {
3535
for k, v in local.tenants : k => local.tenant_data[k]
3636
}
3737
file_permission = "0644"
38-
filename = "${try(pathexpand(var.outputs_location), "")}/tfvars/tenant-${each.key}.auto.tfvars.json"
38+
filename = "${try(pathexpand(var.outputs_location), "")}/tfvars/${var.names.output_files_prefix}-${each.key}.auto.tfvars.json"
3939
content = jsonencode(each.value)
4040
}
4141

4242
resource "local_file" "providers" {
4343
for_each = var.outputs_location == null ? {} : local.tenant_providers
4444
file_permission = "0644"
45-
filename = "${try(pathexpand(var.outputs_location), "")}/tenants/${each.key}/providers/1-resman-providers.tf"
45+
filename = "${try(pathexpand(var.outputs_location), "")}/${var.names.output_files_prefix}/${each.key}/providers/1-resman-providers.tf"
4646
content = try(each.value, null)
4747
}
4848

4949
resource "local_file" "providers-r" {
5050
for_each = var.outputs_location == null ? {} : local.tenant_providers_r
5151
file_permission = "0644"
52-
filename = "${try(pathexpand(var.outputs_location), "")}/tenants/${each.key}/providers/1-resman-r-providers.tf"
52+
filename = "${try(pathexpand(var.outputs_location), "")}/${var.names.output_files_prefix}/${each.key}/providers/1-resman-r-providers.tf"
5353
content = try(each.value, null)
5454
}
5555

@@ -59,20 +59,20 @@ resource "local_file" "tfvars" {
5959
for k, v in local.tenant_tfvars : k => v if var.outputs_location != null
6060
}
6161
file_permission = "0644"
62-
filename = "${try(pathexpand(var.outputs_location), "")}/tenants/${each.key}/tfvars/0-bootstrap.auto.tfvars.json"
62+
filename = "${try(pathexpand(var.outputs_location), "")}/${var.names.output_files_prefix}/${each.key}/tfvars/0-bootstrap.auto.tfvars.json"
6363
content = jsonencode(each.value)
6464
}
6565

6666
resource "local_file" "tfvars_globals" {
6767
for_each = var.outputs_location == null ? {} : local.tenant_globals
6868
file_permission = "0644"
69-
filename = "${try(pathexpand(var.outputs_location), "")}/tenants/${each.key}/tfvars/0-globals.auto.tfvars.json"
69+
filename = "${try(pathexpand(var.outputs_location), "")}/${var.names.output_files_prefix}/${each.key}/tfvars/0-globals.auto.tfvars.json"
7070
content = jsonencode(each.value)
7171
}
7272

7373
resource "local_file" "workflows" {
7474
for_each = var.outputs_location == null ? {} : local.tenant_cicd_workflows
7575
file_permission = "0644"
76-
filename = "${try(pathexpand(var.outputs_location), "")}/tenants/${each.key}/workflows/1-resman-workflow.yaml"
76+
filename = "${try(pathexpand(var.outputs_location), "")}/${var.names.output_files_prefix}/${each.key}/workflows/1-resman-workflow.yaml"
7777
content = try(each.value, null)
7878
}

fast/stages/1-tenant-factory/outputs-gcs.tf renamed to fast/addons/1-resman-tenants/outputs-gcs.tf

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ resource "google_storage_bucket_object" "providers-simple" {
2121
for k, v in local.tenants : k => local.tenant_data[k]
2222
}
2323
bucket = var.automation.outputs_bucket
24-
name = "providers/tenant-${each.key}.tf"
24+
name = "providers/${var.names.output_files_prefix}-${each.key}.tf"
2525
content = templatefile(local._tpl_providers, {
2626
backend_extra = null
2727
bucket = each.value.gcs_bucket
@@ -35,7 +35,7 @@ resource "google_storage_bucket_object" "tfvars-simple" {
3535
for k, v in local.tenants : k => local.tenant_data[k]
3636
}
3737
bucket = var.automation.outputs_bucket
38-
name = "tfvars/tenant-${each.key}.auto.tfvars.json"
38+
name = "tfvars/${var.names.output_files_prefix}-${each.key}.auto.tfvars.json"
3939
content = jsonencode(each.value)
4040
}
4141

fast/stages/1-tenant-factory/tenant-core.tf renamed to fast/addons/1-resman-tenants/tenant-core.tf

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module "tenant-core-logbucket" {
2525
for_each = local.tenants
2626
parent_type = "project"
2727
parent = var.logging.project_id
28-
id = "tn-${each.key}-audit"
28+
id = "${var.names.resource_short_name}-${each.key}-audit"
2929
location = var.locations.logging
3030
log_analytics = { enable = true }
3131
}
@@ -36,7 +36,7 @@ module "tenant-core-folder" {
3636
parent = local.root_node
3737
name = "${each.value.descriptive_name} Core"
3838
logging_sinks = {
39-
"tn-${each.key}-audit" = {
39+
"${var.names.resource_short_name}-${each.key}-audit" = {
4040
destination = module.tenant-core-logbucket[each.key].id
4141
filter = <<-FILTER
4242
log_id("cloudaudit.googleapis.com/activity") OR

fast/stages/1-tenant-factory/tenant-fast-automation.tf renamed to fast/addons/1-resman-tenants/tenant-fast-automation.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ locals {
2626
}
2727
fast_tenants = {
2828
for k, v in local._fast_tenants : k => merge(v, {
29-
stage_0_prefix = "${v.prefix}-prod"
29+
stage_0_prefix = "${v.prefix}-${local.default_environment.short_name}"
3030
principals = {
3131
for gk, gv in v.groups : gk => (
3232
can(regex("^[a-zA-Z]+:", gv))

fast/stages/1-tenant-factory/tenant-fast-cicd.tf renamed to fast/addons/1-resman-tenants/tenant-fast-cicd.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ module "automation-tf-cicd-r-sa" {
131131
source = "../../../modules/iam-service-account"
132132
for_each = local.cicd_repositories
133133
project_id = var.automation.project_id
134-
name = "tenant-${each.key}-1r"
134+
name = "${each.key}-1r"
135135
display_name = "Terraform CI/CD ${each.key} service account (read-only)."
136136
prefix = var.prefix
137137
iam = {

fast/stages/1-tenant-factory/tenant.tf renamed to fast/addons/1-resman-tenants/tenant.tf

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ module "tenant-sa" {
9797
source = "../../../modules/iam-service-account"
9898
for_each = local.tenants
9999
project_id = var.automation.project_id
100-
name = "tn-${each.key}-0"
100+
name = "${var.names.resource_short_name}-${each.key}-0"
101101
display_name = "Terraform tenant ${each.key} service account."
102102
prefix = var.prefix
103103
iam = {
@@ -114,7 +114,7 @@ module "tenant-gcs" {
114114
source = "../../../modules/gcs"
115115
for_each = local.tenants
116116
project_id = var.automation.project_id
117-
name = "tn-${each.key}-0"
117+
name = "${var.names.resource_short_name}-${each.key}-0"
118118
prefix = var.prefix
119119
location = each.value.locations.gcs
120120
versioning = true

fast/stages/1-tenant-factory/variables-fast.tf renamed to fast/addons/1-resman-tenants/variables-fast.tf

+18
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,24 @@ variable "custom_roles" {
6666
default = null
6767
}
6868

69+
variable "environments" {
70+
# tfdoc:variable:source 0-globals
71+
description = "Environment names."
72+
type = map(object({
73+
name = string
74+
short_name = string
75+
tag_name = string
76+
is_default = optional(bool, false)
77+
}))
78+
nullable = false
79+
validation {
80+
condition = anytrue([
81+
for k, v in var.environments : v.is_default == true
82+
])
83+
error_message = "At least one environment should be marked as default."
84+
}
85+
}
86+
6987
variable "groups" {
7088
# tfdoc:variable:source 0-bootstrap
7189
# https://cloud.google.com/docs/enterprise/setup-checklist

fast/stages/1-tenant-factory/variables.tf renamed to fast/addons/1-resman-tenants/variables.tf

+11
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@
1414
* limitations under the License.
1515
*/
1616

17+
# TODO: backport names variable from resman stage
18+
variable "names" {
19+
description = "Configuration for names used for resources and output files."
20+
type = object({
21+
output_files_prefix = optional(string, "2-resman-tenants")
22+
resource_short_name = optional(string, "tn")
23+
})
24+
nullable = false
25+
default = {}
26+
}
27+
1728
variable "outputs_location" {
1829
description = "Path where providers and tfvars files for the following stages are written. Leave empty to disable."
1930
type = string
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FAST_STAGE_DESCRIPTION="NGFW Enterprise networking add-on"
2+
FAST_STAGE_LEVEL=2
3+
FAST_STAGE_NAME=networking-ngfw
4+
FAST_STAGE_DEPS="0-globals 0-bootstrap 1-resman 2-networking"
5+
FAST_STAGE_OPTIONAL="2-security"

0 commit comments

Comments
 (0)