The authoritative and additive approaches can be used together, provided different roles are managed by each. Some care must also be taken with the `groups_iam` variable to ensure that variable keys are static values, so that Terraform is able to compute the dependency graph.
Refer to the [Creating and managing custom constraints](https://cloud.google.com/resource-manager/docs/organization-policy/creating-managing-custom-constraints) documentation for details on usage.
To manage organization policy custom constraints, the `orgpolicy.googleapis.com` service should be enabled in the quota project.
You can use the `id` or `custom_constraint_ids` outputs to prevent race conditions between the creation of a custom constraint and an organization policy using that constraint. Both of these outputs depend on the actual constraint, which would make any resource referring to them to wait for the creation of the constraint.
Org policy custom constraints can be loaded from a directory containing YAML files where each file defines one or more custom constraints. The structure of the YAML files is exactly the same as the `org_policy_custom_constraints` variable.
The example below deploys a few org policy custom constraints split between two YAML files.
Hierarchical firewall policies can be managed via the [`net-firewall-policy`](../net-firewall-policy/) module, including support for factories. Once a policy is available, attaching it to the organization can be done either in the firewall policy module itself, or here:
Custom roles can be defined via the `custom_roles` variable, and referenced via the `custom_role_id` output (this also provides explicit dependency on the custom role):
Refer to the [Creating and managing tags](https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing) documentation for details on usage.
| [contacts](variables.tf#L17) | 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. | <code>map(list(string))</code> | | <code>{}</code> |
| [custom_roles](variables.tf#L24) | Map of role name => list of permissions to create in this project. | <code>map(list(string))</code> | | <code>{}</code> |
| [firewall_policy](variables.tf#L31) | Hierarchical firewall policies to associate to the organization. | <codetitle="object({ name = string policy = string })">object({…})</code> | | <code>null</code> |
| [group_iam](variables.tf#L40) | 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. | <code>map(list(string))</code> | | <code>{}</code> |
| [iam](variables.tf#L47) | IAM bindings, in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
| [iam_bindings](variables.tf#L54) | Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary. | <codetitle="map(object({ members = list(string) role = string condition = optional(object({ expression = string title = string description = optional(string) })) }))">map(object({…}))</code> | | <code>{}</code> |
| [iam_bindings_additive](variables.tf#L69) | Individual additive IAM bindings. Keys are arbitrary. | <codetitle="map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) }))">map(object({…}))</code> | | <code>{}</code> |
| [logging_data_access](variables.tf#L84) | Control activation of data access logs. Format is service => { log type => [exempted members]}. The special 'allServices' key denotes configuration for all services. | <code>map(map(list(string)))</code> | | <code>{}</code> |
| [logging_exclusions](variables.tf#L99) | Logging exclusions for this organization in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
| [logging_sinks](variables.tf#L106) | Logging sinks to create for the organization. | <codetitle="map(object({ bq_partitioned_table = optional(bool) description = optional(string) destination = string disabled = optional(bool, false) exclusions = optional(map(string), {}) filter = string iam = optional(bool, true) include_children = optional(bool, true) type = string }))">map(object({…}))</code> | | <code>{}</code> |
| [network_tags](variables.tf#L137) | Network tags by key name. If `id` is provided, key creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | <codetitle="map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) id = optional(string) network = string # project_id/vpc_name values = optional(map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) })), {}) }))">map(object({…}))</code> | | <code>{}</code> |
| [org_policies](variables.tf#L159) | Organization policies applied to this organization keyed by policy name. | <codetitle="map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool) # for boolean policies only. condition = optional(object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }), {}) })), []) }))">map(object({…}))</code> | | <code>{}</code> |
| [tag_bindings](variables.tf#L221) | Tag bindings for this organization, in key => tag value id format. | <code>map(string)</code> | | <code>null</code> |
| [tags](variables.tf#L227) | Tags by key name. If `id` is provided, key or value creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | <codetitle="map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) id = optional(string) values = optional(map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) id = optional(string) })), {}) }))">map(object({…}))</code> | | <code>{}</code> |