OrgPolicy module (factory) using new org-policy API, #698

This commit is contained in:
Aleksandr Averbukh
2022-07-06 19:41:18 +02:00
parent 9336ac644d
commit a34983b2e9
11 changed files with 551 additions and 2 deletions

View File

@@ -0,0 +1,13 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

View File

@@ -0,0 +1,22 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
module "org-policy" {
source = "../../../../modules/organization-policy"
config_directory = var.config_directory
organization_policies = var.organization_policies
}

View File

@@ -0,0 +1,41 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
organizations/1234567890:
constraints/compute.vmExternalIpAccess:
rules:
- deny_all: true
folders/1234567890:
compute.vmCanIpForward:
inherit_from_parent: false
reset: false
rules:
- allow_all: true
projects/my-project-id:
run.allowedIngress:
inherit_from_parent: true
rules:
- condition:
description: allow internal ingress
expression: resource.matchTag("123456789/environment", "prod")
location: test.log
title: allow-for-prod
values:
allowed_values: ['internal']
iam.allowServiceAccountCredentialLifetimeExtension:
rules:
- allow_all: true
compute.disableGlobalLoadBalancing:
reset: true

View File

@@ -0,0 +1,31 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
variable "config_directory" {
description = "Paths to a folder where organization policy configs are stored in yaml format. Files suffix must be `.yaml`."
type = string
default = null
}
# TODO: convert to a proper data structure map(map(object({...}))) once tf1.3 is released and optional object keys are avaliable,
# for now it will cause multiple keys to be set to null for every policy definition
# https://github.com/hashicorp/terraform/releases/tag/v1.3.0-alpha20220622
variable "organization_policies" {
description = "Organization policies keyed by parent in format `projects/project-id`, `folders/1234567890` or `organizations/1234567890`."
type = any
default = {}
}

View File

@@ -0,0 +1,91 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def test_org_policy_simple(plan_runner):
"Test vpc with no extra options."
org_policies = (
'{'
'"folders/1234567890" = {'
' "constraints/iam.disableServiceAccountKeyUpload" = {'
' rules = ['
' {'
' enforce = true'
' }'
' ]'
' }'
' },'
' "organizations/1234567890" = {'
' "run.allowedIngress" = {'
' rules = ['
' {'
' condition = {'
' description= "allow ingress",'
' expression = "resource.matchTag(\'123456789/environment\', \'prod\')",'
' title = "allow-for-prod-org",'
' },'
' values = {'
' allowed_values = ["internal"]'
' }'
' }'
' ]'
' }'
' }'
'}'
)
_, resources = plan_runner(
organization_policies = org_policies
)
assert len(resources) == 2
org_policy = [r for r in resources if r["values"]
["name"].endswith('iam.disableServiceAccountKeyUpload')][0]["values"]
assert org_policy["parent"] == "folders/1234567890"
assert org_policy["spec"][0]["rules"][0]["enforce"] == "TRUE"
def test_org_policy_factory(plan_runner):
"Test yaml based configuration"
_, resources = plan_runner(
config_directory="./policies",
)
assert len(resources) == 5
org_policy = [r for r in resources if r["values"]
["name"].endswith('run.allowedIngress')][0]["values"]["spec"][0]
assert org_policy["inherit_from_parent"] == True
assert org_policy["rules"][0]["condition"][0]["title"] == "allow-for-prod"
assert set(org_policy["rules"][0]["values"][0]["allowed_values"]) == set(["internal"])
def test_combined_org_policy_config(plan_runner):
"Test combined (yaml, hcl) policy configuration"
org_policies = (
'{'
'"folders/3456789012" = {'
' "constraints/iam.disableServiceAccountKeyUpload" = {'
' rules = ['
' {'
' enforce = true'
' }'
' ]'
' }'
' }'
'}'
)
_, resources = plan_runner(
config_directory="./policies",
organization_policies = org_policies
)
assert len(resources) == 6