Skip to content

Terraform Google Policy Module#

This module manages Google Cloud Organization Policies, supporting both default and custom policies.

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#

  • Apply default organization policies
  • Create custom organization policies
  • Support for boolean and list-based policies
  • Apply policies at organization, folder or project level

Prerequisites#

To use this module, you need the following IAM permissions:

  • roles/orgpolicy.policyAdmin - Required to create, update, and manage organization policies

Usage#

Basic Usage#

module "org_policies" {
  source = "git:https:git@github.com:gcp-terraform-modules/terraform-google-policy.git"

  # Organization domain
  domain = "labs.example.com"

  # Enable default policy import
  import_default_policies = false

  # Custom organization policies
  org_policies = {
    # Example 1: Boolean policy to restrict public IP on Cloud SQL
    "constraints/sql.restrictPublicIp" = {
      allow            = []
      deny             = []
      policy_type      = "boolean"
      policy_for       = "organization"
      project_id       = null
      enforce          = true
      exclude_folders  = []
      exclude_projects = []
    },
  }
}

Implementation Details#

This module uses a unified approach:

  1. It creates a map of default policies when import_default_policies = true
  2. It correctly sets the policy type (boolean or list) for each default policy
  3. It merges these with any custom policies defined in org_policies
  4. It applies all policies using the terraform-google-modules/org-policy/google module

This provides a simple way to enable both default security policies and any custom policies you need.

Notes#

  • All policies (both default and custom) use the same underlying module
  • Default policies have their correct policy type (boolean or list) set automatically
  • Custom policies can override default policies by using the same constraint name

References#

Sample Policies#

Below are examples of commonly used organization policies, organized by category.

Security Policies#

# Disable service account key creation
"constraints/iam.disableServiceAccountKeyCreation" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Disable service account key upload
"constraints/iam.disableServiceAccountKeyUpload" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Disable automatic IAM grants for default service accounts
"constraints/iam.automaticIamGrantsForDefaultServiceAccounts" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Restrict service account credential lifetime extension
"constraints/iam.allowServiceAccountCredentialLifetimeExtension" = {
  allow            = []
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = true  # Deny All
  exclude_folders  = []
  exclude_projects = []
}

# Allowed policy member domains
"constraints/iam.allowedPolicyMemberDomains" = {
  allow            = []  # List of allowed domains
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = false
  exclude_folders  = []
  exclude_projects = []
}

Compute Engine Policies#

# Disable serial port access
"constraints/compute.disableSerialPortAccess" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Disable nested virtualization
"constraints/compute.disableNestedVirtualization" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Skip default network creation
"constraints/compute.skipDefaultNetworkCreation" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Disable guest attributes access
"constraints/compute.disableGuestAttributesAccess" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Restrict VPC peering
"constraints/compute.restrictVpcPeering" = {
  allow            = []
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = true  # Deny All
  exclude_folders  = []
  exclude_projects = []
}

