Simplify org policies data model in resman modules.

This commit is contained in:
Julio Castillo 2023-02-21 12:24:40 +01:00
parent 77df3c8721
commit 6b767c9035
19 changed files with 242 additions and 288 deletions

View File

@ -42,40 +42,46 @@ module "folder" {
name = "Folder name"
org_policies = {
"compute.disableGuestAttributesAccess" = {
enforce = true
rules = [{ enforce = true }]
}
"constraints/compute.skipDefaultNetworkCreation" = {
enforce = true
rules = [{ enforce = true }]
}
"iam.disableServiceAccountKeyCreation" = {
enforce = true
rules = [{ enforce = true }]
}
"iam.disableServiceAccountKeyUpload" = {
enforce = false
rules = [
{
condition = {
expression = "resource.matchTagId(\"tagKeys/1234\", \"tagValues/1234\")"
expression = "resource.matchTagId('tagKeys/1234', 'tagValues/1234')"
title = "condition"
description = "test condition"
location = "somewhere"
}
enforce = true
},
{
enforce = false
}
]
}
"constraints/iam.allowedPolicyMemberDomains" = {
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
rules = [{
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
}]
}
"constraints/compute.trustedImageProjects" = {
allow = {
values = ["projects/my-project"]
}
rules = [{
allow = {
values = ["projects/my-project"]
}
}]
}
"constraints/compute.vmExternalIpAccess" = {
deny = { all = true }
rules = [{ deny = { all = true } }]
}
}
}

View File

