From d43c624f9ec6db066d7c0a24f51b8b66cb0cac5f Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 12 Feb 2025 20:38:44 +0100 Subject: [PATCH] Add new set of org policies with managed constraints to FAST bootstrap (#2884) * Managed org policies example * Add folder with managed org policies * Add tests for managed org policies * Document new managed org policy set --- fast/stages/0-bootstrap/README.md | 7 + .../data/org-policies-managed/compute.yaml | 133 ++++++ .../essentialcontacts.yaml | 35 ++ .../data/org-policies-managed/gcp.yaml | 25 ++ .../data/org-policies-managed/gke.yaml | 23 + .../data/org-policies-managed/iam.yaml | 53 +++ .../data/org-policies-managed/serverless.yaml | 53 +++ .../data/org-policies-managed/sql.yaml | 27 ++ .../data/org-policies-managed/storage.yaml | 32 ++ .../data/org-policies/compute.yaml | 11 +- tests/fast/stages/s0_bootstrap/cicd.yaml | 4 +- .../s0_bootstrap/managed_org_policies.tfvars | 20 + .../s0_bootstrap/managed_org_policies.yaml | 414 +++++++++++++++++ tests/fast/stages/s0_bootstrap/simple.yaml | 4 +- .../s0_bootstrap/simple_org_policies.yaml | 425 ++++++++++++++++++ tests/fast/stages/s0_bootstrap/tftest.yaml | 11 +- 16 files changed, 1266 insertions(+), 11 deletions(-) create mode 100644 fast/stages/0-bootstrap/data/org-policies-managed/compute.yaml create mode 100644 fast/stages/0-bootstrap/data/org-policies-managed/essentialcontacts.yaml create mode 100644 fast/stages/0-bootstrap/data/org-policies-managed/gcp.yaml create mode 100644 fast/stages/0-bootstrap/data/org-policies-managed/gke.yaml create mode 100644 fast/stages/0-bootstrap/data/org-policies-managed/iam.yaml create mode 100644 fast/stages/0-bootstrap/data/org-policies-managed/serverless.yaml create mode 100644 fast/stages/0-bootstrap/data/org-policies-managed/sql.yaml create mode 100644 fast/stages/0-bootstrap/data/org-policies-managed/storage.yaml create mode 100644 tests/fast/stages/s0_bootstrap/managed_org_policies.tfvars create mode 100644 tests/fast/stages/s0_bootstrap/managed_org_policies.yaml create mode 100644 tests/fast/stages/s0_bootstrap/simple_org_policies.yaml diff --git a/fast/stages/0-bootstrap/README.md b/fast/stages/0-bootstrap/README.md index 3abafcf2c..cbc9ea3b8 100644 --- a/fast/stages/0-bootstrap/README.md +++ b/fast/stages/0-bootstrap/README.md @@ -79,6 +79,13 @@ It's often desirable to have organization policies deployed before any other res To cover this use case, organization policies have been moved from the resource management to the bootstrap stage in FAST versions after 26.0.0. They are managed via the usual factory approach, and a [sample set of data files](./data/org-policies/) is included with this stage. They are not applied during the initial run when the `bootstrap_user` variable is set, to work around incompatibilities with user credentials. +FAST uses unmanaged organization policies by default. For those who prefer managed policies, a separate sample set is available. To use these managed policies, configure `factories_config` as shown below. + +```tfvars +factories_config = { + org_policies = "data/org-policies-managed" +} +``` #### Security Command Center Enterprise diff --git a/fast/stages/0-bootstrap/data/org-policies-managed/compute.yaml b/fast/stages/0-bootstrap/data/org-policies-managed/compute.yaml new file mode 100644 index 000000000..0cbe635ec --- /dev/null +++ b/fast/stages/0-bootstrap/data/org-policies-managed/compute.yaml @@ -0,0 +1,133 @@ +# Copyright 2025 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. + +--- +# sample subset of useful organization policies, edit to suit requirements +# start of document (---) avoids errors if the file only contains comments + +# yaml-language-server: $schema=../../schemas/org-policies.schema.json + +compute.disableGuestAttributesAccess: + rules: + - enforce: true + +compute.disableNestedVirtualization: + rules: + - enforce: true + +compute.disableSerialPortAccess: + rules: + - enforce: true + +compute.requireOsLogin: + rules: + - enforce: true + +compute.restrictLoadBalancerCreationForTypes: + rules: + - allow: + values: + - in:INTERNAL + +compute.skipDefaultNetworkCreation: + rules: + - enforce: true + +compute.setNewProjectDefaultToZonalDNSOnly: + rules: + - enforce: true + +# only allow GCP images by default +compute.trustedImageProjects: + rules: + - allow: + values: + - "is:projects/centos-cloud" + - "is:projects/cos-cloud" + - "is:projects/debian-cloud" + - "is:projects/fedora-cloud" + - "is:projects/fedora-coreos-cloud" + - "is:projects/opensuse-cloud" + - "is:projects/rhel-cloud" + - "is:projects/rhel-sap-cloud" + - "is:projects/rocky-linux-cloud" + - "is:projects/suse-cloud" + - "is:projects/suse-sap-cloud" + - "is:projects/ubuntu-os-cloud" + - "is:projects/ubuntu-os-pro-cloud" + - "is:projects/windows-cloud" + - "is:projects/windows-sql-cloud" + - "is:projects/confidential-vm-images" + - "is:projects/backupdr-images" + - "is:projects/deeplearning-platform-release" + - "is:projects/serverless-vpc-access-images" + +compute.vmExternalIpAccess: + rules: + - deny: + all: true + +# compute.disableInternetNetworkEndpointGroup: +# rules: +# - enforce: true + +# compute.restrictCloudNATUsage: +# rules: +# - deny: +# all: true + +# compute.restrictDedicatedInterconnectUsage: +# rules: +# - deny: +# all: true + +# compute.restrictPartnerInterconnectUsage: +# rules: +# - deny: +# all: true + +compute.managed.restrictProtocolForwardingCreationForTypes: + rules: + - enforce: true + parameters: | + {"allowedSchemes": ["INTERNAL"]} + +# compute.restrictSharedVpcHostProjects: +# rules: +# - deny: +# all: true + +# compute.restrictSharedVpcSubnetworks: +# rules: +# - deny: +# all: true + +# compute.restrictVpcPeering: +# rules: +# - deny: +# all: true + +# compute.restrictVpnPeerIPs: +# rules: +# - deny: +# all: true + +# compute.restrictXpnProjectLienRemoval: +# rules: +# - enforce: true + +# compute.vmCanIpForward: +# rules: +# - deny: +# all: true diff --git a/fast/stages/0-bootstrap/data/org-policies-managed/essentialcontacts.yaml b/fast/stages/0-bootstrap/data/org-policies-managed/essentialcontacts.yaml new file mode 100644 index 000000000..00dbc5083 --- /dev/null +++ b/fast/stages/0-bootstrap/data/org-policies-managed/essentialcontacts.yaml @@ -0,0 +1,35 @@ +# Copyright 2025 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. + +--- +# sample subset of useful organization policies, edit to suit requirements +# start of document (---) avoids errors if the file only contains comments + +# yaml-language-server: $schema=../../schemas/org-policies.schema.json + +essentialcontacts.allowedContactDomains: + rules: + - allow: + values: + - '@${organization.domain}' + condition: + title: Restrict essential contacts domains + expression: | + !resource.matchTag('${tags.org_policies_tag_name}', 'allowed-essential-contacts-domains-all') + - allow: + all: true + condition: + title: Allow essential contacts from any domain + expression: | + resource.matchTag('${tags.org_policies_tag_name}', 'allowed-essential-contacts-domains-all') diff --git a/fast/stages/0-bootstrap/data/org-policies-managed/gcp.yaml b/fast/stages/0-bootstrap/data/org-policies-managed/gcp.yaml new file mode 100644 index 000000000..d2440de46 --- /dev/null +++ b/fast/stages/0-bootstrap/data/org-policies-managed/gcp.yaml @@ -0,0 +1,25 @@ +# Copyright 2024 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. + +--- +# sample subset of useful organization policies, edit to suit requirements +# start of document (---) avoids errors if the file only contains comments + +# yaml-language-server: $schema=../../schemas/org-policies.schema.json + +# gcp.resourceLocations: +# rules: +# - allow: +# values: +# - "in:europe-locations" diff --git a/fast/stages/0-bootstrap/data/org-policies-managed/gke.yaml b/fast/stages/0-bootstrap/data/org-policies-managed/gke.yaml new file mode 100644 index 000000000..8991d327f --- /dev/null +++ b/fast/stages/0-bootstrap/data/org-policies-managed/gke.yaml @@ -0,0 +1,23 @@ +# Copyright 2025 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. + +--- +# sample subset of useful organization policies, edit to suit requirements +# start of document (---) avoids errors if the file only contains comments + +# yaml-language-server: $schema=../../schemas/org-policies.schema.json + +custom.disableKubeletReadOnlyPort: + rules: + - enforce: true diff --git a/fast/stages/0-bootstrap/data/org-policies-managed/iam.yaml b/fast/stages/0-bootstrap/data/org-policies-managed/iam.yaml new file mode 100644 index 000000000..5aed9e466 --- /dev/null +++ b/fast/stages/0-bootstrap/data/org-policies-managed/iam.yaml @@ -0,0 +1,53 @@ +# Copyright 2025 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. + +--- +# sample subset of useful organization policies, edit to suit requirements +# start of document (---) avoids errors if the file only contains comments + +# yaml-language-server: $schema=../../schemas/org-policies.schema.json + +iam.managed.allowedPolicyMembers: + rules: + - enforce: false + condition: + title: Allow any member domain + expression: | + resource.matchTag('${tags.org_policies_tag_name}', 'allowed-policy-member-domains-all') + + - enforce: true + parameters: >- + { + "allowedPrincipalSets": [ + "//cloudresourcemanager.googleapis.com/organizations/${organization.id}" + ] + } + +iam.managed.preventPrivilegedBasicRolesForDefaultServiceAccounts: + rules: + - enforce: true + +iam.managed.disableServiceAccountKeyCreation: + rules: + - enforce: true + +iam.managed.disableServiceAccountKeyUpload: + rules: + - enforce: true + +iam.serviceAccountKeyExposureResponse: + rules: + - allow: + values: + - DISABLE_KEY diff --git a/fast/stages/0-bootstrap/data/org-policies-managed/serverless.yaml b/fast/stages/0-bootstrap/data/org-policies-managed/serverless.yaml new file mode 100644 index 000000000..c1b939d44 --- /dev/null +++ b/fast/stages/0-bootstrap/data/org-policies-managed/serverless.yaml @@ -0,0 +1,53 @@ +# Copyright 2024 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. + +--- +# sample subset of useful organization policies, edit to suit requirements +# start of document (---) avoids errors if the file only contains comments + +# yaml-language-server: $schema=../../schemas/org-policies.schema.json + +run.allowedIngress: + rules: + - allow: + values: + - is:internal-and-cloud-load-balancing + +# run.allowedVPCEgress: +# rules: +# - allow: +# values: +# - is:private-ranges-only + +# cloudfunctions.allowedIngressSettings: +# rules: +# - allow: +# values: +# - is:ALLOW_INTERNAL_ONLY + +# cloudfunctions.allowedVpcConnectorEgressSettings: +# rules: +# - allow: +# values: +# - is:PRIVATE_RANGES_ONLY + +# cloudfunctions.requireVPCConnector: +# rules: +# - enforce: true + +# cloudfunctions.restrictAllowedGenerations: +# rules: +# - allow: +# values: +# - is:2ndGen diff --git a/fast/stages/0-bootstrap/data/org-policies-managed/sql.yaml b/fast/stages/0-bootstrap/data/org-policies-managed/sql.yaml new file mode 100644 index 000000000..d0fca4c65 --- /dev/null +++ b/fast/stages/0-bootstrap/data/org-policies-managed/sql.yaml @@ -0,0 +1,27 @@ +# Copyright 2024 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. + +--- +# sample subset of useful organization policies, edit to suit requirements +# start of document (---) avoids errors if the file only contains comments + +# yaml-language-server: $schema=../../schemas/org-policies.schema.json + +sql.restrictAuthorizedNetworks: + rules: + - enforce: true + +sql.restrictPublicIp: + rules: + - enforce: true diff --git a/fast/stages/0-bootstrap/data/org-policies-managed/storage.yaml b/fast/stages/0-bootstrap/data/org-policies-managed/storage.yaml new file mode 100644 index 000000000..03e38fafa --- /dev/null +++ b/fast/stages/0-bootstrap/data/org-policies-managed/storage.yaml @@ -0,0 +1,32 @@ +# Copyright 2024 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. + +--- +# sample subset of useful organization policies, edit to suit requirements +# start of document (---) avoids errors if the file only contains comments + +# yaml-language-server: $schema=../../schemas/org-policies.schema.json + +storage.uniformBucketLevelAccess: + rules: + - enforce: true + +storage.publicAccessPrevention: + rules: + - enforce: true + + +storage.secureHttpTransport: + rules: + - enforce: true diff --git a/fast/stages/0-bootstrap/data/org-policies/compute.yaml b/fast/stages/0-bootstrap/data/org-policies/compute.yaml index d1439e625..71d18c85e 100644 --- a/fast/stages/0-bootstrap/data/org-policies/compute.yaml +++ b/fast/stages/0-bootstrap/data/org-policies/compute.yaml @@ -1,4 +1,4 @@ -# Copyright 2024 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -97,10 +97,11 @@ compute.vmExternalIpAccess: # - deny: # all: true -# compute.restrictProtocolForwardingCreationForTypes: -# rules: -# - deny: -# all: true +compute.restrictProtocolForwardingCreationForTypes: + rules: + - allow: + values: + - in:INTERNAL # compute.restrictSharedVpcHostProjects: # rules: diff --git a/tests/fast/stages/s0_bootstrap/cicd.yaml b/tests/fast/stages/s0_bootstrap/cicd.yaml index c4935cb99..e531a1a1e 100644 --- a/tests/fast/stages/s0_bootstrap/cicd.yaml +++ b/tests/fast/stages/s0_bootstrap/cicd.yaml @@ -335,7 +335,7 @@ counts: google_logging_organization_sink: 4 google_logging_project_bucket_config: 4 google_org_policy_custom_constraint: 1 - google_org_policy_policy: 25 + google_org_policy_policy: 26 google_organization_iam_binding: 27 google_organization_iam_custom_role: 13 google_organization_iam_member: 29 @@ -356,4 +356,4 @@ counts: google_tags_tag_value: 2 local_file: 13 modules: 26 - resources: 273 + resources: 274 diff --git a/tests/fast/stages/s0_bootstrap/managed_org_policies.tfvars b/tests/fast/stages/s0_bootstrap/managed_org_policies.tfvars new file mode 100644 index 000000000..ecac88425 --- /dev/null +++ b/tests/fast/stages/s0_bootstrap/managed_org_policies.tfvars @@ -0,0 +1,20 @@ +billing_account = { + id = "000000-111111-222222" +} +essential_contacts = "gcp-organization-admins@fast.example.com" +factories_config = { + org_policies = "data/org-policies-managed" +} +groups = { + gcp-support = "group:gcp-support@example.com" +} +org_policies_config = { + import_defaults = false +} +organization = { + domain = "fast.example.com" + id = 123456789012 + customer_id = "C00000000" +} +outputs_location = "/fast-config" +prefix = "fast" diff --git a/tests/fast/stages/s0_bootstrap/managed_org_policies.yaml b/tests/fast/stages/s0_bootstrap/managed_org_policies.yaml new file mode 100644 index 000000000..c3d6f4504 --- /dev/null +++ b/tests/fast/stages/s0_bootstrap/managed_org_policies.yaml @@ -0,0 +1,414 @@ +# Copyright 2025 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. + +values: + module.organization.google_org_policy_custom_constraint.constraint["custom.disableKubeletReadOnlyPort"]: + action_type: DENY + condition: resource.nodeConfig.kubeletConfig.insecureKubeletReadonlyPortEnabled + == true + description: Disallows the use of Kubelet read-only port 10255 to enhance security + display_name: Disable Kubelet Read-Only Port 10255 + method_types: + - CREATE + - UPDATE + name: custom.disableKubeletReadOnlyPort + parent: organizations/123456789012 + resource_types: + - container.googleapis.com/Cluster + module.organization.google_org_policy_policy.default["compute.disableGuestAttributesAccess"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.disableGuestAttributesAccess + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.disableNestedVirtualization"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.disableNestedVirtualization + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.disableSerialPortAccess"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.disableSerialPortAccess + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.managed.restrictProtocolForwardingCreationForTypes"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.managed.restrictProtocolForwardingCreationForTypes + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: '{"allowedSchemes":["INTERNAL"]}' + values: [] + module.organization.google_org_policy_policy.default["compute.requireOsLogin"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.requireOsLogin + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.restrictLoadBalancerCreationForTypes"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.restrictLoadBalancerCreationForTypes + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - in:INTERNAL + denied_values: null + module.organization.google_org_policy_policy.default["compute.setNewProjectDefaultToZonalDNSOnly"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.setNewProjectDefaultToZonalDNSOnly + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.skipDefaultNetworkCreation + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.trustedImageProjects"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.trustedImageProjects + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - is:projects/centos-cloud + - is:projects/cos-cloud + - is:projects/debian-cloud + - is:projects/fedora-cloud + - is:projects/fedora-coreos-cloud + - is:projects/opensuse-cloud + - is:projects/rhel-cloud + - is:projects/rhel-sap-cloud + - is:projects/rocky-linux-cloud + - is:projects/suse-cloud + - is:projects/suse-sap-cloud + - is:projects/ubuntu-os-cloud + - is:projects/ubuntu-os-pro-cloud + - is:projects/windows-cloud + - is:projects/windows-sql-cloud + - is:projects/confidential-vm-images + - is:projects/backupdr-images + - is:projects/deeplearning-platform-release + - is:projects/serverless-vpc-access-images + denied_values: null + module.organization.google_org_policy_policy.default["compute.vmExternalIpAccess"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.vmExternalIpAccess + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: 'TRUE' + enforce: null + parameters: null + values: [] + module.organization.google_org_policy_policy.default["custom.disableKubeletReadOnlyPort"]: + dry_run_spec: [] + name: organizations/123456789012/policies/custom.disableKubeletReadOnlyPort + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["essentialcontacts.allowedContactDomains"]: + dry_run_spec: [] + name: organizations/123456789012/policies/essentialcontacts.allowedContactDomains + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: null + expression: '!resource.matchTag(''123456789012/org-policies'', ''allowed-essential-contacts-domains-all'') + + ' + location: null + title: Restrict essential contacts domains + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - '@fast.example.com' + denied_values: null + - allow_all: 'TRUE' + condition: + - description: null + expression: 'resource.matchTag(''123456789012/org-policies'', ''allowed-essential-contacts-domains-all'') + + ' + location: null + title: Allow essential contacts from any domain + deny_all: null + enforce: null + parameters: null + values: [] + module.organization.google_org_policy_policy.default["iam.managed.allowedPolicyMembers"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.managed.allowedPolicyMembers + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: null + expression: 'resource.matchTag(''123456789012/org-policies'', ''allowed-policy-member-domains-all'') + + ' + location: null + title: Allow any member domain + deny_all: null + enforce: 'FALSE' + parameters: null + values: [] + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: '{"allowedPrincipalSets":["//cloudresourcemanager.googleapis.com/organizations/123456789012"]}' + values: [] + module.organization.google_org_policy_policy.default["iam.managed.disableServiceAccountKeyCreation"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.managed.disableServiceAccountKeyCreation + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["iam.managed.disableServiceAccountKeyUpload"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.managed.disableServiceAccountKeyUpload + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["iam.managed.preventPrivilegedBasicRolesForDefaultServiceAccounts"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.managed.preventPrivilegedBasicRolesForDefaultServiceAccounts + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["iam.serviceAccountKeyExposureResponse"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.serviceAccountKeyExposureResponse + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - DISABLE_KEY + denied_values: null + module.organization.google_org_policy_policy.default["run.allowedIngress"]: + dry_run_spec: [] + name: organizations/123456789012/policies/run.allowedIngress + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - is:internal-and-cloud-load-balancing + denied_values: null + module.organization.google_org_policy_policy.default["sql.restrictAuthorizedNetworks"]: + dry_run_spec: [] + name: organizations/123456789012/policies/sql.restrictAuthorizedNetworks + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["sql.restrictPublicIp"]: + dry_run_spec: [] + name: organizations/123456789012/policies/sql.restrictPublicIp + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["storage.publicAccessPrevention"]: + dry_run_spec: [] + name: organizations/123456789012/policies/storage.publicAccessPrevention + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["storage.secureHttpTransport"]: + dry_run_spec: [] + name: organizations/123456789012/policies/storage.secureHttpTransport + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["storage.uniformBucketLevelAccess"]: + dry_run_spec: [] + name: organizations/123456789012/policies/storage.uniformBucketLevelAccess + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + diff --git a/tests/fast/stages/s0_bootstrap/simple.yaml b/tests/fast/stages/s0_bootstrap/simple.yaml index 23f12f0a0..0cb3385a8 100644 --- a/tests/fast/stages/s0_bootstrap/simple.yaml +++ b/tests/fast/stages/s0_bootstrap/simple.yaml @@ -20,7 +20,7 @@ counts: google_logging_organization_sink: 4 google_logging_project_bucket_config: 4 google_org_policy_custom_constraint: 1 - google_org_policy_policy: 25 + google_org_policy_policy: 26 google_organization_iam_binding: 27 google_organization_iam_custom_role: 13 google_organization_iam_member: 29 @@ -41,7 +41,7 @@ counts: google_tags_tag_value: 2 local_file: 8 modules: 20 - resources: 236 + resources: 237 outputs: automation: __missing__ diff --git a/tests/fast/stages/s0_bootstrap/simple_org_policies.yaml b/tests/fast/stages/s0_bootstrap/simple_org_policies.yaml new file mode 100644 index 000000000..c1fe6be93 --- /dev/null +++ b/tests/fast/stages/s0_bootstrap/simple_org_policies.yaml @@ -0,0 +1,425 @@ +# Copyright 2025 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. + +values: + module.organization.google_org_policy_custom_constraint.constraint["custom.disableKubeletReadOnlyPort"]: + action_type: DENY + condition: resource.nodeConfig.kubeletConfig.insecureKubeletReadonlyPortEnabled + == true + description: Disallows the use of Kubelet read-only port 10255 to enhance security + display_name: Disable Kubelet Read-Only Port 10255 + method_types: + - CREATE + - UPDATE + name: custom.disableKubeletReadOnlyPort + parent: organizations/123456789012 + resource_types: + - container.googleapis.com/Cluster + module.organization.google_org_policy_policy.default["compute.disableGuestAttributesAccess"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.disableGuestAttributesAccess + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.disableNestedVirtualization"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.disableNestedVirtualization + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.disableSerialPortAccess"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.disableSerialPortAccess + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.requireOsLogin"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.requireOsLogin + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.restrictLoadBalancerCreationForTypes"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.restrictLoadBalancerCreationForTypes + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - in:INTERNAL + denied_values: null + module.organization.google_org_policy_policy.default["compute.restrictProtocolForwardingCreationForTypes"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.restrictProtocolForwardingCreationForTypes + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - in:INTERNAL + denied_values: null + module.organization.google_org_policy_policy.default["compute.setNewProjectDefaultToZonalDNSOnly"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.setNewProjectDefaultToZonalDNSOnly + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.skipDefaultNetworkCreation + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["compute.trustedImageProjects"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.trustedImageProjects + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - is:projects/centos-cloud + - is:projects/cos-cloud + - is:projects/debian-cloud + - is:projects/fedora-cloud + - is:projects/fedora-coreos-cloud + - is:projects/opensuse-cloud + - is:projects/rhel-cloud + - is:projects/rhel-sap-cloud + - is:projects/rocky-linux-cloud + - is:projects/suse-cloud + - is:projects/suse-sap-cloud + - is:projects/ubuntu-os-cloud + - is:projects/ubuntu-os-pro-cloud + - is:projects/windows-cloud + - is:projects/windows-sql-cloud + - is:projects/confidential-vm-images + - is:projects/backupdr-images + - is:projects/deeplearning-platform-release + - is:projects/serverless-vpc-access-images + denied_values: null + module.organization.google_org_policy_policy.default["compute.vmExternalIpAccess"]: + dry_run_spec: [] + name: organizations/123456789012/policies/compute.vmExternalIpAccess + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: 'TRUE' + enforce: null + parameters: null + values: [] + module.organization.google_org_policy_policy.default["custom.disableKubeletReadOnlyPort"]: + dry_run_spec: [] + name: organizations/123456789012/policies/custom.disableKubeletReadOnlyPort + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["essentialcontacts.allowedContactDomains"]: + dry_run_spec: [] + name: organizations/123456789012/policies/essentialcontacts.allowedContactDomains + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: null + expression: '!resource.matchTag(''123456789012/org-policies'', ''allowed-essential-contacts-domains-all'') + + ' + location: null + title: Restrict essential contacts domains + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - '@fast.example.com' + denied_values: null + - allow_all: 'TRUE' + condition: + - description: null + expression: 'resource.matchTag(''123456789012/org-policies'', ''allowed-essential-contacts-domains-all'') + + ' + location: null + title: Allow essential contacts from any domain + deny_all: null + enforce: null + parameters: null + values: [] + module.organization.google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.allowedPolicyMemberDomains + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: null + expression: '!resource.matchTag(''123456789012/org-policies'', ''allowed-policy-member-domains-all'') + + ' + location: null + title: Restrict member domains + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - C00000000 + denied_values: null + - allow_all: 'TRUE' + condition: + - description: null + expression: 'resource.matchTag(''123456789012/org-policies'', ''allowed-policy-member-domains-all'') + + ' + location: null + title: Allow any member domain + deny_all: null + enforce: null + parameters: null + values: [] + module.organization.google_org_policy_policy.default["iam.automaticIamGrantsForDefaultServiceAccounts"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.automaticIamGrantsForDefaultServiceAccounts + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.disableServiceAccountKeyCreation + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.disableServiceAccountKeyUpload + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["iam.serviceAccountKeyExposureResponse"]: + dry_run_spec: [] + name: organizations/123456789012/policies/iam.serviceAccountKeyExposureResponse + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - DISABLE_KEY + denied_values: null + module.organization.google_org_policy_policy.default["run.allowedIngress"]: + dry_run_spec: [] + name: organizations/123456789012/policies/run.allowedIngress + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - is:internal-and-cloud-load-balancing + denied_values: null + module.organization.google_org_policy_policy.default["sql.restrictAuthorizedNetworks"]: + dry_run_spec: [] + name: organizations/123456789012/policies/sql.restrictAuthorizedNetworks + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["sql.restrictPublicIp"]: + dry_run_spec: [] + name: organizations/123456789012/policies/sql.restrictPublicIp + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["storage.publicAccessPrevention"]: + dry_run_spec: [] + name: organizations/123456789012/policies/storage.publicAccessPrevention + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["storage.secureHttpTransport"]: + dry_run_spec: [] + name: organizations/123456789012/policies/storage.secureHttpTransport + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + module.organization.google_org_policy_policy.default["storage.uniformBucketLevelAccess"]: + dry_run_spec: [] + name: organizations/123456789012/policies/storage.uniformBucketLevelAccess + parent: organizations/123456789012 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] diff --git a/tests/fast/stages/s0_bootstrap/tftest.yaml b/tests/fast/stages/s0_bootstrap/tftest.yaml index b51af9e3f..9d72b9c8e 100644 --- a/tests/fast/stages/s0_bootstrap/tftest.yaml +++ b/tests/fast/stages/s0_bootstrap/tftest.yaml @@ -1,5 +1,5 @@ # skip boilerplate check -# Copyright 2024 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,5 +20,12 @@ tests: - simple.yaml - simple_projects.yaml - simple_sas.yaml + - simple_org_policies.yaml + managed_org_policies: + inventory: + - simple.yaml + - simple_projects.yaml + - simple_sas.yaml + - managed_org_policies.yaml iam_by_principals: - cicd: \ No newline at end of file + cicd: