Simplify org policies data model in resman modules.
This commit is contained in:
parent
77df3c8721
commit
6b767c9035
|
@ -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" = {
|
||||
rules = [{
|
||||
allow = {
|
||||
values = ["C0xxxxxxx", "C0yyyyyyy"]
|
||||
}
|
||||
}]
|
||||
}
|
||||
"constraints/compute.trustedImageProjects" = {
|
||||
rules = [{
|
||||
allow = {
|
||||
values = ["projects/my-project"]
|
||||
}
|
||||
}]
|
||||
}
|
||||
"constraints/compute.vmExternalIpAccess" = {
|
||||
deny = { all = true }
|
||||
rules = [{ deny = { all = true } }]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,12 +95,15 @@ resource "google_org_policy_policy" "default" {
|
|||
? upper(tostring(rule.value.enforce))
|
||||
: null
|
||||
)
|
||||
condition {
|
||||
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] : []
|
||||
content {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = {}
|
||||
|
|
|
@ -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" = {
|
||||
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 }]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,12 +95,15 @@ resource "google_org_policy_policy" "default" {
|
|||
? upper(tostring(rule.value.enforce))
|
||||
: null
|
||||
)
|
||||
condition {
|
||||
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] : []
|
||||
content {
|
||||
|
@ -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,
|
||||
|
|
|
@ -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 = {}
|
||||
|
|
|
@ -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" = {
|
||||
rules = [{
|
||||
allow = {
|
||||
values = ["C0xxxxxxx", "C0yyyyyyy"]
|
||||
}
|
||||
}]
|
||||
}
|
||||
"constraints/compute.trustedImageProjects" = {
|
||||
rules = [{
|
||||
allow = {
|
||||
values = ["projects/my-project"]
|
||||
}
|
||||
}]
|
||||
}
|
||||
"constraints/compute.vmExternalIpAccess" = {
|
||||
deny = { all = true }
|
||||
rules = [{ deny = { all = true } }]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,33 +312,39 @@ 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:
|
||||
rules:
|
||||
- allow:
|
||||
values:
|
||||
- projects/my-project
|
||||
constraints/compute.vmExternalIpAccess:
|
||||
deny:
|
||||
rules:
|
||||
- deny:
|
||||
all: true
|
||||
constraints/iam.allowedPolicyMemberDomains:
|
||||
allow:
|
||||
rules:
|
||||
- allow:
|
||||
values:
|
||||
- C0xxxxxxx
|
||||
- C0yyyyyyy
|
||||
|
|
|
@ -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,12 +95,15 @@ resource "google_org_policy_policy" "default" {
|
|||
? upper(tostring(rule.value.enforce))
|
||||
: null
|
||||
)
|
||||
condition {
|
||||
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] : []
|
||||
content {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = {}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
org_policies = {
|
||||
"compute.vmExternalIpAccess" = {
|
||||
deny = { all = true }
|
||||
rules = [{ deny = { all = true } }]
|
||||
}
|
||||
"iam.allowedPolicyMemberDomains" = {
|
||||
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"] }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
org_policies = {
|
||||
"compute.vmExternalIpAccess" = {
|
||||
deny = { all = true }
|
||||
rules = [{ deny = { all = true } }]
|
||||
}
|
||||
"iam.allowedPolicyMemberDomains" = {
|
||||
inherit_from_parent = true
|
||||
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"] }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
org_policies = {
|
||||
"compute.vmExternalIpAccess" = {
|
||||
deny = { all = true }
|
||||
rules = [{ deny = { all = true } }]
|
||||
}
|
||||
"iam.allowedPolicyMemberDomains" = {
|
||||
inherit_from_parent = true
|
||||
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"] }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue