Incremental improvements to project factory and underlying modules (#3325)
* incremental improvements to project factory and underlying modules * fix org policies diff test
This commit is contained in:
committed by
GitHub
parent
9b3291c395
commit
c6cdc9c98c
@@ -362,9 +362,12 @@ automation:
|
|||||||
| [automation](variables-fast.tf#L17) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-org-setup</code> |
|
| [automation](variables-fast.tf#L17) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-org-setup</code> |
|
||||||
| [billing_account](variables-fast.tf#L26) | Billing account id. | <code title="object({ id = string })">object({…})</code> | ✓ | | <code>0-org-setup</code> |
|
| [billing_account](variables-fast.tf#L26) | Billing account id. | <code title="object({ id = string })">object({…})</code> | ✓ | | <code>0-org-setup</code> |
|
||||||
| [prefix](variables-fast.tf#L92) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | <code>string</code> | ✓ | | <code>0-org-setup</code> |
|
| [prefix](variables-fast.tf#L92) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | <code>string</code> | ✓ | | <code>0-org-setup</code> |
|
||||||
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object({ custom_roles = optional(map(string), {}) folder_ids = optional(map(string), {}) iam_principals = optional(map(string), {}) kms_keys = optional(map(string), {}) locations = optional(map(string), {}) notification_channels = optional(map(string), {}) project_ids = optional(map(string), {}) tag_values = optional(map(string), {}) vpc_host_projects = optional(map(string), {}) vpc_sc_perimeters = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> | |
|
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object({ condition_vars = optional(map(map(string)), {}) custom_roles = optional(map(string), {}) folder_ids = optional(map(string), {}) iam_principals = optional(map(string), {}) kms_keys = optional(map(string), {}) locations = optional(map(string), {}) notification_channels = optional(map(string), {}) project_ids = optional(map(string), {}) tag_values = optional(map(string), {}) vpc_host_projects = optional(map(string), {}) vpc_sc_perimeters = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||||
| [custom_roles](variables-fast.tf#L34) | Custom roles defined at the org level, in key => id format. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
| [custom_roles](variables-fast.tf#L34) | Custom roles defined at the org level, in key => id format. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
||||||
| [factories_config](variables.tf#L35) | Path to folder with YAML resource description data files. | <code title="object({ folders = optional(string, "data/folders") projects = optional(string, "data/projects") budgets = optional(object({ billing_account_id = string data = string })) })">object({…})</code> | | <code>{}</code> | |
|
| [data_defaults](variables.tf#L36) | Optional default values used when corresponding project or folder data from files are missing. | <code title="object({ billing_account = optional(string) bucket = optional(object({ force_destroy = optional(bool) }), {}) contacts = optional(map(list(string)), {}) deletion_policy = optional(string) factories_config = optional(object({ custom_roles = optional(string) observability = optional(string) org_policies = optional(string) quotas = optional(string) }), {}) labels = optional(map(string), {}) metric_scopes = optional(list(string), []) parent = optional(string) prefix = optional(string) project_reuse = optional(object({ use_data_source = optional(bool, true) attributes = optional(object({ name = string number = number services_enabled = optional(list(string), []) })) })) service_encryption_key_ids = optional(map(list(string)), {}) services = optional(list(string), []) shared_vpc_service_config = optional(object({ host_project = string iam_bindings_additive = optional(map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) })), {}) network_users = optional(list(string), []) service_agent_iam = optional(map(list(string)), {}) service_agent_subnet_iam = optional(map(list(string)), {}) service_iam_grants = optional(list(string), []) network_subnet_users = optional(map(list(string)), {}) })) storage_location = optional(string) tag_bindings = optional(map(string), {}) service_accounts = optional(map(object({ display_name = optional(string, "Terraform-managed.") iam_self_roles = optional(list(string)) })), {}) universe = optional(object({ prefix = string unavailable_service_identities = optional(list(string), []) unavailable_services = optional(list(string), []) })) vpc_sc = optional(object({ perimeter_name = string is_dry_run = optional(bool, false) })) logging_data_access = optional(map(object({ ADMIN_READ = optional(object({ exempted_members = optional(list(string)) })), DATA_READ = optional(object({ exempted_members = optional(list(string)) })), DATA_WRITE = optional(object({ exempted_members = optional(list(string)) })) })), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||||
|
| [data_merges](variables.tf#L108) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | <code title="object({ contacts = optional(map(list(string)), {}) labels = optional(map(string), {}) metric_scopes = optional(list(string), []) service_encryption_key_ids = optional(map(list(string)), {}) services = optional(list(string), []) tag_bindings = optional(map(string), {}) service_accounts = optional(map(object({ display_name = optional(string, "Terraform-managed.") iam_self_roles = optional(list(string)) })), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||||
|
| [data_overrides](variables.tf#L127) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | <code title="object({ billing_account = optional(string) bucket = optional(object({ force_destroy = optional(bool) }), {}) contacts = optional(map(list(string))) deletion_policy = optional(string) factories_config = optional(object({ custom_roles = optional(string) observability = optional(string) org_policies = optional(string) quotas = optional(string) }), {}) parent = optional(string) prefix = optional(string) service_encryption_key_ids = optional(map(list(string))) storage_location = optional(string) tag_bindings = optional(map(string)) services = optional(list(string)) service_accounts = optional(map(object({ display_name = optional(string, "Terraform-managed.") iam_self_roles = optional(list(string)) }))) universe = optional(object({ prefix = string unavailable_service_identities = optional(list(string), []) unavailable_services = optional(list(string), []) })) vpc_sc = optional(object({ perimeter_name = string is_dry_run = optional(bool, false) })) logging_data_access = optional(map(object({ ADMIN_READ = optional(object({ exempted_members = optional(list(string)) })), DATA_READ = optional(object({ exempted_members = optional(list(string)) })), DATA_WRITE = optional(object({ exempted_members = optional(list(string)) })) }))) })">object({…})</code> | | <code>{}</code> | |
|
||||||
|
| [factories_config](variables.tf#L173) | Path to folder with YAML resource description data files. | <code title="object({ folders = optional(string, "data/folders") projects = optional(string, "data/projects") budgets = optional(object({ billing_account_id = string data = string })) })">object({…})</code> | | <code>{}</code> | |
|
||||||
| [folder_ids](variables-fast.tf#L42) | Folders created in the bootstrap stage. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
| [folder_ids](variables-fast.tf#L42) | Folders created in the bootstrap stage. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
||||||
| [host_project_ids](variables-fast.tf#L58) | Host project for the shared VPC. | <code>map(string)</code> | | <code>{}</code> | <code>2-networking</code> |
|
| [host_project_ids](variables-fast.tf#L58) | Host project for the shared VPC. | <code>map(string)</code> | | <code>{}</code> | <code>2-networking</code> |
|
||||||
| [iam_principals](variables-fast.tf#L50) | IAM-format principals. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
| [iam_principals](variables-fast.tf#L50) | IAM-format principals. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
||||||
@@ -373,8 +376,9 @@ automation:
|
|||||||
| [perimeters](variables-fast.tf#L84) | Optional VPC-SC perimeter ids. | <code>map(string)</code> | | <code>{}</code> | <code>1-vpcsc</code> |
|
| [perimeters](variables-fast.tf#L84) | Optional VPC-SC perimeter ids. | <code>map(string)</code> | | <code>{}</code> | <code>1-vpcsc</code> |
|
||||||
| [project_ids](variables-fast.tf#L102) | Projects created in the bootstrap stage. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
| [project_ids](variables-fast.tf#L102) | Projects created in the bootstrap stage. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
||||||
| [service_accounts](variables-fast.tf#L110) | Service accounts created in the bootstrap stage. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
| [service_accounts](variables-fast.tf#L110) | Service accounts created in the bootstrap stage. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
||||||
| [stage_name](variables.tf#L55) | FAST stage name. Used to separate output files across different factories. | <code>string</code> | | <code>"2-project-factory"</code> | |
|
| [stage_name](variables.tf#L193) | FAST stage name. Used to separate output files across different factories. | <code>string</code> | | <code>"2-project-factory"</code> | |
|
||||||
| [tag_values](variables-fast.tf#L118) | FAST-managed resource manager tag values. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
| [subnet_self_links](variables-fast.tf#L118) | Shared VPC subnet IDs. | <code>map(map(string))</code> | | <code>{}</code> | <code>2-networking</code> |
|
||||||
|
| [tag_values](variables-fast.tf#L126) | FAST-managed resource manager tag values. | <code>map(string)</code> | | <code>{}</code> | <code>0-org-setup</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,25 @@
|
|||||||
|
|
||||||
# tfdoc:file:description Project factory.
|
# tfdoc:file:description Project factory.
|
||||||
|
|
||||||
|
locals {
|
||||||
|
subnet_self_links = flatten([
|
||||||
|
for net, subnets in var.subnet_self_links : [
|
||||||
|
for subnet_name, subnet_link in subnets : {
|
||||||
|
key = "${net}/${subnet_name}"
|
||||||
|
link = subnet_link
|
||||||
|
}
|
||||||
|
]
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
module "factory" {
|
module "factory" {
|
||||||
source = "../../../modules/project-factory"
|
source = "../../../modules/project-factory"
|
||||||
context = {
|
context = {
|
||||||
|
condition_vars = merge({
|
||||||
|
subnet_self_links = {
|
||||||
|
for v in local.subnet_self_links : v.key => v.link
|
||||||
|
}
|
||||||
|
}, var.context.condition_vars)
|
||||||
custom_roles = merge(
|
custom_roles = merge(
|
||||||
var.custom_roles, var.context.custom_roles
|
var.custom_roles, var.context.custom_roles
|
||||||
)
|
)
|
||||||
@@ -50,20 +66,23 @@ module "factory" {
|
|||||||
var.perimeters, var.context.vpc_sc_perimeters
|
var.perimeters, var.context.vpc_sc_perimeters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
data_defaults = {
|
data_defaults = merge(var.data_defaults, {
|
||||||
# more defaults are available, check the project factory variables
|
billing_account = coalesce(
|
||||||
billing_account = var.billing_account.id
|
var.data_defaults.billing_account, var.billing_account.id
|
||||||
storage_location = var.locations.storage
|
)
|
||||||
}
|
prefix = coalesce(var.data_defaults.prefix, var.prefix)
|
||||||
data_merges = {
|
storage_location = coalesce(
|
||||||
services = [
|
var.data_defaults.storage_location, var.locations.storage
|
||||||
|
)
|
||||||
|
})
|
||||||
|
data_merges = merge(var.data_merges, {
|
||||||
|
services = length(var.data_merges.services) > 0 ? var.data_merges.services : [
|
||||||
"logging.googleapis.com",
|
"logging.googleapis.com",
|
||||||
"monitoring.googleapis.com"
|
"monitoring.googleapis.com"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
data_overrides = {
|
)
|
||||||
prefix = var.prefix
|
data_overrides = var.data_overrides
|
||||||
}
|
|
||||||
factories_config = merge(var.factories_config, {
|
factories_config = merge(var.factories_config, {
|
||||||
budgets = {
|
budgets = {
|
||||||
billing_account_id = try(
|
billing_account_id = try(
|
||||||
|
|||||||
@@ -115,6 +115,14 @@ variable "service_accounts" {
|
|||||||
default = {}
|
default = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "subnet_self_links" {
|
||||||
|
# tfdoc:variable:source 2-networking
|
||||||
|
description = "Shared VPC subnet IDs."
|
||||||
|
type = map(map(string))
|
||||||
|
nullable = false
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
|
||||||
variable "tag_values" {
|
variable "tag_values" {
|
||||||
# tfdoc:variable:source 0-org-setup
|
# tfdoc:variable:source 0-org-setup
|
||||||
description = "FAST-managed resource manager tag values."
|
description = "FAST-managed resource manager tag values."
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
variable "context" {
|
variable "context" {
|
||||||
description = "Context-specific interpolations."
|
description = "Context-specific interpolations."
|
||||||
type = object({
|
type = object({
|
||||||
|
condition_vars = optional(map(map(string)), {})
|
||||||
custom_roles = optional(map(string), {})
|
custom_roles = optional(map(string), {})
|
||||||
folder_ids = optional(map(string), {})
|
folder_ids = optional(map(string), {})
|
||||||
iam_principals = optional(map(string), {})
|
iam_principals = optional(map(string), {})
|
||||||
@@ -32,6 +33,143 @@ variable "context" {
|
|||||||
nullable = false
|
nullable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "data_defaults" {
|
||||||
|
description = "Optional default values used when corresponding project or folder data from files are missing."
|
||||||
|
type = object({
|
||||||
|
billing_account = optional(string)
|
||||||
|
bucket = optional(object({
|
||||||
|
force_destroy = optional(bool)
|
||||||
|
}), {})
|
||||||
|
contacts = optional(map(list(string)), {})
|
||||||
|
deletion_policy = optional(string)
|
||||||
|
factories_config = optional(object({
|
||||||
|
custom_roles = optional(string)
|
||||||
|
observability = optional(string)
|
||||||
|
org_policies = optional(string)
|
||||||
|
quotas = optional(string)
|
||||||
|
}), {})
|
||||||
|
labels = optional(map(string), {})
|
||||||
|
metric_scopes = optional(list(string), [])
|
||||||
|
parent = optional(string)
|
||||||
|
prefix = optional(string)
|
||||||
|
project_reuse = optional(object({
|
||||||
|
use_data_source = optional(bool, true)
|
||||||
|
attributes = optional(object({
|
||||||
|
name = string
|
||||||
|
number = number
|
||||||
|
services_enabled = optional(list(string), [])
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
service_encryption_key_ids = optional(map(list(string)), {})
|
||||||
|
services = optional(list(string), [])
|
||||||
|
shared_vpc_service_config = optional(object({
|
||||||
|
host_project = string
|
||||||
|
iam_bindings_additive = optional(map(object({
|
||||||
|
member = string
|
||||||
|
role = string
|
||||||
|
condition = optional(object({
|
||||||
|
expression = string
|
||||||
|
title = string
|
||||||
|
description = optional(string)
|
||||||
|
}))
|
||||||
|
})), {})
|
||||||
|
network_users = optional(list(string), [])
|
||||||
|
service_agent_iam = optional(map(list(string)), {})
|
||||||
|
service_agent_subnet_iam = optional(map(list(string)), {})
|
||||||
|
service_iam_grants = optional(list(string), [])
|
||||||
|
network_subnet_users = optional(map(list(string)), {})
|
||||||
|
}))
|
||||||
|
storage_location = optional(string)
|
||||||
|
tag_bindings = optional(map(string), {})
|
||||||
|
# non-project resources
|
||||||
|
service_accounts = optional(map(object({
|
||||||
|
display_name = optional(string, "Terraform-managed.")
|
||||||
|
iam_self_roles = optional(list(string))
|
||||||
|
})), {})
|
||||||
|
universe = optional(object({
|
||||||
|
prefix = string
|
||||||
|
unavailable_service_identities = optional(list(string), [])
|
||||||
|
unavailable_services = optional(list(string), [])
|
||||||
|
}))
|
||||||
|
vpc_sc = optional(object({
|
||||||
|
perimeter_name = string
|
||||||
|
is_dry_run = optional(bool, false)
|
||||||
|
}))
|
||||||
|
logging_data_access = optional(map(object({
|
||||||
|
ADMIN_READ = optional(object({ exempted_members = optional(list(string)) })),
|
||||||
|
DATA_READ = optional(object({ exempted_members = optional(list(string)) })),
|
||||||
|
DATA_WRITE = optional(object({ exempted_members = optional(list(string)) }))
|
||||||
|
})), {})
|
||||||
|
})
|
||||||
|
nullable = false
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "data_merges" {
|
||||||
|
description = "Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`."
|
||||||
|
type = object({
|
||||||
|
contacts = optional(map(list(string)), {})
|
||||||
|
labels = optional(map(string), {})
|
||||||
|
metric_scopes = optional(list(string), [])
|
||||||
|
service_encryption_key_ids = optional(map(list(string)), {})
|
||||||
|
services = optional(list(string), [])
|
||||||
|
tag_bindings = optional(map(string), {})
|
||||||
|
# non-project resources
|
||||||
|
service_accounts = optional(map(object({
|
||||||
|
display_name = optional(string, "Terraform-managed.")
|
||||||
|
iam_self_roles = optional(list(string))
|
||||||
|
})), {})
|
||||||
|
})
|
||||||
|
nullable = false
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "data_overrides" {
|
||||||
|
description = "Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`."
|
||||||
|
type = object({
|
||||||
|
# data overrides default to null to mark that they should not override
|
||||||
|
billing_account = optional(string)
|
||||||
|
bucket = optional(object({
|
||||||
|
force_destroy = optional(bool)
|
||||||
|
}), {})
|
||||||
|
contacts = optional(map(list(string)))
|
||||||
|
deletion_policy = optional(string)
|
||||||
|
factories_config = optional(object({
|
||||||
|
custom_roles = optional(string)
|
||||||
|
observability = optional(string)
|
||||||
|
org_policies = optional(string)
|
||||||
|
quotas = optional(string)
|
||||||
|
}), {})
|
||||||
|
parent = optional(string)
|
||||||
|
prefix = optional(string)
|
||||||
|
service_encryption_key_ids = optional(map(list(string)))
|
||||||
|
storage_location = optional(string)
|
||||||
|
tag_bindings = optional(map(string))
|
||||||
|
services = optional(list(string))
|
||||||
|
# non-project resources
|
||||||
|
service_accounts = optional(map(object({
|
||||||
|
display_name = optional(string, "Terraform-managed.")
|
||||||
|
iam_self_roles = optional(list(string))
|
||||||
|
})))
|
||||||
|
universe = optional(object({
|
||||||
|
prefix = string
|
||||||
|
unavailable_service_identities = optional(list(string), [])
|
||||||
|
unavailable_services = optional(list(string), [])
|
||||||
|
}))
|
||||||
|
vpc_sc = optional(object({
|
||||||
|
perimeter_name = string
|
||||||
|
is_dry_run = optional(bool, false)
|
||||||
|
}))
|
||||||
|
logging_data_access = optional(map(object({
|
||||||
|
ADMIN_READ = optional(object({ exempted_members = optional(list(string)) })),
|
||||||
|
DATA_READ = optional(object({ exempted_members = optional(list(string)) })),
|
||||||
|
DATA_WRITE = optional(object({ exempted_members = optional(list(string)) }))
|
||||||
|
})))
|
||||||
|
})
|
||||||
|
nullable = false
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
|
||||||
variable "factories_config" {
|
variable "factories_config" {
|
||||||
description = "Path to folder with YAML resource description data files."
|
description = "Path to folder with YAML resource description data files."
|
||||||
type = object({
|
type = object({
|
||||||
|
|||||||
@@ -138,8 +138,12 @@ resource "google_org_policy_policy" "default" {
|
|||||||
dynamic "values" {
|
dynamic "values" {
|
||||||
for_each = rule.value.has_values ? [1] : []
|
for_each = rule.value.has_values ? [1] : []
|
||||||
content {
|
content {
|
||||||
allowed_values = try(rule.value.allow.values, null)
|
allowed_values = try(rule.value.allow.values, null) == null ? null : [
|
||||||
denied_values = try(rule.value.deny.values, null)
|
for v in rule.value.allow.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
|
denied_values = try(rule.value.deny.values, null) == null ? null : [
|
||||||
|
for v in rule.value.deny.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,8 +181,12 @@ resource "google_org_policy_policy" "default" {
|
|||||||
dynamic "values" {
|
dynamic "values" {
|
||||||
for_each = rule.value.has_values ? [1] : []
|
for_each = rule.value.has_values ? [1] : []
|
||||||
content {
|
content {
|
||||||
allowed_values = try(rule.value.allow.values, null)
|
allowed_values = try(rule.value.allow.values, null) == null ? null : [
|
||||||
denied_values = try(rule.value.deny.values, null)
|
for v in rule.value.allow.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
|
denied_values = try(rule.value.deny.values, null) == null ? null : [
|
||||||
|
for v in rule.value.deny.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,8 +138,12 @@ resource "google_org_policy_policy" "default" {
|
|||||||
dynamic "values" {
|
dynamic "values" {
|
||||||
for_each = rule.value.has_values ? [1] : []
|
for_each = rule.value.has_values ? [1] : []
|
||||||
content {
|
content {
|
||||||
allowed_values = try(rule.value.allow.values, null)
|
allowed_values = try(rule.value.allow.values, null) == null ? null : [
|
||||||
denied_values = try(rule.value.deny.values, null)
|
for v in rule.value.allow.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
|
denied_values = try(rule.value.deny.values, null) == null ? null : [
|
||||||
|
for v in rule.value.deny.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,8 +181,12 @@ resource "google_org_policy_policy" "default" {
|
|||||||
dynamic "values" {
|
dynamic "values" {
|
||||||
for_each = rule.value.has_values ? [1] : []
|
for_each = rule.value.has_values ? [1] : []
|
||||||
content {
|
content {
|
||||||
allowed_values = try(rule.value.allow.values, null)
|
allowed_values = try(rule.value.allow.values, null) == null ? null : [
|
||||||
denied_values = try(rule.value.deny.values, null)
|
for v in rule.value.allow.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
|
denied_values = try(rule.value.deny.values, null) == null ? null : [
|
||||||
|
for v in rule.value.deny.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,8 +138,12 @@ resource "google_org_policy_policy" "default" {
|
|||||||
dynamic "values" {
|
dynamic "values" {
|
||||||
for_each = rule.value.has_values ? [1] : []
|
for_each = rule.value.has_values ? [1] : []
|
||||||
content {
|
content {
|
||||||
allowed_values = try(rule.value.allow.values, null)
|
allowed_values = try(rule.value.allow.values, null) == null ? null : [
|
||||||
denied_values = try(rule.value.deny.values, null)
|
for v in rule.value.allow.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
|
denied_values = try(rule.value.deny.values, null) == null ? null : [
|
||||||
|
for v in rule.value.deny.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,8 +181,12 @@ resource "google_org_policy_policy" "default" {
|
|||||||
dynamic "values" {
|
dynamic "values" {
|
||||||
for_each = rule.value.has_values ? [1] : []
|
for_each = rule.value.has_values ? [1] : []
|
||||||
content {
|
content {
|
||||||
allowed_values = try(rule.value.allow.values, null)
|
allowed_values = try(rule.value.allow.values, null) == null ? null : [
|
||||||
denied_values = try(rule.value.deny.values, null)
|
for v in rule.value.allow.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
|
denied_values = try(rule.value.deny.values, null) == null ? null : [
|
||||||
|
for v in rule.value.deny.values : templatestring(v, var.context.condition_vars)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ def test_policy_implementation():
|
|||||||
'- parent = local.folder_id\n',
|
'- parent = local.folder_id\n',
|
||||||
'+ name = "${var.organization_id}/policies/${each.value}"\n',
|
'+ name = "${var.organization_id}/policies/${each.value}"\n',
|
||||||
'+ parent = var.organization_id\n',
|
'+ parent = var.organization_id\n',
|
||||||
'@@ -187,0 +188,9 @@\n',
|
'@@ -195,0 +196,9 @@\n',
|
||||||
'+ depends_on = [\n',
|
'+ depends_on = [\n',
|
||||||
'+ google_organization_iam_binding.authoritative,\n',
|
'+ google_organization_iam_binding.authoritative,\n',
|
||||||
'+ google_organization_iam_binding.bindings,\n',
|
'+ google_organization_iam_binding.bindings,\n',
|
||||||
|
|||||||
Reference in New Issue
Block a user