Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support domainless orgs in FAST #2086

Merged
merged 7 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fast/stages/0-bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ The `fast_features` variable consists of 4 toggles:
| name | description | type | required | default | producer |
|---|---|:---:|:---:|:---:|:---:|
| [billing_account](variables.tf#L17) | 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> | ✓ | | |
| [organization](variables.tf#L229) | 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> | ✓ | | |
| [organization](variables.tf#L229) | Organization details. | <code title="object&#40;&#123;&#10; id &#61; number&#10; domain &#61; optional&#40;string&#41;&#10; customer_id &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | |
| [prefix](variables.tf#L244) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | |
| [bootstrap_user](variables.tf#L27) | Email of the nominal user running this stage for the first time. | <code>string</code> | | <code>null</code> | |
| [cicd_repositories](variables.tf#L33) | CI/CD repository configuration. Identity providers reference keys in the `federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object&#40;&#123;&#10; bootstrap &#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; resman &#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> | |
Expand Down
35 changes: 19 additions & 16 deletions fast/stages/0-bootstrap/data/org-policies/compute.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,25 @@ compute.trustedImageProjects:
rules:
- allow:
values:
- "projects/centos-cloud"
- "projects/cos-cloud"
- "projects/debian-cloud"
- "projects/fedora-cloud"
- "projects/fedora-coreos-cloud"
- "projects/opensuse-cloud"
- "projects/rhel-cloud"
- "projects/rhel-sap-cloud"
- "projects/rocky-linux-cloud"
- "projects/suse-cloud"
- "projects/suse-byos-cloud"
- "projects/suse-sap-cloud"
- "projects/ubuntu-os-cloud"
- "projects/ubuntu-os-pro-cloud"
- "projects/windows-cloud"
- "projects/windows-sql-cloud"
- "is:projects/centos-cloud"
- "is:projects/cos-cloud"
- "is:projects/debian-cloud"
- "is:projects/fedora-cloud"
- "is:projects/fedora-coreos-cloud"
- "is:projects/opensuse-cloud"
- "is:projects/rhel-cloud"
- "is:projects/rhel-sap-cloud"
- "is:projects/rocky-linux-cloud"
- "is:projects/suse-cloud"
- "is:projects/suse-sap-cloud"
- "is:projects/ubuntu-os-cloud"
- "is:projects/ubuntu-os-pro-cloud"
- "is:projects/windows-cloud"
- "is:projects/windows-sql-cloud"
- "is:projects/confidential-vm-images"
- "is:projects/backupdr-images"
- "is:projects/deeplearning-platform-release"
- "is:projects/serverless-vpc-access-images"

# compute.disableInternetNetworkEndpointGroup:
# rules:
Expand Down
1 change: 0 additions & 1 deletion fast/stages/0-bootstrap/data/org-policies/serverless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ run.allowedIngress:
rules:
- allow:
values:
- is:internal
- is:internal-and-cloud-load-balancing
# run.allowedVPCEgress:
# rules:
Expand Down
2 changes: 1 addition & 1 deletion fast/stages/0-bootstrap/organization-iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ locals {
"roles/billing.creator"
]
# domain IAM bindings
iam_domain_bindings = {
iam_domain_bindings = var.organization.domain == null ? {} : {
"domain:${var.organization.domain}" = {
authoritative = ["roles/browser"]
additive = []
Expand Down
80 changes: 48 additions & 32 deletions fast/stages/0-bootstrap/organization.tf
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ locals {
]
])
drs_domains = concat(
[var.organization.customer_id],
var.organization.customer_id == null ? [] : [var.organization.customer_id],
var.org_policies_config.constraints.allowed_policy_member_domains
)
drs_tag_name = "${var.organization.id}/${var.org_policies_config.tag_name}"
Expand Down Expand Up @@ -104,26 +104,28 @@ locals {
iam_roles_additive = distinct([
for k, v in local._iam_bindings_additive : v.role
])
# import org policies only when not using bootstrap user
import_org_policies = var.org_policies_config.import_defaults && var.bootstrap_user != null
}

# TODO: add a check block to ensure our custom roles exist in the factory files

# import org policy constraints enabled by default in new orgs since February 2024
import {
for_each = !local.import_org_policies ? toset([]) : toset([
"compute.requireOsLogin",
"compute.skipDefaultNetworkCreation",
"compute.vmExternalIpAccess",
"iam.allowedPolicyMemberDomains",
"iam.automaticIamGrantsForDefaultServiceAccounts",
"iam.disableServiceAccountKeyCreation",
"iam.disableServiceAccountKeyUpload",
"sql.restrictAuthorizedNetworks",
"sql.restrictPublicIp",
"storage.uniformBucketLevelAccess",
])
for_each = (
!var.org_policies_config.import_defaults || var.bootstrap_user != null
? toset([])
: toset([
"compute.requireOsLogin",
"compute.skipDefaultNetworkCreation",
"compute.vmExternalIpAccess",
"iam.allowedPolicyMemberDomains",
"iam.automaticIamGrantsForDefaultServiceAccounts",
"iam.disableServiceAccountKeyCreation",
"iam.disableServiceAccountKeyUpload",
"sql.restrictAuthorizedNetworks",
"sql.restrictPublicIp",
"storage.uniformBucketLevelAccess",
])
)
id = "organizations/${var.organization.id}/policies/${each.key}"
to = module.organization.google_org_policy_policy.default[each.key]
}
Expand Down Expand Up @@ -151,34 +153,48 @@ module "organization" {
var.iam_bindings_additive
)
# delegated role grant for resource manager service account
iam_bindings = {
organization_iam_admin_conditional = {
members = [module.automation-tf-resman-sa.iam_email]
role = module.organization.custom_role_id["organization_iam_admin"]
condition = {
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", concat(
[
iam_bindings = merge(
{
organization_iam_admin_conditional = {
members = [module.automation-tf-resman-sa.iam_email]
role = module.organization.custom_role_id["organization_iam_admin"]
condition = {
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", [
"roles/accesscontextmanager.policyAdmin",
"roles/compute.orgFirewallPolicyAdmin",
"roles/compute.xpnAdmin",
"roles/orgpolicy.policyAdmin",
"roles/orgpolicy.policyViewer",
"roles/resourcemanager.organizationViewer",
module.organization.custom_role_id["tenant_network_admin"]
],
local.billing_mode == "org" ? [
]))
)
title = "automation_sa_delegated_grants"
description = "Automation service account delegated grants."
}
}
},
local.billing_mode != "org" ? {} : {
organization_billing_conditional = {
members = [module.automation-tf-resman-sa.iam_email]
role = module.organization.custom_role_id["organization_iam_admin"]
condition = {
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", [
"roles/billing.admin",
"roles/billing.costsManager",
"roles/billing.user",
] : []
)))
)
title = "automation_sa_delegated_grants"
description = "Automation service account delegated grants."
]))
)
title = "automation_sa_delegated_grants"
description = "Automation service account delegated grants."
}
}
}
}
)
custom_roles = var.custom_roles
factories_config = {
custom_roles = var.factories_config.custom_roles
Expand Down
4 changes: 2 additions & 2 deletions fast/stages/0-bootstrap/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,9 @@ variable "org_policies_config" {
variable "organization" {
description = "Organization details."
type = object({
domain = string
id = number
customer_id = string
domain = optional(string)
customer_id = optional(string)
})
}

Expand Down
4 changes: 2 additions & 2 deletions fast/stages/1-resman/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ This is an example that shows how to populate the relevant variables.
```tfvars
tenants = {
tn0 = {
admin_group_email = "[email protected]"
admin_principal = "group:[email protected]"
descriptive_name = "Tenant 0"
# an optional billing account and org can be specified for the tenant
organization = {
Expand All @@ -264,7 +264,7 @@ tenants = {
}
}
tnq = {
admin_group_email = "[email protected]"
admin_principal = "group:[email protected]"
descriptive_name = "Tenant 1"
}
}
Expand Down
4 changes: 2 additions & 2 deletions fast/stages/1-resman/branch-security.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ module "branch-security-folder" {
"roles/resourcemanager.folderAdmin" = [module.branch-security-sa.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-security-sa.iam_email]
# read-only (plan) automation service account
"roles/viewer" = [module.branch-network-r-sa.iam_email]
"roles/resourcemanager.folderViewer" = [module.branch-network-r-sa.iam_email]
"roles/viewer" = [module.branch-security-r-sa.iam_email]
"roles/resourcemanager.folderViewer" = [module.branch-security-r-sa.iam_email]
}
tag_bindings = {
context = try(
Expand Down
2 changes: 1 addition & 1 deletion fast/stages/1-resman/branch-tenants.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
locals {
tenant_iam = {
for k, v in var.tenants : k => [
"group:${v.admin_group_email}",
v.admin_principal,
module.tenant-self-iac-sa[k].iam_email
]
}
Expand Down
4 changes: 2 additions & 2 deletions fast/stages/1-resman/organization-iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,13 @@ locals {
},
{
for k, v in var.tenants : "org-viewer-tenant_${k}_admin" => {
member = "group:${v.admin_group_email}"
member = v.admin_principal
role = "roles/resourcemanager.organizationViewer"
}
},
local.billing_mode != "org" ? {} : {
for k, v in var.tenants : "billing_user-tenant_${k}_billing_admin" => {
member = "group:${v.admin_group_email}"
member = v.admin_principal
role = "roles/billing.user"
}
},
Expand Down
6 changes: 3 additions & 3 deletions tests/fast/stages/s0_bootstrap/checklist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ values:
module.organization.google_organization_iam_binding.bindings["organization_iam_admin_conditional"]:
condition:
- description: Automation service account delegated grants.
expression: api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/accesscontextmanager.policyAdmin','roles/compute.orgFirewallPolicyAdmin','roles/compute.xpnAdmin','roles/orgpolicy.policyAdmin','roles/resourcemanager.organizationViewer','organizations/123456789012/roles/tenantNetworkAdmin','roles/billing.admin','roles/billing.costsManager','roles/billing.user'])
expression: api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/accesscontextmanager.policyAdmin','roles/compute.orgFirewallPolicyAdmin','roles/compute.xpnAdmin','roles/orgpolicy.policyAdmin','roles/orgpolicy.policyViewer','roles/resourcemanager.organizationViewer','organizations/123456789012/roles/tenantNetworkAdmin'])
title: automation_sa_delegated_grants
members:
- serviceAccount:[email protected]
Expand Down Expand Up @@ -363,7 +363,7 @@ counts:
google_logging_organization_sink: 3
google_logging_project_bucket_config: 3
google_org_policy_policy: 20
google_organization_iam_binding: 26
google_organization_iam_binding: 27
google_organization_iam_custom_role: 6
google_organization_iam_member: 35
google_project: 3
Expand All @@ -381,4 +381,4 @@ counts:
google_tags_tag_key: 1
google_tags_tag_value: 1
modules: 16
resources: 190
resources: 191
4 changes: 2 additions & 2 deletions tests/fast/stages/s0_bootstrap/simple.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ counts:
google_logging_organization_sink: 3
google_logging_project_bucket_config: 3
google_org_policy_policy: 20
google_organization_iam_binding: 26
google_organization_iam_binding: 27
google_organization_iam_custom_role: 6
google_organization_iam_member: 22
google_project: 3
Expand All @@ -61,7 +61,7 @@ counts:
google_tags_tag_value: 1
local_file: 7
modules: 15
resources: 181
resources: 182

outputs:
custom_roles:
Expand Down
Loading