Skip to content

Commit

Permalink
FAST MT: Readme updates and more prefix validation (#2305)
Browse files Browse the repository at this point in the history
This change documents the process of deploying FAST on a tenant-factory bootstrapped tenant.

It also fixes changes the validation logic for prefix as follows:

- 0-bootstrap: 9 chars or less
- 1-resman/1-tenant-factory: 9 chars or less if ran at org-level, else 11
- else 11

It also uniforms across all stages the variables.tf and variables-fast.tf breakdown.
  • Loading branch information
sruffilli authored May 24, 2024
1 parent 5068cd9 commit 11050c4
Show file tree
Hide file tree
Showing 33 changed files with 754 additions and 628 deletions.
16 changes: 0 additions & 16 deletions fast/stage-links.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,10 @@ case $STAGE_NAME in
PROVIDER="providers/0-bootstrap-providers.tf"
TFVARS=""
;;
"0-bootstrap-tenant")
MESSAGE="remember to set the prefix in the provider file"
PROVIDER_CMD=$CP_CMD
PROVIDER="providers/0-bootstrap-tenant-providers.tf"
TFVARS="tfvars/0-bootstrap.auto.tfvars.json
tfvars/1-resman.auto.tfvars.json"
;;
"1-resman" | "1-tenant-factory")
PROVIDER="providers/${STAGE_NAME}-providers.tf"
TFVARS="tfvars/0-bootstrap.auto.tfvars.json"
;;
"1-resman-tenant")
if [[ -z "$TENANT" ]]; then
echo "Please set a \$TENANT variable with the tenant shortname"
exit 1
fi
unset GLOBALS
PROVIDER="tenants/$TENANT/providers/1-resman-tenant-providers.tf"
TFVARS="tenants/$TENANT/tfvars/0-bootstrap-tenant.auto.tfvars.json"
;;
"2-networking"*)
if [[ -z "$TENANT" ]]; then
echo "# if this is a tenant stage, set a \$TENANT variable with the tenant shortname and run the command again"
Expand Down
5 changes: 4 additions & 1 deletion fast/stages/0-bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,15 @@ We are intentionally not supporting random prefix/suffixes for names, as that is
What is implemented here is a fairly common convention, composed of tokens ordered by relative importance:

- an organization-level static prefix less or equal to 9 characters (e.g. `myco` or `myco-gcp`)
- an optional tenant-level prefix, if using multitenant stages
- an optional tenant-level prefix, if using tenant factory
- an environment identifier (e.g. `prod`)
- a team/owner identifier (e.g. `sec` for Security)
- a context identifier (e.g. `core` or `kms`)
- an arbitrary identifier used to distinguish similar resources (e.g. `0`, `1`)

> [!WARNING]
> When using tenant factory, a tenant prefix will be automatically generated as `{prefix}-{tenant-shortname}`. The maximum length of such prefix must be 11 characters or less, which means that the longer org-level prefix you use, the less chars you'll have available for the `tenant-shortname`.

Tokens are joined by a `-` character, making it easy to separate the individual tokens visually, and to programmatically split them in billing exports to derive initial high-level groupings for cost attribution.