@ -1,5 +1,5 @@
/**
* Copyright 2022 Google LLC
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,16 +28,6 @@ locals {
k => {
inherit_from_parent = try(v.inherit_from_parent, null)
reset = try(v.reset, null)
allow = can(v.allow) ? {
all = try(v.allow.all, null)
values = try(v.allow.values, null)
} : null
deny = can(v.deny) ? {
all = try(v.deny.all, null)
values = try(v.deny.values, null)
} : null
enforce = try(v.enforce, true)
rules = [
for r in try(v.rules, []) : {
allow = can(r.allow) ? {
@ -48,7 +38,7 @@ locals {
all = try(r.deny.all, null)
values = try(r.deny.values, null)
} : null
enforce = try(r.enforce, true)
enforce = try(r.enforce, null)
condition = {
description = try(r.condition.description, null)
expression = try(r.condition.expression, null)
@ -67,8 +57,9 @@ locals {
k => merge(v, {
name = "${local.folder.name}/policies/${k}"
parent = local.folder.name
is_boolean_policy = v.allow == null && v.deny == null
is_boolean_policy = (
alltrue([for r in v.rules : r.allow == null && r.deny == null])
)
has_values = (
length(coalesce(try(v.allow.values, []), [])) > 0 ||
length(coalesce(try(v.deny.values, []), [])) > 0
@ -90,11 +81,9 @@ resource "google_org_policy_policy" "default" {
for_each = local.org_policies
name = each.value.name
parent = each.value.parent
spec {
inherit_from_parent = each.value.inherit_from_parent
reset = each.value.reset
dynamic "rules" {
for_each = each.value.rules
iterator = rule
@ -106,11 +95,14 @@ resource "google_org_policy_policy" "default" {
? upper(tostring(rule.value.enforce))
: null
)
condition {
description = rule.value.condition.description
expression = rule.value.condition.expression
location = rule.value.condition.location
title = rule.value.condition.title
dynamic "condition" {
for_each = rule.value.condition.expression != null ? [1] : []
content {
description = rule.value.condition.description
expression = rule.value.condition.expression
location = rule.value.condition.location
title = rule.value.condition.title
}
}
dynamic "values" {
for_each = rule.value.has_values ? [1] : []
@ -121,22 +113,5 @@ resource "google_org_policy_policy" "default" {
}
}
}
rules {
allow_all = try(each.value.allow.all, null) == true ? "TRUE" : null
deny_all = try(each.value.deny.all, null) == true ? "TRUE" : null
enforce = (
each.value.is_boolean_policy && each.value.enforce != null
? upper(tostring(each.value.enforce))
: null
)
dynamic "values" {
for_each = each.value.has_values ? [1] : []
content {
allowed_values = try(each.value.allow.values, null)
denied_values = try(each.value.deny.values, null)
}
}
}
}
}

View File

@ -1,5 +1,5 @@
/**
* Copyright 2022 Google LLC
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -143,19 +143,6 @@ variable "org_policies" {
type = map(object({
inherit_from_parent = optional(bool) # for list policies only.
reset = optional(bool)
# default (unconditional) values
allow = optional(object({
all = optional(bool)
values = optional(list(string))
}))
deny = optional(object({
all = optional(bool)
values = optional(list(string))
}))
enforce = optional(bool, true) # for boolean policies only.
# conditional values
rules = optional(list(object({
allow = optional(object({
all = optional(bool)
@ -165,13 +152,13 @@ variable "org_policies" {
all = optional(bool)
values = optional(list(string))
}))
enforce = optional(bool, true) # for boolean policies only.
condition = object({
enforce = optional(bool) # for boolean policies only.
condition = optional(object({
description = optional(string)
expression = optional(string)
location = optional(string)
title = optional(string)
})
}), {})
})), [])
}))
default = {}

View File

@ -25,50 +25,77 @@ module "org" {
iam_additive_members = {
"user:compute@example.org" = ["roles/compute.admin", "roles/container.viewer"]
}
tags = {
allowexternal = {
description = "Allow external identities."
values = {
true = {}, false = {}
}
}
}
org_policies = {
"custom.gkeEnableAutoUpgrade" = {
enforce = true
rules = [{ enforce = true }]
}
"compute.disableGuestAttributesAccess" = {
enforce = true
rules = [{ enforce = true }]
}
"constraints/compute.skipDefaultNetworkCreation" = {
enforce = true
rules = [{ enforce = true }]
}
"iam.disableServiceAccountKeyCreation" = {
enforce = true
rules = [{ enforce = true }]
}
"iam.disableServiceAccountKeyUpload" = {
enforce = false
rules = [
{
condition = {
expression = "resource.matchTagId(\"tagKeys/1234\", \"tagValues/1234\")"
expression = "resource.matchTagId('tagKeys/1234', 'tagValues/1234')"
title = "condition"
description = "test condition"
location = "somewhere"
}
enforce = true
},
{
enforce = false
}
]
}
"constraints/iam.allowedPolicyMemberDomains" = {
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
rules = [
{
allow = { all = true }
condition = {
expression = "resource.matchTag('1234567890/allowexternal', 'true')"
title = "Allow external identities"
description = "Allow external identities when resource has the `allowexternal` tag set to true."
}
},
{
allow = { values = ["C0xxxxxxx", "C0yyyyyyy"] }
condition = {
expression = "!resource.matchTag('1234567890/allowexternal', 'true')"
title = ""
description = "For any resource without allowexternal=true, only allow identities from restricted domains."
}
}
]
}
"constraints/compute.trustedImageProjects" = {
allow = {
values = ["projects/my-project"]
}
rules = [{
allow = {
values = ["projects/my-project"]
}
}]
}
"constraints/compute.vmExternalIpAccess" = {
deny = { all = true }
rules = [{ deny = { all = true } }]
}
}
}
# tftest modules=1 resources=13 inventory=basic.yaml
# tftest modules=1 resources=16 inventory=basic.yaml
```
## IAM
@ -111,7 +138,7 @@ module "org" {
# not necessarily to enforce on the org level, policy may be applied on folder/project levels
org_policies = {
"custom.gkeEnableAutoUpgrade" = {
enforce = true
rules = [{ enforce = true }]
}
}
}
@ -131,7 +158,7 @@ module "org" {
org_policy_custom_constraints_data_path = "configs/custom-constraints"
org_policies = {
"custom.gkeEnableAutoUpgrade" = {
enforce = true
rules = [{ enforce = true }]
}
}
}

View File

@ -1,5 +1,5 @@
/**
* Copyright 2022 Google LLC
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,16 +28,6 @@ locals {
k => {
inherit_from_parent = try(v.inherit_from_parent, null)
reset = try(v.reset, null)
allow = can(v.allow) ? {
all = try(v.allow.all, null)
values = try(v.allow.values, null)
} : null
deny = can(v.deny) ? {
all = try(v.deny.all, null)
values = try(v.deny.values, null)
} : null
enforce = try(v.enforce, true)
rules = [
for r in try(v.rules, []) : {
allow = can(r.allow) ? {
@ -48,7 +38,7 @@ locals {
all = try(r.deny.all, null)
values = try(r.deny.values, null)
} : null
enforce = try(r.enforce, true)
enforce = try(r.enforce, null)
condition = {
description = try(r.condition.description, null)
expression = try(r.condition.expression, null)
@ -67,8 +57,9 @@ locals {
k => merge(v, {
name = "${var.organization_id}/policies/${k}"
parent = var.organization_id
is_boolean_policy = v.allow == null && v.deny == null
is_boolean_policy = (
alltrue([for r in v.rules : r.allow == null && r.deny == null])
)
has_values = (
length(coalesce(try(v.allow.values, []), [])) > 0 ||
length(coalesce(try(v.deny.values, []), [])) > 0
@ -90,11 +81,9 @@ resource "google_org_policy_policy" "default" {
for_each = local.org_policies
name = each.value.name
parent = each.value.parent
spec {
inherit_from_parent = each.value.inherit_from_parent
reset = each.value.reset
dynamic "rules" {
for_each = each.value.rules
iterator = rule
@ -106,11 +95,14 @@ resource "google_org_policy_policy" "default" {
? upper(tostring(rule.value.enforce))
: null
)
condition {
description = rule.value.condition.description
expression = rule.value.condition.expression
location = rule.value.condition.location
title = rule.value.condition.title
dynamic "condition" {
for_each = rule.value.condition.expression != null ? [1] : []
content {
description = rule.value.condition.description
expression = rule.value.condition.expression
location = rule.value.condition.location
title = rule.value.condition.title
}
}
dynamic "values" {
for_each = rule.value.has_values ? [1] : []
@ -121,25 +113,7 @@ resource "google_org_policy_policy" "default" {
}
}
}
rules {
allow_all = try(each.value.allow.all, null) == true ? "TRUE" : null
deny_all = try(each.value.deny.all, null) == true ? "TRUE" : null
enforce = (
each.value.is_boolean_policy && each.value.enforce != null
? upper(tostring(each.value.enforce))
: null
)
dynamic "values" {
for_each = each.value.has_values ? [1] : []
content {
allowed_values = try(each.value.allow.values, null)
denied_values = try(each.value.deny.values, null)
}
}
}
}
depends_on = [
google_organization_iam_audit_config.config,
google_organization_iam_binding.authoritative,

View File

@ -1,5 +1,5 @@
/**
* Copyright 2022 Google LLC
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -183,18 +183,6 @@ variable "org_policies" {
type = map(object({
inherit_from_parent = optional(bool) # for list policies only.
reset = optional(bool)
# default (unconditional) values
allow = optional(object({
all = optional(bool)
values = optional(list(string))
}))
deny = optional(object({
all = optional(bool)
values = optional(list(string))
}))
enforce = optional(bool, true) # for boolean policies only.
# conditional values
rules = optional(list(object({
allow = optional(object({
all = optional(bool)
@ -204,13 +192,13 @@ variable "org_policies" {
all = optional(bool)
values = optional(list(string))
}))
enforce = optional(bool, true) # for boolean policies only.
condition = object({
enforce = optional(bool) # for boolean policies only.
condition = optional(object({
description = optional(string)
expression = optional(string)
location = optional(string)
title = optional(string)
})
}), {})
})), [])
}))
default = {}

View File

@ -243,40 +243,46 @@ module "project" {
prefix = "foo"
org_policies = {
"compute.disableGuestAttributesAccess" = {
enforce = true
rules = [{ enforce = true }]
}
"constraints/compute.skipDefaultNetworkCreation" = {
enforce = true
rules = [{ enforce = true }]
}
"iam.disableServiceAccountKeyCreation" = {
enforce = true
rules = [{ enforce = true }]
}
"iam.disableServiceAccountKeyUpload" = {
enforce = false
rules = [
{
condition = {
expression = "resource.matchTagId(\"tagKeys/1234\", \"tagValues/1234\")"
expression = "resource.matchTagId('tagKeys/1234', 'tagValues/1234')"
title = "condition"
description = "test condition"
location = "somewhere"
}
enforce = true
},
{
enforce = false
}
]
}
"constraints/iam.allowedPolicyMemberDomains" = {
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
rules = [{
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
}]
}
"constraints/compute.trustedImageProjects" = {
allow = {
values = ["projects/my-project"]
}
rules = [{
allow = {
values = ["projects/my-project"]
}
}]
}
"constraints/compute.vmExternalIpAccess" = {
deny = { all = true }
rules = [{ deny = { all = true } }]
}
}
}
@ -306,36 +312,42 @@ module "project" {
```yaml
# tftest-file id=boolean path=configs/org-policies/boolean.yaml
compute.disableGuestAttributesAccess:
enforce: true
rules:
- enforce: true
constraints/compute.skipDefaultNetworkCreation:
enforce: true
rules:
- enforce: true
iam.disableServiceAccountKeyCreation:
enforce: true
rules:
- enforce: true
iam.disableServiceAccountKeyUpload:
enforce: false
rules:
- condition:
description: test condition
expression: resource.matchTagId("tagKeys/1234", "tagValues/1234")
expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234')
location: somewhere
title: condition
enforce: true
- enforce: false
```
```yaml
# tftest-file id=list path=configs/org-policies/list.yaml
constraints/compute.trustedImageProjects:
allow:
values:
- projects/my-project
rules:
- allow:
values:
- projects/my-project
constraints/compute.vmExternalIpAccess:
deny:
all: true
rules:
- deny:
all: true
constraints/iam.allowedPolicyMemberDomains:
allow:
values:
- C0xxxxxxx
- C0yyyyyyy
rules:
- allow:
values:
- C0xxxxxxx
- C0yyyyyyy
```

View File

@ -1,5 +1,5 @@
/**
* Copyright 2022 Google LLC
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,16 +28,6 @@ locals {
k => {
inherit_from_parent = try(v.inherit_from_parent, null)
reset = try(v.reset, null)
allow = can(v.allow) ? {
all = try(v.allow.all, null)
values = try(v.allow.values, null)
} : null
deny = can(v.deny) ? {
all = try(v.deny.all, null)
values = try(v.deny.values, null)
} : null
enforce = try(v.enforce, true)
rules = [
for r in try(v.rules, []) : {
allow = can(r.allow) ? {
@ -48,7 +38,7 @@ locals {
all = try(r.deny.all, null)
values = try(r.deny.values, null)
} : null
enforce = try(r.enforce, true)
enforce = try(r.enforce, null)
condition = {
description = try(r.condition.description, null)
expression = try(r.condition.expression, null)
@ -67,8 +57,9 @@ locals {
k => merge(v, {
name = "projects/${local.project.project_id}/policies/${k}"
parent = "projects/${local.project.project_id}"
is_boolean_policy = v.allow == null && v.deny == null
is_boolean_policy = (
alltrue([for r in v.rules : r.allow == null && r.deny == null])
)
has_values = (
length(coalesce(try(v.allow.values, []), [])) > 0 ||
length(coalesce(try(v.deny.values, []), [])) > 0
@ -90,11 +81,9 @@ resource "google_org_policy_policy" "default" {
for_each = local.org_policies
name = each.value.name
parent = each.value.parent
spec {
inherit_from_parent = each.value.inherit_from_parent
reset = each.value.reset
dynamic "rules" {
for_each = each.value.rules
iterator = rule
@ -106,11 +95,14 @@ resource "google_org_policy_policy" "default" {
? upper(tostring(rule.value.enforce))
: null
)
condition {
description = rule.value.condition.description
expression = rule.value.condition.expression
location = rule.value.condition.location
title = rule.value.condition.title
dynamic "condition" {
for_each = rule.value.condition.expression != null ? [1] : []
content {
description = rule.value.condition.description
expression = rule.value.condition.expression
location = rule.value.condition.location
title = rule.value.condition.title
}
}
dynamic "values" {
for_each = rule.value.has_values ? [1] : []
@ -121,22 +113,5 @@ resource "google_org_policy_policy" "default" {
}
}
}
rules {
allow_all = try(each.value.allow.all, null) == true ? "TRUE" : null
deny_all = try(each.value.deny.all, null) == true ? "TRUE" : null
enforce = (
each.value.is_boolean_policy && each.value.enforce != null
? upper(tostring(each.value.enforce))
: null
)
dynamic "values" {
for_each = each.value.has_values ? [1] : []
content {
allowed_values = try(each.value.allow.values, null)
denied_values = try(each.value.deny.values, null)
}
}
}
}
}

View File

@ -1,5 +1,5 @@
/**
* Copyright 2022 Google LLC
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -147,19 +147,6 @@ variable "org_policies" {
type = map(object({
inherit_from_parent = optional(bool) # for list policies only.
reset = optional(bool)
# default (unconditional) values
allow = optional(object({
all = optional(bool)
values = optional(list(string))
}))
deny = optional(object({
all = optional(bool)
values = optional(list(string))
}))
enforce = optional(bool, true) # for boolean policies only.
# conditional values
rules = optional(list(object({
allow = optional(object({
all = optional(bool)
@ -169,13 +156,13 @@ variable "org_policies" {
all = optional(bool)
values = optional(list(string))
}))
enforce = optional(bool, true) # for boolean policies only.
condition = object({
enforce = optional(bool) # for boolean policies only.
condition = optional(object({
description = optional(string)
expression = optional(string)
location = optional(string)
title = optional(string)
})
}), {})
})), [])
}))
default = {}

View File

@ -1,4 +1,4 @@
# Copyright 2022 Google LLC
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -91,7 +91,7 @@ values:
- allow_all: null
condition:
- description: test condition
expression: resource.matchTagId("tagKeys/1234", "tagValues/1234")
expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234')
location: somewhere
title: condition
deny_all: null

View File

@ -1,9 +1,8 @@
org_policies = {
"iam.disableServiceAccountKeyCreation" = {
enforce = true
rules = [{ enforce = true }]
}
"iam.disableServiceAccountKeyUpload" = {
enforce = false
rules = [
{
condition = {
@ -13,6 +12,9 @@ org_policies = {
location = "xxx"
}
enforce = true
},
{
enforce = false
}
]
}

View File

@ -1,14 +1,15 @@
org_policies = {
"compute.vmExternalIpAccess" = {
deny = { all = true }
rules = [{ deny = { all = true } }]
}
"iam.allowedPolicyMemberDomains" = {
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
rules = [{
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
}]
}
"compute.restrictLoadBalancerCreationForTypes" = {
deny = { values = ["in:EXTERNAL"] }
rules = [
{
condition = {
@ -31,6 +32,9 @@ org_policies = {
allow = {
all = true
}
},
{
deny = { values = ["in:EXTERNAL"] }
}
]
}

View File

@ -71,8 +71,23 @@ values:
- inherit_from_parent: null
reset: null
rules:
- allow_all: 'TRUE'
condition:
- description: Allow external identities when resource has the `allowexternal`
tag set to true.
expression: resource.matchTag('1234567890/allowexternal', 'true')
location: null
title: Allow external identities
deny_all: null
enforce: null
values: []
- allow_all: null
condition: []
condition:
- description: For any resource without allowexternal=true, only allow identities
from restricted domains.
expression: '!resource.matchTag(''1234567890/allowexternal'', ''true'')'
location: null
title: ''
deny_all: null
enforce: null
values:
@ -102,7 +117,7 @@ values:
- allow_all: null
condition:
- description: test condition
expression: resource.matchTagId("tagKeys/1234", "tagValues/1234")
expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234')
location: somewhere
title: condition
deny_all: null
@ -141,6 +156,20 @@ values:
member: user:compute@example.org
org_id: '1234567890'
role: roles/container.viewer
module.org.google_tags_tag_key.default["allowexternal"]:
description: Allow external identities.
parent: organizations/1234567890
purpose: null
purpose_data: null
short_name: allowexternal
module.org.google_tags_tag_value.default["allowexternal/false"]:
short_name: 'false'
module.org.google_tags_tag_value.default["allowexternal/true"]:
short_name: 'true'
counts:
google_org_policy_policy: 8
google_organization_iam_binding: 3
google_organization_iam_member: 2
google_tags_tag_key: 1
google_tags_tag_value: 2

View File

@ -1,9 +1,9 @@
org_policies = {
"iam.disableServiceAccountKeyCreation" = {
enforce = true
rules = [{ enforce = true }]
}
"iam.disableServiceAccountKeyUpload" = {
enforce = false
rules = [
{
condition = {
@ -13,6 +13,9 @@ org_policies = {
location = "xxx"
}
enforce = true
},
{
enforce = false
}
]
}

View File

@ -1,15 +1,17 @@
org_policies = {
"compute.vmExternalIpAccess" = {
deny = { all = true }
rules = [{ deny = { all = true } }]
}
"iam.allowedPolicyMemberDomains" = {
inherit_from_parent = true
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
rules = [{
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
}]
}
"compute.restrictLoadBalancerCreationForTypes" = {
deny = { values = ["in:EXTERNAL"] }
rules = [
{
condition = {
@ -32,6 +34,9 @@ org_policies = {
allow = {
all = true
}
},
{
deny = { values = ["in:EXTERNAL"] }
}
]
}

View File

@ -1,4 +1,4 @@
# Copyright 2022 Google LLC
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -26,61 +26,35 @@ def test_policy_implementation():
path = modules_path / module / 'organization-policies.tf'
lines[module] = path.open().readlines()
diff1 = difflib.unified_diff(lines['project'], lines['folder'])
diff1 = difflib.unified_diff(lines['project'], lines['folder'], 'project',
'folder', n=0)
assert list(diff1) == [
'--- \n',
'+++ \n',
'@@ -14,7 +14,7 @@\n',
' * limitations under the License.\n',
' */\n',
' \n',
'--- project\n',
'+++ folder\n',
'@@ -17 +17 @@\n',
'-# tfdoc:file:description Project-level organization policies.\n',
'+# tfdoc:file:description Folder-level organization policies.\n',
' \n',
' locals {\n',
' _factory_data_raw = merge([\n',
'@@ -65,8 +65,8 @@\n',
' org_policies = {\n',
' for k, v in local._org_policies :\n',
' k => merge(v, {\n',
'@@ -58,2 +58,2 @@\n',
'- name = "projects/${local.project.project_id}/policies/${k}"\n',
'- parent = "projects/${local.project.project_id}"\n',
'+ name = "${local.folder.name}/policies/${k}"\n',
'+ parent = local.folder.name\n',
' \n',
' is_boolean_policy = v.allow == null && v.deny == null\n',
' has_values = (\n',
]
diff2 = difflib.unified_diff(lines['folder'], lines['organization'])
diff2 = difflib.unified_diff(lines['folder'], lines['organization'], 'folder',
'organization', n=0)
assert list(diff2) == [
'--- \n',
'+++ \n',
'@@ -14,7 +14,7 @@\n',
' * limitations under the License.\n',
' */\n',
' \n',
'--- folder\n',
'+++ organization\n',
'@@ -17 +17 @@\n',
'-# tfdoc:file:description Folder-level organization policies.\n',
'+# tfdoc:file:description Organization-level organization policies.\n',
' \n',
' locals {\n',
' _factory_data_raw = merge([\n',
'@@ -65,8 +65,8 @@\n',
' org_policies = {\n',
' for k, v in local._org_policies :\n',
' k => merge(v, {\n',
'@@ -58,2 +58,2 @@\n',
'- name = "${local.folder.name}/policies/${k}"\n',
'- parent = local.folder.name\n',
'+ name = "${var.organization_id}/policies/${k}"\n',
'+ parent = var.organization_id\n',
' \n',
' is_boolean_policy = v.allow == null && v.deny == null\n',
' has_values = (\n',
'@@ -139,4 +139,13 @@\n',
' }\n',
' }\n',
' }\n',
'+\n',
'@@ -116,0 +117,8 @@\n',
'+ depends_on = [\n',
'+ google_organization_iam_audit_config.config,\n',
'+ google_organization_iam_binding.authoritative,\n',
@ -89,5 +63,4 @@ def test_policy_implementation():
'+ google_organization_iam_policy.authoritative,\n',
'+ google_org_policy_custom_constraint.constraint,\n',
'+ ]\n',
' }\n',
]

