Conditionally creates billing sink if the billing account is of type resource (#3130)

* updated billing.tf file to conditionally creates billing sink if the billing account resides out of org

* replace resources with modules

* replace individual iam resources with billing_iam local passed in the module

* update module name and path and move iam from local to module call

* update README.md

* Add log_bucket option to billing_account variable, and update billing account IAM assignments

* update 0-bootstrap README to reflect changes to billing account module

* Update current bootstrap tests to reflect the change to billing_account variable

* Create test for the case when billing account log bucket is created

* running fmt

---------

Co-authored-by: Ludovico Magnocavallo <ludomagno@google.com>
This commit is contained in:
Ali-Aburub
2025-07-21 18:09:36 +03:00
committed by GitHub
parent eae95187e5
commit ae6b3ee18d
8 changed files with 2279 additions and 51 deletions

View File

@@ -662,7 +662,7 @@ FAST defines a simple mechanism to extend stage functionality via the use of [ad
| name | description | modules | resources |
|---|---|---|---|
| [automation.tf](./automation.tf) | Automation project and resources. | <code>gcs</code> · <code>iam-service-account</code> · <code>project</code> | |
| [billing.tf](./billing.tf) | Billing export project and dataset. | <code>bigquery-dataset</code> · <code>project</code> | <code>google_billing_account_iam_member</code> |
| [billing.tf](./billing.tf) | Billing export project and dataset. | <code>bigquery-dataset</code> · <code>billing-account</code> · <code>logging-bucket</code> · <code>project</code> | |
| [cicd.tf](./cicd.tf) | CI/CD locals and resources. | <code>iam-service-account</code> | |
| [identity-providers-wfif-defs.tf](./identity-providers-wfif-defs.tf) | Workforce Identity provider definitions. | | |
| [identity-providers-wfif.tf](./identity-providers-wfif.tf) | Workforce Identity Federation provider definitions. | | <code>google_iam_workforce_pool</code> · <code>google_iam_workforce_pool_provider</code> |
@@ -683,29 +683,29 @@ FAST defines a simple mechanism to extend stage functionality via the use of [ad
| 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; force_create &#61; optional&#40;object&#40;&#123;&#10; dataset &#61; optional&#40;bool, false&#41;&#10; project &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#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#L281) | 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#L296) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | |
| [bootstrap_user](variables.tf#L38) | Email of the nominal user running this stage for the first time. | <code>string</code> | | <code>null</code> | |
| [cicd_config](variables.tf#L44) | 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; identity_provider &#61; string&#10; repository &#61; object&#40;&#123;&#10; name &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; type &#61; optional&#40;string, &#34;github&#34;&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#41;&#10; resman &#61; optional&#40;object&#40;&#123;&#10; identity_provider &#61; string&#10; repository &#61; object&#40;&#123;&#10; name &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; type &#61; optional&#40;string, &#34;github&#34;&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#41;&#10; vpcsc &#61; optional&#40;object&#40;&#123;&#10; identity_provider &#61; string&#10; repository &#61; object&#40;&#123;&#10; name &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; type &#61; optional&#40;string, &#34;github&#34;&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [custom_roles](variables.tf#L85) | Map of role names => list of permissions to additionally create at the organization level. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [environments](variables.tf#L92) | Environment names. When not defined, short name is set to the key and tag name to lower(name). | <code title="map&#40;object&#40;&#123;&#10; name &#61; string&#10; is_default &#61; optional&#40;bool, false&#41;&#10; short_name &#61; optional&#40;string&#41;&#10; tag_name &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code title="&#123;&#10; dev &#61; &#123;&#10; name &#61; &#34;Development&#34;&#10; &#125;&#10; prod &#61; &#123;&#10; name &#61; &#34;Production&#34;&#10; is_default &#61; true&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [essential_contacts](variables.tf#L132) | Email used for essential contacts, unset if null. | <code>string</code> | | <code>null</code> | |
| [factories_config](variables.tf#L138) | Configuration for the resource factories or external data. | <code title="object&#40;&#123;&#10; custom_constraints &#61; optional&#40;string, &#34;data&#47;custom-constraints&#34;&#41;&#10; custom_roles &#61; optional&#40;string, &#34;data&#47;custom-roles&#34;&#41;&#10; org_policies &#61; optional&#40;string, &#34;data&#47;org-policies&#34;&#41;&#10; org_policies_iac &#61; optional&#40;string, &#34;data&#47;org-policies-iac&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [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; force_create &#61; optional&#40;object&#40;&#123;&#10; dataset &#61; optional&#40;bool, false&#41;&#10; project &#61; optional&#40;bool, false&#41;&#10; log_bucket &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#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#L282) | 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#L297) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | |
| [bootstrap_user](variables.tf#L39) | Email of the nominal user running this stage for the first time. | <code>string</code> | | <code>null</code> | |
| [cicd_config](variables.tf#L45) | 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; identity_provider &#61; string&#10; repository &#61; object&#40;&#123;&#10; name &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; type &#61; optional&#40;string, &#34;github&#34;&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#41;&#10; resman &#61; optional&#40;object&#40;&#123;&#10; identity_provider &#61; string&#10; repository &#61; object&#40;&#123;&#10; name &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; type &#61; optional&#40;string, &#34;github&#34;&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#41;&#10; vpcsc &#61; optional&#40;object&#40;&#123;&#10; identity_provider &#61; string&#10; repository &#61; object&#40;&#123;&#10; name &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; type &#61; optional&#40;string, &#34;github&#34;&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [custom_roles](variables.tf#L86) | Map of role names => list of permissions to additionally create at the organization level. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [environments](variables.tf#L93) | Environment names. When not defined, short name is set to the key and tag name to lower(name). | <code title="map&#40;object&#40;&#123;&#10; name &#61; string&#10; is_default &#61; optional&#40;bool, false&#41;&#10; short_name &#61; optional&#40;string&#41;&#10; tag_name &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code title="&#123;&#10; dev &#61; &#123;&#10; name &#61; &#34;Development&#34;&#10; &#125;&#10; prod &#61; &#123;&#10; name &#61; &#34;Production&#34;&#10; is_default &#61; true&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [essential_contacts](variables.tf#L133) | Email used for essential contacts, unset if null. | <code>string</code> | | <code>null</code> | |
| [factories_config](variables.tf#L139) | Configuration for the resource factories or external data. | <code title="object&#40;&#123;&#10; custom_constraints &#61; optional&#40;string, &#34;data&#47;custom-constraints&#34;&#41;&#10; custom_roles &#61; optional&#40;string, &#34;data&#47;custom-roles&#34;&#41;&#10; org_policies &#61; optional&#40;string, &#34;data&#47;org-policies&#34;&#41;&#10; org_policies_iac &#61; optional&#40;string, &#34;data&#47;org-policies-iac&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [fast_addon](variables-addons.tf#L17) | FAST addons configurations for stages 1. Keys are used as short names for the add-on resources. | <code title="map&#40;object&#40;&#123;&#10; parent_stage &#61; string&#10; cicd_config &#61; optional&#40;object&#40;&#123;&#10; identity_provider &#61; string&#10; repository &#61; object&#40;&#123;&#10; name &#61; string&#10; branch &#61; optional&#40;string&#41;&#10; type &#61; optional&#40;string, &#34;github&#34;&#41;&#10; &#125;&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [groups](variables.tf#L150) | 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-secops-admins &#61; optional&#40;string, &#34;gcp-security-admins&#34;&#41;&#10; gcp-security-admins &#61; optional&#40;string, &#34;gcp-security-admins&#34;&#41;&#10; gcp-support &#61; optional&#40;string, &#34;gcp-devops&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [iam](variables.tf#L167) | Organization-level custom IAM settings in role => [principal] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [iam_bindings_additive](variables.tf#L174) | Organization-level custom additive IAM bindings. Keys are arbitrary. | <code title="map&#40;object&#40;&#123;&#10; member &#61; string&#10; role &#61; string&#10; condition &#61; optional&#40;object&#40;&#123;&#10; expression &#61; string&#10; title &#61; string&#10; description &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [iam_by_principals](variables.tf#L189) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [locations](variables.tf#L196) | 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> | |
| [log_sinks](variables.tf#L210) | Org-level log sinks, in name => {type, filter} format. | <code title="map&#40;object&#40;&#123;&#10; filter &#61; string&#10; type &#61; string&#10; disabled &#61; optional&#40;bool, false&#41;&#10; exclusions &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code title="&#123;&#10; audit-logs &#61; &#123;&#10; filter &#61; &#60;&#60;-FILTER&#10; log_id&#40;&#34;cloudaudit.googleapis.com&#47;activity&#34;&#41; OR&#10; log_id&#40;&#34;cloudaudit.googleapis.com&#47;system_event&#34;&#41; OR&#10; log_id&#40;&#34;cloudaudit.googleapis.com&#47;policy&#34;&#41; OR&#10; log_id&#40;&#34;cloudaudit.googleapis.com&#47;access_transparency&#34;&#41;&#10; FILTER&#10; type &#61; &#34;logging&#34;&#10; &#125;&#10; iam &#61; &#123;&#10; filter &#61; &#60;&#60;-FILTER&#10; protoPayload.serviceName&#61;&#34;iamcredentials.googleapis.com&#34; OR&#10; protoPayload.serviceName&#61;&#34;iam.googleapis.com&#34; OR&#10; protoPayload.serviceName&#61;&#34;sts.googleapis.com&#34;&#10; FILTER&#10; type &#61; &#34;logging&#34;&#10; &#125;&#10; vpc-sc &#61; &#123;&#10; filter &#61; &#60;&#60;-FILTER&#10; protoPayload.metadata.&#64;type&#61;&#34;type.googleapis.com&#47;google.cloud.audit.VpcServiceControlAuditMetadata&#34;&#10; FILTER&#10; type &#61; &#34;logging&#34;&#10; &#125;&#10; workspace-audit-logs &#61; &#123;&#10; filter &#61; &#60;&#60;-FILTER&#10; protoPayload.serviceName&#61;&#34;admin.googleapis.com&#34; OR&#10; protoPayload.serviceName&#61;&#34;cloudidentity.googleapis.com&#34; OR&#10; protoPayload.serviceName&#61;&#34;login.googleapis.com&#34;&#10; FILTER&#10; type &#61; &#34;logging&#34;&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [org_policies_config](variables.tf#L266) | Organization policies customization. | <code title="object&#40;&#123;&#10; iac_policy_member_domains &#61; optional&#40;list&#40;string&#41;&#41;&#10; import_defaults &#61; optional&#40;bool, false&#41;&#10; tag_name &#61; optional&#40;string, &#34;org-policies&#34;&#41;&#10; tag_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;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [outputs_location](variables.tf#L290) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
| [project_parent_ids](variables.tf#L305) | Optional parents for projects created here in folders/nnnnnnn format. Null values will use the organization as parent. | <code title="object&#40;&#123;&#10; automation &#61; optional&#40;string&#41;&#10; billing &#61; optional&#40;string&#41;&#10; logging &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [resource_names](variables.tf#L316) | Resource names overrides for specific resources. Prefix is always set via code, except where noted in the variable type. | <code title="object&#40;&#123;&#10; bq-billing &#61; optional&#40;string, &#34;billing_export&#34;&#41;&#10; bq-logs &#61; optional&#40;string, &#34;logs&#34;&#41;&#10; gcs-bootstrap &#61; optional&#40;string, &#34;prod-iac-core-bootstrap-0&#34;&#41;&#10; gcs-logs &#61; optional&#40;string, &#34;prod-logs&#34;&#41;&#10; gcs-outputs &#61; optional&#40;string, &#34;prod-iac-core-outputs-0&#34;&#41;&#10; gcs-resman &#61; optional&#40;string, &#34;prod-iac-core-resman-0&#34;&#41;&#10; gcs-vpcsc &#61; optional&#40;string, &#34;prod-iac-core-vpcsc-0&#34;&#41;&#10; project-automation &#61; optional&#40;string, &#34;prod-iac-core-0&#34;&#41;&#10; project-billing &#61; optional&#40;string, &#34;prod-billing-exp-0&#34;&#41;&#10; project-logs &#61; optional&#40;string, &#34;prod-audit-logs-0&#34;&#41;&#10; pubsub-logs_template &#61; optional&#40;string, &#34;&#36;&#36;&#123;key&#125;&#34;&#41;&#10; sa-bootstrap &#61; optional&#40;string, &#34;prod-bootstrap-0&#34;&#41;&#10; sa-bootstrap_ro &#61; optional&#40;string, &#34;prod-bootstrap-0r&#34;&#41;&#10; sa-cicd_template &#61; optional&#40;string, &#34;prod-&#36;&#36;&#123;key&#125;-1&#34;&#41;&#10; sa-cicd_template_ro &#61; optional&#40;string, &#34;prod-&#36;&#36;&#123;key&#125;-1r&#34;&#41;&#10; sa-resman &#61; optional&#40;string, &#34;prod-resman-0&#34;&#41;&#10; sa-resman_ro &#61; optional&#40;string, &#34;prod-resman-0r&#34;&#41;&#10; sa-vpcsc &#61; optional&#40;string, &#34;prod-vpcsc-0&#34;&#41;&#10; sa-vpcsc_ro &#61; optional&#40;string, &#34;prod-vpcsc-0r&#34;&#41;&#10; wf-bootstrap &#61; optional&#40;string, &#34;&#36;&#36;&#123;prefix&#125;-bootstrap&#34;&#41;&#10; wf-provider_template &#61; optional&#40;string, &#34;&#36;&#36;&#123;prefix&#125;-bootstrap-&#36;&#36;&#123;key&#125;&#34;&#41;&#10; wif-bootstrap &#61; optional&#40;string, &#34;&#36;&#36;&#123;prefix&#125;-bootstrap&#34;&#41;&#10; wif-provider_template &#61; optional&#40;string, &#34;&#36;&#36;&#123;prefix&#125;-bootstrap-&#36;&#36;&#123;key&#125;&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [universe](variables.tf#L348) | Target GCP universe. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; prefix &#61; string&#10; unavailable_services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [workforce_identity_providers](variables.tf#L358) | Workforce Identity Federation pools. | <code title="map&#40;object&#40;&#123;&#10; attribute_condition &#61; optional&#40;string&#41;&#10; issuer &#61; string&#10; display_name &#61; string&#10; description &#61; string&#10; disabled &#61; optional&#40;bool, false&#41;&#10; saml &#61; optional&#40;object&#40;&#123;&#10; idp_metadata_xml &#61; string&#10; &#125;&#41;, null&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [workload_identity_providers](variables.tf#L374) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | <code title="map&#40;object&#40;&#123;&#10; attribute_condition &#61; optional&#40;string&#41;&#10; issuer &#61; string&#10; custom_settings &#61; optional&#40;object&#40;&#123;&#10; issuer_uri &#61; optional&#40;string&#41;&#10; audiences &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; jwks_json &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [groups](variables.tf#L151) | 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-secops-admins &#61; optional&#40;string, &#34;gcp-security-admins&#34;&#41;&#10; gcp-security-admins &#61; optional&#40;string, &#34;gcp-security-admins&#34;&#41;&#10; gcp-support &#61; optional&#40;string, &#34;gcp-devops&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [iam](variables.tf#L168) | Organization-level custom IAM settings in role => [principal] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [iam_bindings_additive](variables.tf#L175) | Organization-level custom additive IAM bindings. Keys are arbitrary. | <code title="map&#40;object&#40;&#123;&#10; member &#61; string&#10; role &#61; string&#10; condition &#61; optional&#40;object&#40;&#123;&#10; expression &#61; string&#10; title &#61; string&#10; description &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [iam_by_principals](variables.tf#L190) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [locations](variables.tf#L197) | 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> | |
| [log_sinks](variables.tf#L211) | Org-level log sinks, in name => {type, filter} format. | <code title="map&#40;object&#40;&#123;&#10; filter &#61; string&#10; type &#61; string&#10; disabled &#61; optional&#40;bool, false&#41;&#10; exclusions &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code title="&#123;&#10; audit-logs &#61; &#123;&#10; filter &#61; &#60;&#60;-FILTER&#10; log_id&#40;&#34;cloudaudit.googleapis.com&#47;activity&#34;&#41; OR&#10; log_id&#40;&#34;cloudaudit.googleapis.com&#47;system_event&#34;&#41; OR&#10; log_id&#40;&#34;cloudaudit.googleapis.com&#47;policy&#34;&#41; OR&#10; log_id&#40;&#34;cloudaudit.googleapis.com&#47;access_transparency&#34;&#41;&#10; FILTER&#10; type &#61; &#34;logging&#34;&#10; &#125;&#10; iam &#61; &#123;&#10; filter &#61; &#60;&#60;-FILTER&#10; protoPayload.serviceName&#61;&#34;iamcredentials.googleapis.com&#34; OR&#10; protoPayload.serviceName&#61;&#34;iam.googleapis.com&#34; OR&#10; protoPayload.serviceName&#61;&#34;sts.googleapis.com&#34;&#10; FILTER&#10; type &#61; &#34;logging&#34;&#10; &#125;&#10; vpc-sc &#61; &#123;&#10; filter &#61; &#60;&#60;-FILTER&#10; protoPayload.metadata.&#64;type&#61;&#34;type.googleapis.com&#47;google.cloud.audit.VpcServiceControlAuditMetadata&#34;&#10; FILTER&#10; type &#61; &#34;logging&#34;&#10; &#125;&#10; workspace-audit-logs &#61; &#123;&#10; filter &#61; &#60;&#60;-FILTER&#10; protoPayload.serviceName&#61;&#34;admin.googleapis.com&#34; OR&#10; protoPayload.serviceName&#61;&#34;cloudidentity.googleapis.com&#34; OR&#10; protoPayload.serviceName&#61;&#34;login.googleapis.com&#34;&#10; FILTER&#10; type &#61; &#34;logging&#34;&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [org_policies_config](variables.tf#L267) | Organization policies customization. | <code title="object&#40;&#123;&#10; iac_policy_member_domains &#61; optional&#40;list&#40;string&#41;&#41;&#10; import_defaults &#61; optional&#40;bool, false&#41;&#10; tag_name &#61; optional&#40;string, &#34;org-policies&#34;&#41;&#10; tag_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;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [outputs_location](variables.tf#L291) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
| [project_parent_ids](variables.tf#L306) | Optional parents for projects created here in folders/nnnnnnn format. Null values will use the organization as parent. | <code title="object&#40;&#123;&#10; automation &#61; optional&#40;string&#41;&#10; billing &#61; optional&#40;string&#41;&#10; logging &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [resource_names](variables.tf#L317) | Resource names overrides for specific resources. Prefix is always set via code, except where noted in the variable type. | <code title="object&#40;&#123;&#10; bq-billing &#61; optional&#40;string, &#34;billing_export&#34;&#41;&#10; bq-logs &#61; optional&#40;string, &#34;logs&#34;&#41;&#10; gcs-bootstrap &#61; optional&#40;string, &#34;prod-iac-core-bootstrap-0&#34;&#41;&#10; gcs-logs &#61; optional&#40;string, &#34;prod-logs&#34;&#41;&#10; gcs-outputs &#61; optional&#40;string, &#34;prod-iac-core-outputs-0&#34;&#41;&#10; gcs-resman &#61; optional&#40;string, &#34;prod-iac-core-resman-0&#34;&#41;&#10; gcs-vpcsc &#61; optional&#40;string, &#34;prod-iac-core-vpcsc-0&#34;&#41;&#10; project-automation &#61; optional&#40;string, &#34;prod-iac-core-0&#34;&#41;&#10; project-billing &#61; optional&#40;string, &#34;prod-billing-exp-0&#34;&#41;&#10; project-logs &#61; optional&#40;string, &#34;prod-audit-logs-0&#34;&#41;&#10; pubsub-logs_template &#61; optional&#40;string, &#34;&#36;&#36;&#123;key&#125;&#34;&#41;&#10; sa-bootstrap &#61; optional&#40;string, &#34;prod-bootstrap-0&#34;&#41;&#10; sa-bootstrap_ro &#61; optional&#40;string, &#34;prod-bootstrap-0r&#34;&#41;&#10; sa-cicd_template &#61; optional&#40;string, &#34;prod-&#36;&#36;&#123;key&#125;-1&#34;&#41;&#10; sa-cicd_template_ro &#61; optional&#40;string, &#34;prod-&#36;&#36;&#123;key&#125;-1r&#34;&#41;&#10; sa-resman &#61; optional&#40;string, &#34;prod-resman-0&#34;&#41;&#10; sa-resman_ro &#61; optional&#40;string, &#34;prod-resman-0r&#34;&#41;&#10; sa-vpcsc &#61; optional&#40;string, &#34;prod-vpcsc-0&#34;&#41;&#10; sa-vpcsc_ro &#61; optional&#40;string, &#34;prod-vpcsc-0r&#34;&#41;&#10; wf-bootstrap &#61; optional&#40;string, &#34;&#36;&#36;&#123;prefix&#125;-bootstrap&#34;&#41;&#10; wf-provider_template &#61; optional&#40;string, &#34;&#36;&#36;&#123;prefix&#125;-bootstrap-&#36;&#36;&#123;key&#125;&#34;&#41;&#10; wif-bootstrap &#61; optional&#40;string, &#34;&#36;&#36;&#123;prefix&#125;-bootstrap&#34;&#41;&#10; wif-provider_template &#61; optional&#40;string, &#34;&#36;&#36;&#123;prefix&#125;-bootstrap-&#36;&#36;&#123;key&#125;&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [universe](variables.tf#L349) | Target GCP universe. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; prefix &#61; string&#10; unavailable_services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [workforce_identity_providers](variables.tf#L359) | Workforce Identity Federation pools. | <code title="map&#40;object&#40;&#123;&#10; attribute_condition &#61; optional&#40;string&#41;&#10; issuer &#61; string&#10; display_name &#61; string&#10; description &#61; string&#10; disabled &#61; optional&#40;bool, false&#41;&#10; saml &#61; optional&#40;object&#40;&#123;&#10; idp_metadata_xml &#61; string&#10; &#125;&#41;, null&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [workload_identity_providers](variables.tf#L375) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | <code title="map&#40;object&#40;&#123;&#10; attribute_condition &#61; optional&#40;string&#41;&#10; issuer &#61; string&#10; custom_settings &#61; optional&#40;object&#40;&#123;&#10; issuer_uri &#61; optional&#40;string&#41;&#10; audiences &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; jwks_json &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
## Outputs

View File

@@ -17,22 +17,41 @@
# tfdoc:file:description Billing export project and dataset.
locals {
# used here for convenience, in organization.tf members are explicit
billing_ext_admins = [
local.principals.gcp-billing-admins,
local.principals.gcp-organization-admins,
module.automation-tf-bootstrap-sa.iam_email,
module.automation-tf-resman-sa.iam_email
]
billing_ext_viewers = [
module.automation-tf-bootstrap-r-sa.iam_email,
module.automation-tf-resman-r-sa.iam_email
]
billing_mode = (
var.billing_account.no_iam
? null
: var.billing_account.is_org_level ? "org" : "resource"
)
_billing_iam_bindings = {
"roles/billing.admin" = [
local.principals.gcp-billing-admins,
local.principals.gcp-organization-admins,
module.automation-tf-bootstrap-sa.iam_email,
module.automation-tf-resman-sa.iam_email
],
"roles/billing.viewer" = [
module.automation-tf-bootstrap-r-sa.iam_email,
module.automation-tf-resman-r-sa.iam_email
],
"roles/logging.configWriter" = local.billing_mode == "org" || !var.billing_account.force_create.log_bucket ? [] : [
module.automation-tf-bootstrap-sa.iam_email
]
}
_billing_iam_bindings_add = flatten([for role, bindings in local._billing_iam_bindings : [
for member in bindings : {
member = member,
role = role
}
]])
billing_iam_bindings_additive = {
for b in local._billing_iam_bindings_add : "${b.role}-${b.member}" => {
member = b.member
role = b.role
}
}
}
# billing account in same org (IAM is in the organization.tf file)
@@ -81,20 +100,28 @@ module "billing-export-dataset" {
# standalone billing account
resource "google_billing_account_iam_member" "billing_ext_admin" {
for_each = toset(
local.billing_mode == "resource" ? local.billing_ext_admins : []
)
billing_account_id = var.billing_account.id
role = "roles/billing.admin"
member = each.key
module "billing-account-logbucket" {
source = "../../../modules/logging-bucket"
count = local.billing_mode == "resource" && var.billing_account.force_create.log_bucket ? 1 : 0
parent_type = "project"
parent = module.log-export-project.project_id
id = "billing-account"
location = local.locations.logging
log_analytics = { enable = true }
# org-level logging settings ready before we create any logging buckets
depends_on = [module.organization-logging]
}
resource "google_billing_account_iam_member" "billing_ext_viewer" {
for_each = toset(
local.billing_mode == "resource" ? local.billing_ext_viewers : []
)
billing_account_id = var.billing_account.id
role = "roles/billing.viewer"
member = each.key
}
module "billing-account" {
source = "../../../modules/billing-account"
count = local.billing_mode == "resource" ? 1 : 0
id = var.billing_account.id
iam_bindings_additive = local.billing_iam_bindings_additive
logging_sinks = !var.billing_account.force_create.log_bucket ? {} : {
billing_bucket_log_sink = {
destination = module.billing-account-logbucket[0].id
type = "logging"
description = "billing-account sink (Terraform-managed)."
}
}
}

View File

@@ -19,8 +19,9 @@ variable "billing_account" {
type = object({
id = string
force_create = optional(object({
dataset = optional(bool, false)
project = optional(bool, false)
dataset = optional(bool, false)
project = optional(bool, false)
log_bucket = optional(bool, false)
}), {})
is_org_level = optional(bool, true)
no_iam = optional(bool, false)

View File

@@ -2493,6 +2493,7 @@ outputs:
force_create:
dataset: false
project: false
log_bucket: false
id: 000000-111111-222222
is_org_level: true
no_iam: false

View File

@@ -0,0 +1,23 @@
billing_account = {
id = "000000-111111-222222"
is_org_level = false
force_create = {
dataset = true
project = true
log_bucket = true
}
}
essential_contacts = "gcp-organization-admins@fast.example.com"
groups = {
gcp-support = "group:gcp-support@example.com"
}
org_policies_config = {
import_defaults = false
}
organization = {
domain = "fast.example.com"
id = 123456789012
customer_id = "C00000000"
}
outputs_location = "/fast-config"
prefix = "fast"

File diff suppressed because it is too large Load Diff

View File

@@ -1604,6 +1604,7 @@ outputs:
force_create:
dataset: false
project: false
log_bucket: false
id: 000000-111111-222222
is_org_level: true
no_iam: false

View File

@@ -23,5 +23,8 @@ tests:
inventory:
- simple.yaml
- managed_org_policies.yaml
external_billing_account:
inventory:
- external_billing_account.yaml
iam_by_principals:
cicd: