Google Cloud Organization Module#
This module provides a foundation for setting up a Google Cloud Organization with proper infrastructure-as-code (IaC) management, audit logging, and folder structure. It creates the necessary management projects, storage buckets for Terraform state, audit logging configuration, and service accounts with appropriate permissions.
Compatibility#
This module is compatible with Terraform version ~> 1.0 and has been tested with the following provider versions:
- Google Provider:
>= 6.28.0, < 7.0.0 - Google Beta Provider:
>= 6.28.0, < 7.0.0
Features#
Management Infrastructure#
- Creates an IaC management project for Terraform state storage.
- Sets up a versioned GCS bucket for Terraform state files (
tfstate_bucketvariable). - Creates a service account for Terraform operations.
Folder Structure#
- Supports creation and management of a hierarchical folder structure (configured via
root_foldersandsub_foldersvariables). - Enables multi-level folder hierarchies (up to 4 levels).
- Flexible parent-child folder relationships (see "Configurable Components" for details).
Audit & Logging#
- Creates a dedicated audit project
- Sets up organization or folder level audit logging. If explicitly specified it can be project based logging as well
- Configures log export to a dedicated GCS bucket in audit project
- Enables versioning for audit logs
Security & IAM#
- Creates and configures service accounts with least privilege. The idea is when this module is used in deployment templates, any subsequent deployment to be done using this service account
- Sets up folder-level IAM permissions
- Configures organization-level roles
- Manages billing account access
- [EXPERIMENTAL] Supports predefined groups for common admin roles (optional)
- [EXPERIMENTAL] Automatically adds Terraform service account to DevOps group if configured
Configurable Components#
The following components are optional and can be configured as needed:
Management Folder (create_mgmt_folder variable)#
- Creates a dedicated folder for management resources
- Can be disabled if using existing management folder
Sub-Folders (sub_folders variable)#
- Supports up to 4 levels of folder hierarchy
- Flexible parent-child relationships
- Optional for each level
API Activation (activate_apis variable)#
- Additional APIs to enable in projects
- Supplements default APIs
Experimental Features#
DISCLAIMER: The following features are experimental and should be considered BETA functionality. They have not been thoroughly tested in production environments and may be subject to breaking changes in future versions. Use at your own risk and test thoroughly before implementing in production.
Group-based IAM Permissions (groups variable)
- Assigns predefined roles to groups specified in a map.
- The map keys must be one of the following predefined identifiers. Groups follow the GCP Enterprise Setup Checklist:
gcp-billing-admins: Billing account administrationroles/billing.admin: Full access to billing accounts
gcp-network-admins: Network administration and VPC managementroles/cloudasset.owner: Asset inventory managementroles/cloudsupport.techSupportEditor: Technical support accessroles/compute.orgFirewallPolicyAdmin: Organization firewall policy managementroles/compute.xpnAdmin: Shared VPC management
gcp-organization-admins: Full organization administrationroles/cloudasset.owner: Asset inventory managementroles/cloudsupport.admin: Full support accessroles/compute.osAdminLogin: OS login administrationroles/owner: Full organization ownershiproles/resourcemanager.folderAdmin: Folder managementroles/resourcemanager.organizationAdmin: Organization administrationroles/resourcemanager.projectCreator: Project creationroles/billing.admin: Billing administrationroles/orgpolicy.policyAdmin: Organization policy management
gcp-security-admins: Security and compliance managementroles/cloudasset.owner: Asset inventory managementroles/cloudsupport.techSupportEditor: Technical support accessroles/iam.securityReviewer: IAM security reviewroles/logging.admin: Logging administrationroles/securitycenter.admin: Security Center administrationroles/iam.organizationRoleAdmin: Organization role managementroles/orgpolicy.policyAdmin: Organization policy management
gcp-devops: DevOps and infrastructure managementroles/cloudsupport.techSupportEditor: Technical support accessroles/logging.viewer: Log viewingroles/monitoring.viewer: Monitoring accessroles/resourcemanager.folderAdmin: Folder managementroles/compute.xpnAdmin: Shared VPC managementroles/resourcemanager.projectCreator: Project creationroles/storage.admin: Storage administrationroles/resourcemanager.projectIamAdmin: Project IAM managementroles/compute.orgFirewallPolicyAdmin: Organization firewall policy managementroles/compute.orgSecurityResourceAdmin: Organization security resource managementroles/iam.securityAdmin: Security administrationroles/logging.configWriter: Logging configurationroles/resourcemanager.organizationViewer: Organization viewingroles/resourcemanager.folderViewer: Folder viewingroles/iam.organizationRoleAdmin: Organization role managementroles/billing.user: Billing access
gcp-secops-admins: Security operations (optional)- No default roles assigned
-
gcp-support: Support team access (optional)- No default roles assigned (maps to gcp-devops by default)
-
Group values can be specified in three formats:
- Simple group name (domain will be added automatically):
- Full IAM-formatted principal:
-
Default name (based on the key):
-
If the
groupsmap is empty or omitted, no group permissions are applied. - When
groups = {}(default), the module will not create any IAM bindings at all. - Because of complexity using google cloud identity in terraform members of the groups should be added from Google Workspace
- You don't need to specify all groups - only include what you need.
Usage#
module "organization" {
source = "git:https:git@github.com:your-repo/terraform-google-organization.git"
# Required variables
billing_account = "YOUR_BILLING_ACCOUNT_ID"
domain = "labs.example.com"
parent_folder = "123456789123"
# Optional variables with sensible defaults
prefix = "gcp-blues-29"
tfstate_bucket = "iac-tfstate"
location = "me-west1"
create_mgmt_folder = true
mgmt_folder = "management"
root_folders = ["platform", "marketplace"]
deletion_protection = false
sub_folders = {
level2 = [
{
name = "nonprod"
parent = "platform"
},
{
name = "prod"
parent = "platform"
}
],
level3 = [
{
name = "shared"
parent = "platform/nonprod"
},
{
name = "dev"
parent = "platform/nonprod"
},
{
name = "stage"
parent = "platform/nonprod"
},
{
name = "shared"
parent = "platform/prod"
},
{
name = "app1"
parent = "platform/prod"
},
{
name = "app2"
parent = "platform/prod"
}
]
}
# Audit logging configuration
audit_project = "audit"
log_sink_name = "organization_sink"
bucket_name = "audit-logs"
create_log_export = false
# Project configuration
random_project_id = false
deletion_policy = "DELETE"
# Safety settings
force_destroy_state_bucket = true
# EXPERIMENTAL: Groups for IAM permissions
# Provide a map of predefined keys to actual group names.
# Omit or set to {} for no group permissions.
groups = {}
}
Module Deletion#
When deleting this module, consider the following:
- State Bucket:
- If
force_destroy_state_bucket = false, you'll need to manually empty the bucket first -
Contains Terraform state files - ensure proper backup before deletion
-
Audit Logs:
- Audit logs bucket contains important audit trail
- Consider archiving logs before deletion
-
Set
force_destroy = trueif needed -
Service Accounts:
- Check for dependencies before deletion
-
Revoke any OAuth tokens if necessary
-
Projects:
- Projects will be scheduled for deletion
- Can be restored within 30 days
- After 30 days, deletion is permanent
Software#
This module requires the following software dependencies:
- Terraform
~> 1.0 - Google Cloud Provider
>= 6.28.0, < 7.0.0 - Google Cloud Beta Provider
>= 6.28.0, < 7.0.0
Service Account#
The service account used to run this module must have the following IAM roles:
roles/resourcemanager.organizationAdmin- To manage organization resourcesroles/resourcemanager.folderAdmin- To create and manage foldersroles/resourcemanager.projectCreator- To create projectsroles/billing.admin- To associate billing accounts with projectsroles/storage.admin- To create and manage storage bucketsroles/iam.serviceAccountAdmin- To create and manage service accountsroles/logging.configWriter- To configure audit loggingroles/iam.organizationRoleAdmin- To manage organization-level IAM
APIs#
The following GCP APIs must be enabled in the target organization:
- Cloud Resource Manager API (
cloudresourcemanager.googleapis.com) - Identity and Access Management (IAM) API (
iam.googleapis.com) - Cloud Storage API (
storage.googleapis.com) - Cloud Logging API (
logging.googleapis.com) - Cloud Billing API (
cloudbilling.googleapis.com) - Service Usage API (
serviceusage.googleapis.com)
License#
This module is covered by a commercial license. Please see LICENSE for details.
Support#
This module is developed and maintained by MyOps Limited. For any support inquiries, please contact us at info@myops.co.il.
Requirements#
| Name | Version |
|---|---|
| terraform | ~> 1 |
| >= 6.28.0, < 7.0.0 | |
| google-beta | >= 6.28.0, < 7.0.0 |
Providers#
| Name | Version |
|---|---|
| >= 6.28.0, < 7.0.0 |
Modules#
| Name | Source | Version |
|---|---|---|
| audit_project | terraform-google-modules/project-factory/google | ~> 18.0 |
| iac_project | terraform-google-modules/project-factory/google | ~> 18.0 |
| log_export | terraform-google-modules/log-export/google | ~> 10.0 |
| log_export_destination_storage | terraform-google-modules/log-export/google//modules/storage | ~> 10.0 |
| tf-service-account | git::https://github.com/GoogleCloudPlatform/cloud-foundation-fabric.git//modules/iam-service-account | v39.0.0 |
Resources#
| Name | Type |
|---|---|
| google_folder.level_2 | resource |
| google_folder.level_3 | resource |
| google_folder.level_4 | resource |
| google_folder.mgmt_folder | resource |
| google_folder.root_folders | resource |
| google_organization_iam_member.organization_iam_additive | resource |
| google_storage_bucket.tfstate_bucket | resource |
| google_folder.mgmt_folder | data source |
| google_folder.parent_folder | data source |
| google_folder.root_folders | data source |
| google_organization.org | data source |
Inputs#
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| activate_apis | List of API to activate on the project | list(string) |
[] |
no |
| audit_project | Audit project name | string |
"audit" |
no |
| billing_account | Billing Account | string |
n/a | yes |
| bucket_name | The name of the bucket to be created and used for log entries matching the filter. | string |
"audit_logs" |
no |
| create_mgmt_folder | Wheather to create shared mgmt folder or not | bool |
true |
no |
| deletion_policy | Whether to enable deletion protection for the Projects | string |
"PREVENT" |
no |
| deletion_protection | Whether to enable deletion protection for the folders | bool |
true |
no |
| domain | Organization domain | string |
n/a | yes |
| force_destroy_state_bucket | Whether to allow destroying the state bucket - WARNING: only set to true in testing and cleaning up | bool |
false |
no |
| groups | [EXPERIMENTAL] Map of predefined group identifiers (e.g., 'gcp-billing-admins') to actual group names (e.g., 'my-billing-admins'). If omitted or empty, no group-based permissions are applied. If names are provided without domain prefix, the 'group:' principal and organization domain are interpolated. | map(string) |
{} |
no |
| iac_project | IaC project name for tfstate bucket | string |
"mgmt-iac" |
no |
| location | Default Location of the tfstate bucket & audit logs if unspecified | string |
"" |
no |
| log_location | Audit logs bucket location | string |
"" |
no |
| log_sink_name | Log sink name | string |
"folder_sink" |
no |
| log_sink_parent | Entity name to sink logs from. Type is one of the following: 'project', 'folder', 'billing_account', or 'organization' | string |
"" |
no |
| log_sink_parent_type | The GCP resource in which you create the log sink. Must be one of the following: 'project', 'folder', 'billing_account', or 'organization' | string |
"" |
no |
| mgmt_folder | Name of the folder that will be created if admin_folder = true or admin_folder name | string |
"management" |
no |
| parent_folder | Name of the folder that will be created if create_parent_folder = true or parent_folder name | string |
n/a | yes |
| prefix | Prefix used for naming | string |
null |
no |
| random_project_id | Flag to enable random suffix generation | bool |
false |
no |
| root_folders | Provide list of root folders to create | list(string) |
[ |
no |
| sub_folders | Define a folder structure for your organization. You can define the struture up to 4 levels deep. Levels 2-4 map a child folder to a parent folder. Example {level1=[us, eu], level2 = [{name = tenant, parent = us}], level3 = [{name = dev, parent = us/tenant}] | object({ |
{} |
no |
| tfstate_bucket | tfstate bucket name | string |
"tfstate" |
no |
| tfstate_location | Location of the tfstate bucket | string |
"" |
no |
Outputs#
| Name | Description |
|---|---|
| audit_project | Audit Project ID |
| console_link | Console link |
| destination_uri | Destination URI |
| iac_project | IaC Management Project ID |
| log_filter | Log filter expression |
| log_sink_sa | Service account name of the log sink |
| mgmt_folder | Share mgmt Folder ID |
| org_id | Organization ID |
| organization_group_iam | [EXPERIMENTAL] Organization group IAM bindings |
| root_folders | Root folders |
| sub_folders | Sub folders object |
| tfstate_bucket | Bucket where the state file for this module will be stored |