Skip to content

Commit

Permalink
Streamline environments variable across stages (#2688)
Browse files Browse the repository at this point in the history
* streamline environments variable across stages

* linting

* linting
  • Loading branch information
ludoo authored Nov 15, 2024
1 parent a6c0bad commit 31cb391
Show file tree
Hide file tree
Showing 42 changed files with 296 additions and 166 deletions.
56 changes: 28 additions & 28 deletions fast/stages/0-bootstrap/README.md

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions fast/stages/0-bootstrap/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,17 @@ locals {
tfvars_globals = {
billing_account = var.billing_account
groups = local.principals
environments = var.environments
locations = local.locations
organization = var.organization
prefix = var.prefix
environments = {
for k, v in var.environments :
k => merge(v, {
tag_name = (
v.tag_name != null ? v.tag_name : lower(replace(v.name, " ", "-"))
)
})
}
locations = local.locations
organization = var.organization
prefix = var.prefix
}
}

Expand Down
9 changes: 9 additions & 0 deletions fast/stages/0-bootstrap/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ variable "environments" {
type = map(object({
name = string
is_default = optional(bool, false)
tag_name = optional(string)
}))
nullable = false
default = {
Expand All @@ -113,6 +114,14 @@ variable "environments" {
])
error_message = "At least one environment should be marked as default."
}
validation {
condition = alltrue([
for k, v in var.environments : join(" ", regexall(
"[a-zA-Z][a-zA-Z0-9\\s-]+[a-zA-Z0-9]", v.name
)) == v.name
])
error_message = "Environment names can only contain letters numbers dashes or spaces."
}
}

variable "essential_contacts" {
Expand Down
30 changes: 15 additions & 15 deletions fast/stages/1-resman/README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions fast/stages/1-resman/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ locals {
# automation_resman_sa = try(
# data.google_client_openid_userinfo.provider_identity[0].email, null
# )
# tag values use descriptive names
gcs_storage_class = (
length(split("-", var.locations.gcs)) < 2
? "MULTI_REGIONAL"
Expand Down
8 changes: 4 additions & 4 deletions fast/stages/1-resman/organization.tf
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,20 @@ locals {
)
# environment tag values and their IAM bindings for stage 2 service accounts
environment_tag_values = {
for k, v in var.environment_names : v => {
for k, v in var.environments : v.tag_name => {
iam = merge(
# user-defined configuration
try(local.tags.environment.values[v].iam, {}),
try(local.tags.environment.values[v.tag_name].iam, {}),
# stage 2 service accounts
{
"roles/resourcemanager.tagUser" = distinct(concat(
try(local.tags.environment.values[v].iam["roles/resourcemanager.tagUser"], []),
try(local.tags.environment.values[v.tag_name].iam["roles/resourcemanager.tagUser"], []),
!var.fast_stage_2.project_factory.enabled ? [] : [module.pf-sa-rw[0].iam_email],
!var.fast_stage_2.networking.enabled ? [] : [module.net-sa-rw[0].iam_email],
!var.fast_stage_2.security.enabled ? [] : [module.sec-sa-rw[0].iam_email],
))
"roles/resourcemanager.tagViewer" = distinct(concat(
try(local.tags.environment.values[v].iam["roles/resourcemanager.tagViewer"], []),
try(local.tags.environment.values[v.tag_name].iam["roles/resourcemanager.tagViewer"], []),
!var.fast_stage_2.project_factory.enabled ? [] : [module.pf-sa-ro[0].iam_email],
!var.fast_stage_2.networking.enabled ? [] : [module.net-sa-ro[0].iam_email],
!var.fast_stage_2.security.enabled ? [] : [module.sec-sa-ro[0].iam_email],
Expand Down
5 changes: 2 additions & 3 deletions fast/stages/1-resman/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ locals {
local.top_level_service_accounts
)
tfvars = {
environment_names = var.environment_names
stage_config = merge(
{
for k, v in local.stage3 : k => {
Expand All @@ -50,14 +49,14 @@ locals {
short_name = v.short_name
# rw service accounts for stage 3s that need delegated IAM on stage 2s
iam_delegated_principals = {
for ek, ev in var.environment_names : ek => [
for ek, _ in var.environments : ek => [
for sk, sv in local.stage3 :
"serviceAccount:${local.stage_service_accounts[sk]}"
if sv.environment == ek && try(sv.stage2_iam[k].iam_admin_delegated, false)
]
}
iam_viewer_principals = {
for ek, ev in var.environment_names : ek => [
for ek, _ in var.environments : ek => [
for sk, sv in local.stage3 :
"serviceAccount:${local.stage_service_accounts["${sk}-r"]}"
if sv.environment == ek && try(sv.stage2_iam[k].iam_admin_delegated, false)
Expand Down
8 changes: 4 additions & 4 deletions fast/stages/1-resman/stage-2-networking.tf
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,10 @@ module "net-folder-prod" {
source = "../../../modules/folder"
count = local.net_use_env_folders ? 1 : 0
parent = module.net-folder[0].id
name = title(var.environment_names["prod"])
name = var.environments["prod"].name
tag_bindings = {
environment = try(
local.tag_values["${var.tag_names.environment}/${var.environment_names["prod"]}"].id,
local.tag_values["${var.tag_names.environment}/${var.environments["prod"].tag_name}"].id,
null
)
}
Expand All @@ -170,10 +170,10 @@ module "net-folder-dev" {
source = "../../../modules/folder"
count = local.net_use_env_folders ? 1 : 0
parent = module.net-folder[0].id
name = title(var.environment_names["dev"])
name = var.environments["dev"].name
tag_bindings = {
environment = try(
local.tag_values["${var.tag_names.environment}/${var.environment_names["dev"]}"].id,
local.tag_values["${var.tag_names.environment}/${var.environments["dev"].tag_name}"].id,
null
)
}
Expand Down
8 changes: 4 additions & 4 deletions fast/stages/1-resman/stage-2-security.tf
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ module "sec-folder-prod" {
source = "../../../modules/folder"
count = local.sec_use_env_folders ? 1 : 0
parent = module.sec-folder[0].id
name = title(var.environment_names["prod"])
name = var.environments["prod"].name
iam = {
# stage 3s service accounts
for role, attrs in local.sec_s3_iam.prod : role => [
Expand All @@ -133,7 +133,7 @@ module "sec-folder-prod" {
}
tag_bindings = {
environment = try(
local.tag_values["${var.tag_names.environment}/${var.environment_names["prod"]}"].id,
local.tag_values["${var.tag_names.environment}/${var.environments["prod"].tag_name}"].id,
null
)
}
Expand All @@ -143,7 +143,7 @@ module "sec-folder-dev" {
source = "../../../modules/folder"
count = local.sec_use_env_folders ? 1 : 0
parent = module.sec-folder[0].id
name = title(var.environment_names["dev"])
name = var.environments["dev"].name
iam = {
# stage 3s service accounts
for role, attrs in local.sec_s3_iam.dev : role => [
Expand All @@ -156,7 +156,7 @@ module "sec-folder-dev" {
}
tag_bindings = {
environment = try(
local.tag_values["${var.tag_names.environment}/${var.environment_names["dev"]}"].id,
local.tag_values["${var.tag_names.environment}/${var.environments["dev"].tag_name}"].id,
null
)
}
Expand Down
6 changes: 3 additions & 3 deletions fast/stages/1-resman/stage-3.tf
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ locals {
for sa, roles in try(v.organization_iam.sa_roles, []) : [
for role in roles : {
context = try(v.organization_iam.context_tag_value, "")
env = var.environment_names[v.environment]
env = var.environments[v.environment].tag_name
role = role
sa = sa
s3 = k
Expand All @@ -98,7 +98,7 @@ locals {
for s2, attrs in v.stage2_iam : [
for sa, roles in attrs.sa_roles : [
for role in roles : {
env = var.environment_names[v.environment]
env = var.environments[v.environment].tag_name
role = lookup(var.custom_roles, role, role)
sa = sa
s2 = s2
Expand Down Expand Up @@ -139,7 +139,7 @@ module "stage3-folder" {
iam_by_principals = each.value.folder_config.iam_by_principals
tag_bindings = merge(
{
environment = local.tag_values["environment/${var.environment_names[each.value.environment]}"].id
environment = local.tag_values["environment/${var.environments[each.value.environment].tag_name}"].id
},
{
for k, v in each.value.folder_config.tag_bindings : k => try(
Expand Down
17 changes: 17 additions & 0 deletions fast/stages/1-resman/variables-fast.tf
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,23 @@ variable "custom_roles" {
default = null
}

variable "environments" {
# tfdoc:variable:source 0-globals
description = "Environment names."
type = map(object({
name = string
tag_name = string
is_default = optional(bool, false)
}))
nullable = false
validation {
condition = anytrue([
for k, v in var.environments : v.is_default == true
])
error_message = "At least one environment should be marked as default."
}
}

variable "groups" {
# tfdoc:variable:source 0-bootstrap
# https://cloud.google.com/docs/enterprise/setup-checklist
Expand Down
12 changes: 0 additions & 12 deletions fast/stages/1-resman/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,6 @@
# defaults for variables marked with global tfdoc annotations, can be set via
# the tfvars file generated in stage 00 and stored in its outputs

variable "environment_names" {
description = "Long environment names."
type = object({
dev = string
prod = string
})
default = {
dev = "development"
prod = "production"
}
}

variable "factories_config" {
description = "Configuration for the resource factories or external data."
type = object({
Expand Down
Loading

0 comments on commit 31cb391

Please sign in to comment.