Skip to content

Latest commit

 

History

History
 
 

organization-policy

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Google Cloud Organization Policy

This module allows creation and management of GCP Organization Policies by defining them in a well formatted yaml files or with HCL.

Yaml based factory can simplify centralized management of Org Policies for a DevSecOps team by providing a simple way to define/structure policies and exclusions.

NOTE: This module uses experimental feature module_variable_optional_attrs which will be included into terraform release 1.3.

Example

Terraform code

# using configuration provided in a set of yaml files
module "org-policy-factory" {
  source = "./modules/organization-policy"

  config_directory = "./policies"
}

# using configuration provided in the module variable
module "org-policy" {
  source = "./modules/organization-policy"
  
  policies = {
    "folders/1234567890" = {
      # enforce boolean policy with no conditions
      "iam.disableServiceAccountKeyUpload" = {
        rules = [
          {
            enforce = true
          }
        ]
      },
      # Deny All for compute.vmCanIpForward policy
      "compute.vmCanIpForward" = {
        inherit_from_parent = false
        rules = [
          deny = [] # stands for deny_all
        ]
      }
    },
    "organizations/1234567890" = {
      # allow only internal ingress when match condition env=prod
      "run.allowedIngress" = {
        rules = [
          {
            allow = ["internal"]
            condition = {
              description= "allow ingress"
              expression = "resource.matchTag('123456789/environment', 'prod')"
              title = "allow-for-prod-org"
            }
          }
        ]
      }
    }
  } 
}
# tftest skip

Org Policy definition format and structure

Structure of policies variable

policies = {
  "parent_id" = { # parent id in format projects/project-id, folders/1234567890 or organizations/1234567890.
    "policy_name" = { # policy constraint id, for example compute.vmExternalIpAccess.
      inherit_from_parent = true|false # (Optional) Only for list constraints. Determines the inheritance behavior for this policy.
      reset               = true|false # (Optional) Ignores policies set above this resource and restores the constraint_default enforcement behavior.
      rules               = [ # Up to 10 PolicyRules are allowed.
        {
          allow = ["value1", "value2"] # (Optional) Only for list constraints. Stands for `allow_all` if set to empty list `[]` or to `values.allowed_values` if set to a list of values
          denyl = ["value3", "value4"] # (Optional) Only for list constraints. Stands for `deny_all` if set to empty list `[]` or to `values.denied_values` if set to a list of values
          enforce   = true|false       # (Optional) Only for boolean constraints. If true, then the Policy is enforced.
          condition = {                # (Optional) A condition which determines whether this rule is used in the evaluation of the policy.
            description = "Condition description" # (Optional)
            expression  = "Condition expression"  # (Optional) For example "resource.matchTag('123456789/environment', 'prod')".
            location    = "policy-error.log"      # (Optional) String indicating the location of the expression for error reporting.
            title       = "condition-title"       # (Optional)
          }
        }
      ]
    }
  }
}
# tftest skip

Structure of configuration provided in a yaml file/s

Configuration should be placed in a set of yaml files in the config directory. Policy entry structure as follows:

parent_id: # parent id in format projects/project-id, folders/1234567890 or organizations/1234567890.
  policy_name1: # policy constraint id, for example compute.vmExternalIpAccess.
    inherit_from_parent: true|false # (Optional) Only for list constraints. Determines the inheritance behavior for this policy.
    reset: true|false               # (Optional) Ignores policies set above this resource and restores the constraint_default enforcement behavior.
    rules:
      - allow: ["value1", "value2"] # (Optional) Only for list constraints. Stands for `allow_all` if set to empty list `[]` or to `values.allowed_values` if set to a list of values
        deny: ["value3", "value4"] # (Optional) Only for list constraints. Stands for `deny_all` if set to empty list `[]` or to `values.denied_values` if set to a list of values
        enforce: true|false   # (Optional) Only for boolean constraints. If true, then the Policy is enforced.
        condition:            # (Optional) A condition which determines whether this rule is used in the evaluation of the policy.
          description: Condition description   # (Optional)
          expression: Condition expression     # (Optional) For example resource.matchTag("123456789/environment", "prod")
          location: policy-error.log           # (Optional) String indicating the location of the expression for error reporting.
          title: condition-title               # (Optional)

Module allows policies to be distributed into multiple yaml files for a better management and navigation.

├── org-policies
│   ├── baseline.yaml
│   ├── image-import-projects.yaml
│   └── exclusions.yaml

Organization policies example yaml configuration

cat ./policies/baseline.yaml
organizations/1234567890:
  constraints/compute.vmExternalIpAccess:
    rules:
      - deny: [] # Stands for deny_all = true
folders/1234567890:
  compute.vmCanIpForward:
    inherit_from_parent: false
    reset: false
    rules:
      - allow: [] # Stands for allow_all = true
projects/my-project-id:
  run.allowedIngress:
    inherit_from_parent: true
    rules:
      - allow: ['internal'] # Stands for values.allowed_values
        condition:
          description: allow internal ingress
          expression: resource.matchTag("123456789/environment", "prod")
          location: test.log
          title: allow-for-prod
  iam.allowServiceAccountCredentialLifetimeExtension:
    rules:
      - deny: [] # Stands for deny_all = true
  compute.disableGlobalLoadBalancing:
    reset: true

Variables

name description type required default
config_directory Paths to a folder where organization policy configs are stored in yaml format. Files suffix must be .yaml. string null
policies Organization policies keyed by parent in format projects/project-id, folders/1234567890 or organizations/1234567890. map(map(object({…}))) {}

Outputs

name description sensitive
policies Organization policies.