The convention is used in its full form only for specific resources with globally unique names (projects, GCS buckets). Other resources adopt a shorter version for legibility, as the full context can always be derived from their project.
Expand Down
10 changes: 5 additions & 5 deletions fast/stages/1-resman/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ A full reference of IAM roles managed by this stage [is available here](./IAM.md
| [billing_account](variables-fast.tf#L42) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | <code title="object&#40;&#123;&#10; id &#61; string&#10; is_org_level &#61; optional&#40;bool, true&#41;&#10; no_iam &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [logging](variables-fast.tf#L93) | Logging configuration for tenants. | <code title="object&#40;&#123;&#10; project_id &#61; string&#10; log_sinks &#61; optional&#40;map&#40;object&#40;&#123;&#10; filter &#61; string&#10; type &#61; string&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-tenant-factory</code> |
| [organization](variables-fast.tf#L106) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L158) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables-fast.tf#L124) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [cicd_repositories](variables.tf#L20) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object&#40;&#123;&#10; data_platform_dev &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; data_platform_prod &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; gke_dev &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; gke_prod &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; gcve_dev &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; gcve_prod &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; networking &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; project_factory_dev &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; project_factory_prod &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; security &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; type &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; identity_provider &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [custom_roles](variables-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | <code title="object&#40;&#123;&#10; gcve_network_admin &#61; string&#10; organization_admin_viewer &#61; string&#10; service_project_network_admin &#61; string&#10; storage_viewer &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [factories_config](variables.tf#L114) | Configuration for the resource factories or external data. | <code title="object&#40;&#123;&#10; checklist_data &#61; optional&#40;string&#41;&#10; org_policies &#61; optional&#40;string, &#34;data&#47;org-policies&#34;&#41;&#10; top_level_folders &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
Expand All @@ -276,10 +276,10 @@ A full reference of IAM roles managed by this stage [is available here](./IAM.md
| [groups](variables-fast.tf#L65) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object&#40;&#123;&#10; gcp-billing-admins &#61; optional&#40;string, &#34;gcp-billing-admins&#34;&#41;&#10; gcp-devops &#61; optional&#40;string, &#34;gcp-devops&#34;&#41;&#10; gcp-network-admins &#61; optional&#40;string, &#34;gcp-vpc-network-admins&#34;&#41;&#10; gcp-organization-admins &#61; optional&#40;string, &#34;gcp-organization-admins&#34;&#41;&#10; gcp-security-admins &#61; optional&#40;string, &#34;gcp-security-admins&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-bootstrap</code> |
| [locations](variables-fast.tf#L80) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object&#40;&#123;&#10; bq &#61; optional&#40;string, &#34;EU&#34;&#41;&#10; gcs &#61; optional&#40;string, &#34;EU&#34;&#41;&#10; logging &#61; optional&#40;string, &#34;global&#34;&#41;&#10; pubsub &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-bootstrap</code> |
| [outputs_location](variables.tf#L152) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
| [root_node](variables-fast.tf#L117) | Root node for the hierarchy, if running in tenant mode. | <code>string</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [tag_names](variables.tf#L169) | Customized names for resource management tags. | <code title="object&#40;&#123;&#10; context &#61; optional&#40;string, &#34;context&#34;&#41;&#10; environment &#61; optional&#40;string, &#34;environment&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [tags](variables.tf#L183) | Custom secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | <code title="map&#40;object&#40;&#123;&#10; description &#61; optional&#40;string, &#34;Managed by the Terraform organization module.&#34;&#41;&#10; iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; values &#61; optional&#40;map&#40;object&#40;&#123;&#10; description &#61; optional&#40;string, &#34;Managed by the Terraform organization module.&#34;&#41;&#10; iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; id &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [top_level_folders](variables.tf#L204) | Additional top-level folders. Keys are used for service account and bucket names, values implement the folders module interface with the addition of the 'automation' attribute. | <code title="map&#40;object&#40;&#123;&#10; name &#61; string&#10; automation &#61; optional&#40;object&#40;&#123;&#10; enable &#61; optional&#40;bool, true&#41;&#10; sa_impersonation_principals &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; contacts &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; firewall_policy &#61; optional&#40;map&#40;any&#41;&#41;&#10; logging_data_access &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; logging_exclusions &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; logging_sinks &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; iam &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; iam_bindings &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; iam_bindings_additive &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; iam_by_principals &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; org_policies &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [root_node](variables-fast.tf#L130) | Root node for the hierarchy, if running in tenant mode. | <code>string</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [tag_names](variables.tf#L158) | Customized names for resource management tags. | <code title="object&#40;&#123;&#10; context &#61; optional&#40;string, &#34;context&#34;&#41;&#10; environment &#61; optional&#40;string, &#34;environment&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [tags](variables.tf#L172) | Custom secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | <code title="map&#40;object&#40;&#123;&#10; description &#61; optional&#40;string, &#34;Managed by the Terraform organization module.&#34;&#41;&#10; iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; values &#61; optional&#40;map&#40;object&#40;&#123;&#10; description &#61; optional&#40;string, &#34;Managed by the Terraform organization module.&#34;&#41;&#10; iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; id &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [top_level_folders](variables.tf#L193) | Additional top-level folders. Keys are used for service account and bucket names, values implement the folders module interface with the addition of the 'automation' attribute. | <code title="map&#40;object&#40;&#123;&#10; name &#61; string&#10; automation &#61; optional&#40;object&#40;&#123;&#10; enable &#61; optional&#40;bool, true&#41;&#10; sa_impersonation_principals &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; contacts &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; firewall_policy &#61; optional&#40;map&#40;any&#41;&#41;&#10; logging_data_access &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; logging_exclusions &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; logging_sinks &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; iam &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; iam_bindings &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; iam_bindings_additive &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; iam_by_principals &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; org_policies &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |

## Outputs

Expand Down
13 changes: 13 additions & 0 deletions fast/stages/1-resman/variables-fast.tf
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,19 @@ variable "organization" {
nullable = false
}

check "prefix_validator" {
assert {
condition = (try(length(var.prefix), 0) < 10) || (try(length(var.prefix), 0) < 12 && var.root_node != null)
error_message = "var.prefix must be 9 characters or shorter for organizations, and 11 chars or shorter for tenants."
}
}

variable "prefix" {
# tfdoc:variable:source 0-bootstrap
description = "Prefix used for resources that need unique names. Use 9 characters or less."
type = string
}

variable "root_node" {
# tfdoc:variable:source 0-bootstrap
description = "Root node for the hierarchy, if running in tenant mode."
Expand Down
11 changes: 0 additions & 11 deletions fast/stages/1-resman/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,6 @@ variable "outputs_location" {
default = null
}

variable "prefix" {
# tfdoc:variable:source 0-bootstrap
description = "Prefix used for resources that need unique names. Use 9 characters or less."
type = string
# real maximum length is 11 but we need to keep at least 2 for tenants
validation {
condition = try(length(var.prefix), 0) < 10
error_message = "Use a maximum of 9 characters for prefix."
}
}

variable "tag_names" {
description = "Customized names for resource management tags."
type = object({
Expand Down
Loading

0 comments on commit 11050c4

Please sign in to comment.