View File

@ -1,4 +1,4 @@
# Copyright 2022 Google LLC
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -102,7 +102,7 @@ values:
- allow_all: null
condition:
- description: test condition
expression: resource.matchTagId("tagKeys/1234", "tagValues/1234")
expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234')
location: somewhere
title: condition
deny_all: null

View File

@ -1,9 +1,8 @@
org_policies = {
"iam.disableServiceAccountKeyCreation" = {
enforce = true
rules = [{ enforce = true }]
}
"iam.disableServiceAccountKeyUpload" = {
enforce = false
rules = [
{
condition = {
@ -13,6 +12,9 @@ org_policies = {
location = "xxx"
}
enforce = true
},
{
enforce = false
}
]
}

View File

@ -1,15 +1,17 @@
org_policies = {
"compute.vmExternalIpAccess" = {
deny = { all = true }
rules = [{ deny = { all = true } }]
}
"iam.allowedPolicyMemberDomains" = {
inherit_from_parent = true
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
rules = [{
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}
}]
}
"compute.restrictLoadBalancerCreationForTypes" = {
deny = { values = ["in:EXTERNAL"] }
rules = [
{
condition = {
@ -32,6 +34,9 @@ org_policies = {
allow = {
all = true
}
},
{
deny = { values = ["in:EXTERNAL"] }
}
]
}