# Require OS Login
"constraints/compute.requireOsLogin" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# VM External IP Access
"constraints/compute.vmExternalIpAccess" = {
  allow            = []  # Only folders/projects/instances that need it
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Restrict Protocol Forwarding Creation For Types
"constraints/compute.restrictProtocolForwardingCreationForTypes" = {
  allow            = []
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = true  # Deny All
  exclude_folders  = []
  exclude_projects = []
}

Storage Policies#

# Enforce uniform bucket level access
"constraints/storage.uniformBucketLevelAccess" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Storage retention policy
"constraints/storage.retentionPolicySeconds" = {
  allow            = []
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = false  # Allow All
  exclude_folders  = []
  exclude_projects = []
}

# Public access prevention
"constraints/storage.publicAccessPrevention" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Restrict auth types
"constraints/storage.restrictAuthTypes" = {
  allow            = []
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = false
  exclude_folders  = []
  exclude_projects = []
}

Network Policies#

# Restrict load balancer creation
"constraints/compute.restrictLoadBalancerCreationForTypes" = {
  allow            = [
    "in:INTERNAL"
  ]
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = null
  exclude_folders  = []
  exclude_projects = []
}

# Disable internet network endpoint group
"constraints/compute.disableInternetNetworkEndpointGroup" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Restrict VPN peer IPs
"constraints/compute.restrictVpnPeerIPs" = {
  allow            = []
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = true  # Deny All
  exclude_folders  = []
  exclude_projects = []
}

Cloud Functions and Cloud Run Policies#

# Require VPC connector for Cloud Functions
"constraints/cloudfunctions.requireVPCConnector" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Allow only internal ingress for Cloud Functions
"constraints/cloudfunctions.allowedIngressSettings" = {
  allow            = [
    "ALLOW_INTERNAL_ONLY"
  ]
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = null
  exclude_folders  = []
  exclude_projects = []
}

# Set VPC connector egress settings to private only
"constraints/cloudfunctions.allowedVpcConnectorEgressSettings" = {
  allow            = [
    "PRIVATE_RANGES_ONLY"
  ]
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = null
  exclude_folders  = []
  exclude_projects = []
}

# Allow only internal ingress for Cloud Run
"constraints/run.allowedIngress" = {
  allow            = [
    "internal"
  ]
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = null
  exclude_folders  = []
  exclude_projects = []
}

# Set VPC egress to private ranges only for Cloud Run
"constraints/run.allowedVPCEgress" = {
  allow            = [
    "private-ranges-only"
  ]
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = null
  exclude_folders  = []
  exclude_projects = []
}

Resource Location Policies#

# Restrict resource locations
"constraints/gcp.resourceLocations" = {
  allow            = [
    "in:us-locations"  # Replace with your preferred location
  ]
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = null
  exclude_folders  = []
  exclude_projects = []
}

Contact Policies#

# Allowed contact domains
"constraints/essentialcontacts.allowedContactDomains" = {
  allow            = [
    "@example.com"  # Replace with your domain
  ]
  deny             = []
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = null
  exclude_folders  = []
  exclude_projects = []
}

Other Policies#

# SQL restrict public IP
"constraints/sql.restrictPublicIp" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Detailed audit logging mode
"constraints/gcp.detailedAuditLoggingMode" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Disable App Engine code download
"constraints/appengine.disableCodeDownload" = {
  allow            = []
  deny             = []
  policy_type      = "boolean"
  policy_for       = "organization"
  project_id       = null
  enforce          = true
  exclude_folders  = []
  exclude_projects = []
}

# Restrict service usage
"constraints/serviceuser.services" = {
  allow            = []
  deny             = [
    "doubleclicksearch.googleapis.com"
  ]
  policy_type      = "list"
  policy_for       = "organization"
  project_id       = null
  enforce          = null
  exclude_folders  = []
  exclude_projects = []
}

Software#

This module requires the following software dependencies:

Service Account#

The service account used to run this module must have the following IAM roles:

  • roles/orgpolicy.policyAdmin - To create, update, and manage organization policies
  • roles/resourcemanager.organizationViewer - To view organization resources (when applying at organization level)
  • roles/resourcemanager.folderViewer - To view folder resources (when applying at folder level)
  • roles/viewer - To view project resources (when applying at project level)

APIs#

The following GCP APIs must be enabled in the target organization/project:

  • Cloud Resource Manager API (cloudresourcemanager.googleapis.com)
  • Organization Policy API (orgpolicy.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
google >= 6.28.0, < 7.0.0
google-beta >= 6.28.0, < 7.0.0

Providers#

Name Version
google >= 6.28.0, < 7.0.0

Modules#

Name Source Version
policy terraform-google-modules/org-policy/google ~> 7.0.0

Resources#

Name Type
google_organization.org data source

Inputs#

Name Description Type Default Required
default_policies List of default policies to apply when import_default_policies is true. The module automatically determines the correct policy type (boolean or list) for each policy. See the References section in README.md for more information about organization policy constraints. list(string)
[
"constraints/iam.disableServiceAccountKeyCreation",
"constraints/iam.disableServiceAccountKeyUpload",
"constraints/iam.automaticIamGrantsForDefaultServiceAccounts",
"constraints/storage.uniformBucketLevelAccess",
"constraints/compute.setNewProjectDefaultToZonalDNSOnly",
"constraints/compute.restrictProtocolForwardingCreationForTypes"
]
no
domain The domain name of the Organization string n/a yes
import_default_policies Whether to apply default organization policies. When true, policies listed in default_policies will be applied. See the README.md file for more information about required IAM permissions. bool false no
org_policies Map of custom organization policies to create. Each policy is keyed by its constraint name. See the README.md file for examples and usage information.
map(
object({
allow = list(string),
deny = list(string),
policy_type = string,
policy_for = string,
organization_id = optional(string),
folder_id = optional(string),
project_id = string,
enforce = bool,
exclude_folders = set(string),
exclude_projects = set(string)
})
)
{} no

Outputs#

Name Description
managed_policies Map of all policies managed by this module.
managed_policy_constraints List of all organization policy constraints managed by this module.
organization_id The organization ID where policies are applied.