Google Cloud Folder Module
This module allows the creation and management of folders, including support for IAM bindings, organization policies, and hierarchical firewall rules.
module "folder" {
source = " ./modules/folder"
parent = " organizations/1234567890"
name = " Folder name"
group_iam = {
" [email protected] " = [
" roles/owner" ,
" roles/resourcemanager.projectCreator"
]
}
iam = {
" roles/owner" = [" user:[email protected] " ]
}
}
# tftest modules=1 resources=3
module "folder" {
source = " ./modules/folder"
parent = " organizations/1234567890"
name = " Folder name"
policy_boolean = {
" constraints/compute.disableGuestAttributesAccess" = true
" constraints/compute.skipDefaultNetworkCreation" = true
}
policy_list = {
" constraints/compute.trustedImageProjects" = {
inherit_from_parent = null
suggested_value = null
status = true
values = [" projects/my-project" ]
}
}
}
# tftest modules=1 resources=4
In the same way as for the organization module, the in-built factory allows you to define a single policy, using one file for rules, and an optional file for CIDR range substitution variables. Remember that non-absolute paths are relative to the root module (the folder where you run terraform
).
module "folder" {
source = " ./modules/folder"
parent = " organizations/1234567890"
name = " Folder name"
firewall_policy_factory = {
cidr_file = " data/cidrs.yaml"
policy_name = null
rules_file = " data/rules.yaml"
}
firewall_policy_attachments = {
factory-policy = module.folder.firewall_policy_id[" factory" ]
}
}
# tftest skip
# cidrs.yaml
rfc1918 :
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
# rules.yaml
allow-admins :
description : Access from the admin subnet to all subnets
direction : INGRESS
action : allow
priority : 1000
ranges :
- $rfc1918
ports :
all : []
target_resources : null
enable_logging : false
allow-ssh-from-iap :
description : Enable SSH from IAP
direction : INGRESS
action : allow
priority : 1002
ranges :
- 35.235.240.0/20
ports :
tcp : ["22"]
target_resources : null
enable_logging : false
module "gcs" {
source = " ./modules/gcs"
project_id = " my-project"
name = " gcs_sink"
force_destroy = true
}
module "dataset" {
source = " ./modules/bigquery-dataset"
project_id = " my-project"
id = " bq_sink"
}
module "pubsub" {
source = " ./modules/pubsub"
project_id = " my-project"
name = " pubsub_sink"
}
module "bucket" {
source = " ./modules/logging-bucket"
parent_type = " project"
parent = " my-project"
id = " bucket"
}
module "folder-sink" {
source = " ./modules/folder"
parent = " folders/657104291943"
name = " my-folder"
logging_sinks = {
warnings = {
type = " storage"
destination = module.gcs.name
filter = " severity=WARNING"
include_children = true
exclusions = {}
}
info = {
type = " bigquery"
destination = module.dataset.id
filter = " severity=INFO"
include_children = true
exclusions = {}
}
notice = {
type = " pubsub"
destination = module.pubsub.id
filter = " severity=NOTICE"
include_children = true
exclusions = {}
}
debug = {
type = " logging"
destination = module.bucket.id
filter = " severity=DEBUG"
include_children = true
exclusions = {
no-compute = " logName:compute"
}
}
}
logging_exclusions = {
no-gce-instances = " resource.type=gce_instance"
}
}
# tftest modules=5 resources=14
Hierarchical firewall policies
module "folder1" {
source = " ./modules/folder"
parent = var. organization_id
name = " policy-container"
firewall_policies = {
iap-policy = {
allow-iap-ssh = {
description = " Always allow ssh from IAP"
direction = " INGRESS"
action = " allow"
priority = 100
ranges = [" 35.235.240.0/20" ]
ports = { tcp = [" 22" ] }
target_service_accounts = null
target_resources = null
logging = false
}
}
}
firewall_policy_association = {
iap-policy = " iap-policy"
}
}
module "folder2" {
source = " ./modules/folder"
parent = var. organization_id
name = " hf2"
firewall_policy_association = {
iap-policy = module.folder1.firewall_policy_id[" iap-policy" ]
}
}
# tftest modules=2 resources=6
name
description
resources
firewall-policies.tf
None
google_compute_firewall_policy
· google_compute_firewall_policy_association
· google_compute_firewall_policy_rule
iam.tf
IAM bindings, roles and audit logging resources.
google_folder_iam_binding
logging.tf
Log sinks and supporting resources.
google_bigquery_dataset_iam_member
· google_logging_folder_exclusion
· google_logging_folder_sink
· google_project_iam_member
· google_pubsub_topic_iam_member
· google_storage_bucket_iam_member
main.tf
Module-level locals and resources.
google_essential_contacts_contact
· google_folder
organization-policies.tf
Folder-level organization policies.
google_folder_organization_policy
outputs.tf
Module outputs.
variables.tf
Module variables.
versions.tf
Version pins.
name
description
type
required
default
contacts
List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES.
map(list(string))
{}
firewall_policies
Hierarchical firewall policies created in this folder.
map(map(object({…})))
{}
firewall_policy_association
The hierarchical firewall policy to associate to this folder. Must be either a key in the firewall_policies
map or the id of a policy defined somewhere else.
map(string)
{}
firewall_policy_factory
Configuration for the firewall policy factory.
object({…})
null
folder_create
Create folder. When set to false, uses id to reference an existing folder.
bool
true
group_iam
Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the iam
variable.
map(list(string))
{}
iam
IAM bindings in {ROLE => [MEMBERS]} format.
map(list(string))
{}
id
Folder ID in case you use folder_create=false.
string
null
logging_exclusions
Logging exclusions for this folder in the form {NAME -> FILTER}.
map(string)
{}
logging_sinks
Logging sinks to create for this folder.
map(object({…}))
{}
name
Folder name.
string
null
parent
Parent in folders/folder_id or organizations/org_id format.
string
null
policy_boolean
Map of boolean org policies and enforcement value, set value to null for policy restore.
map(bool)
{}
policy_list
Map of list org policies, status is true for allow, false for deny, null for restore. Values can only be used for allow or deny.
map(object({…}))
{}