├── .github ├── conventional-commit-lint.yaml ├── release-please.yml ├── renovate.json ├── trusted-contribution.yml └── workflows │ ├── lint.yaml │ └── stale.yml ├── .gitignore ├── .kitchen.yml ├── CHANGELOG.md ├── CODEOWNERS ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── boolean_constraints.tf ├── build ├── int.cloudbuild.yaml └── lint.cloudbuild.yaml ├── docs └── upgrading_to_v3.0.md ├── examples ├── basic_org_policies │ ├── README.md │ ├── main.tf │ └── variables.tf ├── boolean_org_exclude │ ├── README.md │ ├── main.tf │ └── variables.tf ├── boolean_project_allow │ ├── README.md │ ├── main.tf │ └── variables.tf ├── list_folder_deny │ ├── README.md │ ├── main.tf │ └── variables.tf ├── list_org_exclude │ ├── README.md │ ├── main.tf │ └── variables.tf └── v2_boolean_org_enforce │ ├── README.md │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── list_constraints.tf ├── main.tf ├── metadata.yaml ├── modules ├── bucket_policy_only │ ├── README.md │ ├── main.tf │ ├── metadata.yaml │ ├── variables.tf │ └── versions.tf ├── domain_restricted_sharing │ ├── README.md │ ├── main.tf │ ├── metadata.yaml │ ├── variables.tf │ └── versions.tf ├── org_policy_v2 │ ├── README.md │ ├── boolean_constraints.tf │ ├── list_constraints.tf │ ├── main.tf │ ├── metadata.yaml │ ├── outputs.tf │ ├── variables.tf │ └── versions.tf ├── restrict_vm_external_ips │ ├── README.md │ ├── main.tf │ ├── metadata.yaml │ ├── variables.tf │ └── versions.tf └── skip_default_network │ ├── README.md │ ├── main.tf │ ├── metadata.yaml │ ├── variables.tf │ └── versions.tf ├── outputs.tf ├── test ├── .gitignore ├── fixtures │ ├── boolean_org_exclude │ │ ├── main.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── boolean_project_allow │ │ ├── main.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ ├── list_folder_deny │ │ ├── main.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf │ └── list_org_exclude │ │ ├── main.tf │ │ ├── outputs.tf │ │ ├── variables.tf │ │ └── versions.tf ├── integration │ ├── boolean_org_exclude │ │ ├── controls │ │ │ └── gcloud.rb │ │ └── inspec.yml │ ├── boolean_project_allow │ │ ├── controls │ │ │ └── gcloud.rb │ │ └── inspec.yml │ ├── discover_test.go │ ├── go.mod │ ├── go.sum │ ├── list_folder_deny │ │ ├── controls │ │ │ └── gcloud.rb │ │ └── inspec.yml │ ├── list_org_exclude │ │ ├── controls │ │ │ └── gcloud.rb │ │ └── inspec.yml │ └── v2_boolean_org_enforce │ │ └── v2_boolean_org_enforce_test.go └── setup │ ├── .gitignore │ ├── iam.tf │ ├── main.tf │ ├── outputs.tf │ ├── variables.tf │ └── versions.tf ├── variables.tf └── versions.tf /.github/conventional-commit-lint.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # NOTE: This file is automatically generated from: 16 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/github 17 | 18 | enabled: true 19 | always_check_pr_title: true 20 | -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | releaseType: terraform-module 16 | handleGHRelease: true 17 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["github>GoogleCloudPlatform/cloud-foundation-toolkit//infra/terraform/test-org/github/resources/renovate"] 4 | } 5 | -------------------------------------------------------------------------------- /.github/trusted-contribution.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # NOTE: This file is automatically generated from: 16 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/github 17 | 18 | annotations: 19 | - type: comment 20 | text: "/gcbrun" 21 | trustedContributors: 22 | - release-please[bot] 23 | - renovate[bot] 24 | - renovate-bot 25 | - forking-renovate[bot] 26 | - dependabot[bot] 27 | -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # NOTE: This file is automatically generated from values at: 16 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/org/locals.tf 17 | 18 | name: 'lint' 19 | 20 | on: 21 | workflow_dispatch: 22 | pull_request: 23 | branches: 24 | - main 25 | 26 | concurrency: 27 | group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}' 28 | cancel-in-progress: true 29 | 30 | jobs: 31 | lint: 32 | name: 'lint' 33 | runs-on: 'ubuntu-latest' 34 | steps: 35 | - uses: 'actions/checkout@v4' 36 | - id: variables 37 | run: | 38 | MAKEFILE=$(find . -name Makefile -print -quit) 39 | if [ -z "$MAKEFILE" ]; then 40 | echo dev-tools=gcr.io/cloud-foundation-cicd/cft/developer-tools:1 >> "$GITHUB_OUTPUT" 41 | else 42 | VERSION=$(grep "DOCKER_TAG_VERSION_DEVELOPER_TOOLS := " $MAKEFILE | cut -d\ -f3) 43 | IMAGE=$(grep "DOCKER_IMAGE_DEVELOPER_TOOLS := " $MAKEFILE | cut -d\ -f3) 44 | REGISTRY=$(grep "REGISTRY_URL := " $MAKEFILE | cut -d\ -f3) 45 | echo dev-tools=${REGISTRY}/${IMAGE}:${VERSION} >> "$GITHUB_OUTPUT" 46 | fi 47 | - run: docker run --rm -e ENABLE_BPMETADATA -v ${{ github.workspace }}:/workspace ${{ steps.variables.outputs.dev-tools }} module-swapper 48 | env: 49 | ENABLE_BPMETADATA: 1 50 | 51 | - run: docker run --rm -e ENABLE_BPMETADATA -v ${{ github.workspace }}:/workspace ${{ steps.variables.outputs.dev-tools }} /usr/local/bin/test_lint.sh 52 | env: 53 | ENABLE_BPMETADATA: 1 54 | 55 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # NOTE: This file is automatically generated from: 16 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/github 17 | 18 | name: "Close stale issues" 19 | on: 20 | schedule: 21 | - cron: "0 23 * * *" 22 | 23 | jobs: 24 | stale: 25 | if: github.repository_owner == 'GoogleCloudPlatform' || github.repository_owner == 'terraform-google-modules' 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/stale@v9 29 | with: 30 | repo-token: ${{ secrets.GITHUB_TOKEN }} 31 | stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days' 32 | stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days' 33 | exempt-issue-labels: 'triaged' 34 | exempt-pr-labels: 'dependencies,autorelease: pending' 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX leaves these everywhere on SMB shares 2 | ._* 3 | 4 | # OSX trash 5 | .DS_Store 6 | *.pyc* 7 | 8 | # Emacs save files 9 | *~ 10 | \#*\# 11 | .\#* 12 | 13 | # Vim-related files 14 | [._]*.s[a-w][a-z] 15 | [._]s[a-w][a-z] 16 | *.un~ 17 | Session.vim 18 | .netrwhist 19 | 20 | ### https://raw.github.com/github/gitignore/90f149de451a5433aebd94d02d11b0e28843a1af/Terraform.gitignore 21 | 22 | # Local .terraform directories 23 | **/.terraform/* 24 | 25 | # .tfstate files 26 | *.tfstate 27 | *.tfstate.* 28 | 29 | # Crash log files 30 | crash.log 31 | 32 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 33 | # .tfvars files are managed as part of configuration and so should be included in 34 | # version control. 35 | # 36 | # example.tfvars 37 | 38 | # Files used for testing 39 | **/terraform.tfvars 40 | 41 | # Secrets 42 | credentials.json 43 | 44 | # Test files 45 | .kitchen/ 46 | 47 | # tf lock file 48 | .terraform.lock.hcl 49 | 50 | -------------------------------------------------------------------------------- /.kitchen.yml: -------------------------------------------------------------------------------- 1 | 2 | # Copyright 2019 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | --- 17 | provisioner: 18 | name: terraform 19 | 20 | platforms: 21 | - name: local 22 | 23 | verifier: 24 | name: terraform 25 | color: false 26 | systems: 27 | - name: system 28 | backend: local 29 | 30 | suites: 31 | - name: boolean_org_exclude 32 | driver: 33 | name: terraform 34 | command_timeout: 1800 35 | root_module_directory: test/fixtures/boolean_org_exclude 36 | verify_version: false 37 | - name: boolean_project_allow 38 | driver: 39 | name: terraform 40 | command_timeout: 1800 41 | root_module_directory: test/fixtures/boolean_project_allow 42 | verify_version: false 43 | - name: list_folder_deny 44 | driver: 45 | name: terraform 46 | command_timeout: 1800 47 | root_module_directory: test/fixtures/list_folder_deny 48 | verify_version: false 49 | - name: list_org_exclude 50 | driver: 51 | name: terraform 52 | command_timeout: 1800 53 | root_module_directory: test/fixtures/list_org_exclude 54 | verify_version: false 55 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [7.0.0](https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v6.0.0...v7.0.0) (2025-02-04) 8 | 9 | 10 | ### ⚠ BREAKING CHANGES 11 | 12 | * **TPG>=6.14:** add parameter field support into org policy ([#163](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/163)) 13 | 14 | ### Features 15 | 16 | * **TPG>=6.14:** add parameter field support into org policy ([#163](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/163)) ([974d1c0](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/974d1c09e3a886e99ed5eecbd438177522445299)) 17 | 18 | ## [6.0.0](https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v5.4.0...v6.0.0) (2025-01-08) 19 | 20 | 21 | ### ⚠ BREAKING CHANGES 22 | 23 | * **TF>=1.3:** update terraform & metadata ([#156](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/156)) 24 | 25 | ### Features 26 | 27 | * add variable validation in org policy v2 ([#149](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/149)) ([4fc5fc5](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/4fc5fc5255344c6e9e3bc77d352c87eaa1618a3e)) 28 | 29 | 30 | ### Bug Fixes 31 | 32 | * **docs:** Input policy rule limit change from documentation ([#157](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/157)) ([f90dd34](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/f90dd342100ef220dba47a57f67021a5f1a14130)) 33 | * **TF>=1.3:** update terraform & metadata ([#156](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/156)) ([4bb7b4a](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/4bb7b4a4bfb21bfe284b575b2688570bf3b5a22c)) 34 | 35 | ## [5.4.0](https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v5.3.0...v5.4.0) (2024-08-29) 36 | 37 | 38 | ### Features 39 | 40 | * **deps:** Update Terraform Google Provider to v6 (major) ([#143](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/143)) ([f08651d](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/f08651d9c3e8aafb2b68b4e0401e24e428e8bf82)) 41 | 42 | ## [5.3.0](https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v5.2.2...v5.3.0) (2023-11-14) 43 | 44 | 45 | ### Features 46 | 47 | * support inheritance for list constraints on v2 module ([#104](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/104)) ([c4c4663](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/c4c4663aa56bacd72b19354747a117848f0ec955)) 48 | 49 | 50 | ### Bug Fixes 51 | 52 | * upgraded versions.tf to include minor bumps from tpg v5 ([#106](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/106)) ([d482c74](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/d482c743950df6b1d23285fdee4027f782c8e818)) 53 | 54 | ## [5.2.2](https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v5.2.1...v5.2.2) (2023-01-04) 55 | 56 | 57 | ### Bug Fixes 58 | 59 | * relax null provider constraint ([#79](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/79)) ([0ba6c56](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/0ba6c56303ec8d92762e41662a609e52a038af30)) 60 | * specify rules variable type in org_policy_v2 ([#73](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/73)) ([8ef6e1f](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/8ef6e1fb6a4028cb9b69c07fd0f92cb5bfda2cc0)) 61 | 62 | ## [5.2.1](https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v5.2.0...v5.2.1) (2022-12-29) 63 | 64 | 65 | ### Bug Fixes 66 | 67 | * fix folder and project exclusions ([#71](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/71)) ([182c272](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/182c27202c90d087a405f252884fce434cbdfd3a)) 68 | * fixes lint issues and generates metadata ([#72](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/72)) ([b800144](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/b80014487aba21ea1ff534f16d4dc3936af89dae)) 69 | 70 | ## [5.2.0](https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v5.1.0...v5.2.0) (2022-09-01) 71 | 72 | 73 | ### Features 74 | 75 | * added org_policy_v2 as a submodule supporting conditions ([#58](https://github.com/terraform-google-modules/terraform-google-org-policy/issues/58)) ([af5e9de](https://github.com/terraform-google-modules/terraform-google-org-policy/commit/af5e9dee506032c8daa8f86ddab6fa07672750e2)) 76 | 77 | ## [5.1.0](https://www.github.com/terraform-google-modules/terraform-google-org-policy/compare/v5.0.0...v5.1.0) (2021-12-20) 78 | 79 | 80 | ### Features 81 | 82 | * update TPG version constraints to allow 4.0 ([#52](https://www.github.com/terraform-google-modules/terraform-google-org-policy/issues/52)) ([2d39ed9](https://www.github.com/terraform-google-modules/terraform-google-org-policy/commit/2d39ed989b09841aacc738121d0909f5e94efa22)) 83 | 84 | ## [5.0.0](https://www.github.com/terraform-google-modules/terraform-google-org-policy/compare/v4.0.0...v5.0.0) (2021-03-19) 85 | 86 | 87 | ### ⚠ BREAKING CHANGES 88 | 89 | * add Terraform 0.13 constraint and module attribution (#43) 90 | 91 | ### Features 92 | 93 | * add Terraform 0.13 constraint and module attribution ([#43](https://www.github.com/terraform-google-modules/terraform-google-org-policy/issues/43)) ([61cd430](https://www.github.com/terraform-google-modules/terraform-google-org-policy/commit/61cd4309985c32707e19e5de9016e6feec6ecefa)) 94 | 95 | 96 | ### Bug Fixes 97 | 98 | * Change exclusion variables in submodules to accept sets ([#44](https://www.github.com/terraform-google-modules/terraform-google-org-policy/issues/44)) ([20b6a30](https://www.github.com/terraform-google-modules/terraform-google-org-policy/commit/20b6a30f0d6590b3d70c20d5c024d6c39adab722)) 99 | 100 | ## [4.0.0](https://www.github.com/terraform-google-modules/terraform-google-org-policy/compare/v3.0.2...v4.0.0) (2020-12-08) 101 | 102 | 103 | ### ⚠ BREAKING CHANGES 104 | 105 | * The exclusions have had their state location changed and will be recreated (this is a no-op). 106 | 107 | ### Features 108 | 109 | * Make exclude_folders and exclude_projects use sets and use for_each to avoid unnecessary resource updates ([#32](https://www.github.com/terraform-google-modules/terraform-google-org-policy/issues/32)) ([5d552af](https://www.github.com/terraform-google-modules/terraform-google-org-policy/commit/5d552afaf5523dd1434066a047824e09b96cf42f)) 110 | 111 | 112 | ### Bug Fixes 113 | 114 | * relax version constraints to enable terraform 0.13.x compatibility ([#37](https://www.github.com/terraform-google-modules/terraform-google-org-policy/issues/37)) ([d29507e](https://www.github.com/terraform-google-modules/terraform-google-org-policy/commit/d29507eeea8a4aa15713c435f4c15cc24254d1f9)) 115 | * use correct module names in documentation ([#30](https://www.github.com/terraform-google-modules/terraform-google-org-policy/issues/30)) ([235338d](https://www.github.com/terraform-google-modules/terraform-google-org-policy/commit/235338d6e9e1fcfad703be1c67ca8de2df1928a4)) 116 | 117 | ### [3.0.2](https://www.github.com/terraform-google-modules/terraform-google-org-policy/compare/v3.0.1...v3.0.2) (2020-02-05) 118 | 119 | 120 | ### Bug Fixes 121 | 122 | * Allow for provider 3.x ([#28](https://www.github.com/terraform-google-modules/terraform-google-org-policy/issues/28)) ([bbcf4c1](https://www.github.com/terraform-google-modules/terraform-google-org-policy/commit/bbcf4c1c14597c8ba51480d928fcb748d9355051)) 123 | 124 | ## [Unreleased] 125 | 126 | Please add new unreleased features here. 127 | 128 | ## [3.1.0] - 2019-12-05 129 | 130 | ### Added 131 | 132 | - submodules `bucket_policy_only`, `domain_restricted_sharing`, `restrict_vm_external_ips`, `skip_default_network` [#15] 133 | 134 | ## [3.0.1] - 2019-10-31 :jack_o_lantern: 135 | 136 | ### Fixed 137 | 138 | - The logic controlling the interaction bentween the variables `enforce`, `allow`, and `deny`. [#12] 139 | 140 | ## [3.0.0] - 2019-10-17 141 | v3.0.0 is a backwards-incompatible release. Please see the [upgrading guide](./docs/upgrading_to_v3.0.md). 142 | ### Changed 143 | 144 | - **Breaking**: Fixed combining with folders/projects creation by adding `policy_for` input variable. [#19] 145 | 146 | ## [2.0.0] - 2019-07-25 147 | 148 | ### Changed 149 | 150 | - Supported version of Terraform is 0.12. [#11] 151 | 152 | ## [1.0.0] 153 | 154 | This is the initial release of the module, with full support for org policy management. 155 | 156 | [Unreleased]: https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v3.1.0...HEAD 157 | [3.1.0]: https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v3.0.1...v3.1.0 158 | [3.0.1]: https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v3.0.0...v3.0.1 159 | [3.0.0]: https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v2.0.0...v3.0.0 160 | [2.0.0]: https://github.com/terraform-google-modules/terraform-google-org-policy/compare/v1.0.0...v2.0.0 161 | [1.0.0]: https://github.com/terraform-google-modules/terraform-google-org-policy/releases/tag/v1.0.0 162 | 163 | [#12]: https://github.com/terraform-google-modules/terraform-google-org-policy/issues/12 164 | [#11]: https://github.com/terraform-google-modules/terraform-google-org-policy/pull/11 165 | [#18]: https://github.com/terraform-google-modules/terraform-google-org-policy/pull/18 166 | [#19]: https://github.com/terraform-google-modules/terraform-google-org-policy/pull/19 167 | [#15]: https://github.com/terraform-google-modules/terraform-google-org-policy/issues/15 168 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # NOTE: This file is automatically generated from values at: 2 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/org/locals.tf 3 | 4 | * @terraform-google-modules/cft-admins @nehalk-tf 5 | 6 | # NOTE: GitHub CODEOWNERS locations: 7 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-and-branch-protection 8 | 9 | CODEOWNERS @terraform-google-modules/cft-admins 10 | .github/CODEOWNERS @terraform-google-modules/cft-admins 11 | docs/CODEOWNERS @terraform-google-modules/cft-admins 12 | 13 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This document provides guidelines for contributing to the module. 4 | 5 | ## Dependencies 6 | 7 | The following dependencies must be installed on the development system: 8 | 9 | - [Docker Engine][docker-engine] 10 | - [Google Cloud SDK][google-cloud-sdk] 11 | - [make] 12 | 13 | ## Generating Documentation for Inputs and Outputs 14 | 15 | The Inputs and Outputs tables in the READMEs of the root module, 16 | submodules, and example modules are automatically generated based on 17 | the `variables` and `outputs` of the respective modules. These tables 18 | must be refreshed if the module interfaces are changed. 19 | 20 | ### Execution 21 | 22 | Run `make generate_docs` to generate new Inputs and Outputs tables. 23 | 24 | ## Integration Testing 25 | 26 | Integration tests are used to verify the behaviour of the root module, 27 | submodules, and example modules. Additions, changes, and fixes should 28 | be accompanied with tests. 29 | 30 | The integration tests are run using [Kitchen][kitchen], 31 | [Kitchen-Terraform][kitchen-terraform], and [InSpec][inspec]. These 32 | tools are packaged within a Docker image for convenience. 33 | 34 | The general strategy for these tests is to verify the behaviour of the 35 | [example modules](./examples/), thus ensuring that the root module, 36 | submodules, and example modules are all functionally correct. 37 | 38 | ### Test Environment 39 | The easiest way to test the module is in an isolated test project. The setup for such a project is defined in [test/setup](./test/setup/) directory. 40 | 41 | To use this setup, you need a service account with these permissions: 42 | - Project Creator (on a Folder or Organization level) 43 | - Project Billing Manager (on a Folder or Organization level) 44 | - IAM Security Admin (Organization level) 45 | 46 | The project that the service account belongs to must have the following APIs enabled (the setup won't 47 | create any resources on the service account's project): 48 | - Cloud Resource Manager 49 | - Cloud Billing 50 | - Service Usage 51 | - Identity and Access Management (IAM) 52 | 53 | Export the Service Account credentials to your environment like so: 54 | 55 | ``` 56 | export SERVICE_ACCOUNT_JSON=$(< credentials.json) 57 | ``` 58 | 59 | You will also need to set a few environment variables: 60 | ``` 61 | export TF_VAR_org_id="your_org_id" 62 | export TF_VAR_folder_id="your_folder_id" 63 | export TF_VAR_billing_account="your_billing_account_id" 64 | ``` 65 | 66 | With these settings in place, you can prepare a test project using Docker: 67 | ``` 68 | make docker_test_prepare 69 | ``` 70 | 71 | ### Noninteractive Execution 72 | 73 | Run `make docker_test_integration` to test all of the example modules 74 | noninteractively, using the prepared test project. 75 | 76 | ### Interactive Execution 77 | 78 | 1. Run `make docker_run` to start the testing Docker container in 79 | interactive mode. 80 | 81 | 1. Run `kitchen_do create ` to initialize the working 82 | directory for an example module. 83 | 84 | 1. Run `kitchen_do converge ` to apply the example module. 85 | 86 | 1. Run `kitchen_do verify ` to test the example module. 87 | 88 | 1. Run `kitchen_do destroy ` to destroy the example module 89 | state. 90 | 91 | ## Linting and Formatting 92 | 93 | Many of the files in the repository can be linted or formatted to 94 | maintain a standard of quality. 95 | 96 | ### Execution 97 | 98 | Run `make docker_test_lint`. 99 | 100 | [docker-engine]: https://www.docker.com/products/docker-engine 101 | [flake8]: http://flake8.pycqa.org/en/latest/ 102 | [gofmt]: https://golang.org/cmd/gofmt/ 103 | [google-cloud-sdk]: https://cloud.google.com/sdk/install 104 | [hadolint]: https://github.com/hadolint/hadolint 105 | [inspec]: https://inspec.io/ 106 | [kitchen-terraform]: https://github.com/newcontext-oss/kitchen-terraform 107 | [kitchen]: https://kitchen.ci/ 108 | [make]: https://en.wikipedia.org/wiki/Make_(software) 109 | [shellcheck]: https://www.shellcheck.net/ 110 | [terraform-docs]: https://github.com/segmentio/terraform-docs 111 | [terraform]: https://terraform.io/ 112 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Please note that this file was generated from [terraform-google-module-template](https://github.com/terraform-google-modules/terraform-google-module-template). 16 | # Please make sure to contribute relevant changes upstream! 17 | 18 | # Make will use bash instead of sh 19 | SHELL := /usr/bin/env bash 20 | 21 | DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 1.23 22 | DOCKER_IMAGE_DEVELOPER_TOOLS := cft/developer-tools 23 | REGISTRY_URL := gcr.io/cloud-foundation-cicd 24 | 25 | # Enter docker container for local development 26 | .PHONY: docker_run 27 | docker_run: 28 | docker run --rm -it \ 29 | -e SERVICE_ACCOUNT_JSON \ 30 | -v "$(CURDIR)":/workspace \ 31 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 32 | /bin/bash 33 | 34 | # Execute prepare tests within the docker container 35 | .PHONY: docker_test_prepare 36 | docker_test_prepare: 37 | docker run --rm -it \ 38 | -e SERVICE_ACCOUNT_JSON \ 39 | -e TF_VAR_org_id \ 40 | -e TF_VAR_folder_id \ 41 | -e TF_VAR_billing_account \ 42 | -v "$(CURDIR)":/workspace \ 43 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 44 | /usr/local/bin/execute_with_credentials.sh prepare_environment 45 | 46 | # Clean up test environment within the docker container 47 | .PHONY: docker_test_cleanup 48 | docker_test_cleanup: 49 | docker run --rm -it \ 50 | -e SERVICE_ACCOUNT_JSON \ 51 | -e TF_VAR_org_id \ 52 | -e TF_VAR_folder_id \ 53 | -e TF_VAR_billing_account \ 54 | -v "$(CURDIR)":/workspace \ 55 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 56 | /usr/local/bin/execute_with_credentials.sh cleanup_environment 57 | 58 | # Execute integration tests within the docker container 59 | .PHONY: docker_test_integration 60 | docker_test_integration: 61 | docker run --rm -it \ 62 | -e SERVICE_ACCOUNT_JSON \ 63 | -v "$(CURDIR)":/workspace \ 64 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 65 | /usr/local/bin/test_integration.sh 66 | 67 | # Execute lint tests within the docker container 68 | .PHONY: docker_test_lint 69 | docker_test_lint: 70 | docker run --rm -it \ 71 | -v "$(CURDIR)":/workspace \ 72 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 73 | /usr/local/bin/test_lint.sh 74 | 75 | # Generate documentation 76 | .PHONY: docker_generate_docs 77 | docker_generate_docs: 78 | docker run --rm -it \ 79 | -v "$(CURDIR)":/workspace \ 80 | $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ 81 | /bin/bash -c 'source /usr/local/bin/task_helper_functions.sh && generate_docs' 82 | 83 | # Alias for backwards compatibility 84 | .PHONY: generate_docs 85 | generate_docs: docker_generate_docs 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Organization Policy Terraform Module 2 | 3 | This Terraform module makes it easier to manage [organization policies](https://cloud.google.com/resource-manager/docs/organization-policy/overview) for your Google Cloud environment, particularly when you want to have exclusion rules. This module will allow you to set a top-level org policy and then disable it on individual projects or folders easily. 4 | 5 | ## Compatibility 6 | This module is meant for use with Terraform 1.3+ and tested using Terraform 1.10+. If you find incompatibilities using Terraform >=1.3, please open an issue. 7 | If you haven't 8 | [upgraded](https://www.terraform.io/upgrade-guides/0-13.html) and need a Terraform 9 | 0.12.x-compatible version of this module, the last released version 10 | intended for Terraform 0.12.x is [v4.0.0](https://registry.terraform.io/modules/terraform-google-modules/-org-policy/google/v4.0.0). 11 | 12 | ## Usage 13 | Many examples are included in the [examples](./examples/) folder, but simple usage is as follows: 14 | 15 | ```hcl 16 | module "org-policy" { 17 | source = "terraform-google-modules/org-policy/google" 18 | version = "~> 3.0.2" 19 | 20 | policy_for = "organization" 21 | constraint = "constraints/serviceuser.services" 22 | policy_type = "list" 23 | organization_id = "123456789" 24 | enforce = true 25 | exclude_folders = ["folders/folder-1-id", "folders/folder-2-id"] 26 | exclude_projects = ["project3", "project4"] 27 | } 28 | ``` 29 | 30 | ### Variables 31 | To control module's behavior, change variables' values regarding the following: 32 | 33 | - `constraint`: set this variable with the [constraint value](https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints#available_constraints) in the form `constraints/{constraint identifier}`. For example, `constraints/serviceuser.services` 34 | - `policy_type`: Specify either `boolean` for boolean policies or `list` for list policies. (default `list`) 35 | - Policy Root: set one of the following values to determine where the policy is applied: 36 | - `organization_id` 37 | - `project_id` 38 | - `folder_id` 39 | - `policy_for`: Specify the hierarchy level where the policy is applied. Can be **one of** the following values. 40 | - `organization` 41 | - `folder` 42 | - `project` 43 | - `exclude_folders`: a list of folder IDs to be excluded from this policy. These folders must be lower in the hierarchy than the policy root. 44 | - `exclude_projects`: a list of project IDs to be excluded from this policy. They must be lower in the hierarchy than the policy root. 45 | - Boolean policies (with `policy_type: "boolean"`) can set the following variables: 46 | - `enforce`: if `true` or `null` then the policy is enforced at the root; if `false` then policy is not enforced at the root. (default `null`) 47 | - List policies (with `policy_type: "list"`) can set **one of** the following variables. Only one may be set. 48 | - `enforce`: if `true` or `null` then policy will deny all; if `false` then policy will allow all (default `null`) 49 | - `allow`: list of values to include in the policy with ALLOW behavior. Set `enforce` to `null` to use it. 50 | - `deny`: list of values to include in the policy with DENY behavior. Set `enforce` to `null` to use it. 51 | - List policies with allow or deny values require the length to be set (a workaround for [this terraform issue](https://github.com/hashicorp/terraform/issues/10857)) 52 | - `allow_list_length` 53 | - `deny_list_length` 54 | 55 | 56 | ## Inputs 57 | 58 | | Name | Description | Type | Default | Required | 59 | |------|-------------|------|---------|:--------:| 60 | | allow | (Only for list constraints) List of values which should be allowed | `list(string)` |
[
""
]
| no | 61 | | allow\_list\_length | The number of elements in the allow list | `number` | `0` | no | 62 | | constraint | The constraint to be applied | `string` | n/a | yes | 63 | | deny | (Only for list constraints) List of values which should be denied | `list(string)` |
[
""
]
| no | 64 | | deny\_list\_length | The number of elements in the deny list | `number` | `0` | no | 65 | | enforce | If boolean constraint, whether the policy is enforced at the root; if list constraint, whether to deny all (true) or allow all | `bool` | `null` | no | 66 | | exclude\_folders | Set of folders to exclude from the policy | `set(string)` | `[]` | no | 67 | | exclude\_projects | Set of projects to exclude from the policy | `set(string)` | `[]` | no | 68 | | folder\_id | The folder id for putting the policy | `string` | `null` | no | 69 | | organization\_id | The organization id for putting the policy | `string` | `null` | no | 70 | | policy\_for | Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`. | `string` | n/a | yes | 71 | | policy\_type | The constraint type to work with (either 'boolean' or 'list') | `string` | `"list"` | no | 72 | | project\_id | The project id for putting the policy | `string` | `null` | no | 73 | 74 | ## Outputs 75 | 76 | No outputs. 77 | 78 | 79 | 80 | ## Requirements 81 | ### Terraform plugins 82 | - [Terraform](https://www.terraform.io/downloads.html) >= 1.3 83 | - [terraform-provider-google](https://github.com/terraform-providers/terraform-provider-google) >= v3.53 84 | 85 | ### Permissions 86 | In order to execute this module, the Service Account you run as must have the **Organization Policy Administrator** (`roles/orgpolicy.PolicyAdmin`) role. 87 | 88 | ## Install 89 | ### Terraform 90 | Be sure you have the correct Terraform version (>= 1.3.x), you can choose the binary here: 91 | - https://releases.hashicorp.com/terraform/ 92 | 93 | ### Terraform plugins 94 | 95 | - [terraform-provider-google](https://github.com/terraform-providers/terraform-provider-google) >= v3.53 96 | 97 | 98 | ### Fast install (optional) 99 | For a fast install, please configure the variables on init_centos.sh or init_debian.sh script and then launch it. 100 | 101 | The script will do: 102 | - Environment variables setting 103 | - Installation of base packages like wget, curl, unzip, gcloud, etc. 104 | -------------------------------------------------------------------------------- /boolean_constraints.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Organization policy (boolean constraint) 19 | *****************************************/ 20 | resource "google_organization_policy" "org_policy_boolean" { 21 | count = local.organization && local.boolean_policy ? 1 : 0 22 | 23 | org_id = var.organization_id 24 | constraint = var.constraint 25 | 26 | boolean_policy { 27 | enforced = var.enforce != false 28 | } 29 | } 30 | 31 | /****************************************** 32 | Folder policy (boolean constraint) 33 | *****************************************/ 34 | resource "google_folder_organization_policy" "folder_policy_boolean" { 35 | count = local.folder && local.boolean_policy ? 1 : 0 36 | 37 | folder = var.folder_id 38 | constraint = var.constraint 39 | 40 | boolean_policy { 41 | enforced = var.enforce != false 42 | } 43 | } 44 | 45 | /****************************************** 46 | Project policy (boolean constraint) 47 | *****************************************/ 48 | resource "google_project_organization_policy" "project_policy_boolean" { 49 | count = local.project && local.boolean_policy ? 1 : 0 50 | 51 | project = var.project_id 52 | constraint = var.constraint 53 | 54 | boolean_policy { 55 | enforced = var.enforce != false 56 | } 57 | } 58 | 59 | /****************************************** 60 | Exclude folders from policy (boolean constraint) 61 | *****************************************/ 62 | resource "google_folder_organization_policy" "policy_boolean_exclude_folders" { 63 | for_each = (local.boolean_policy && !local.project) ? var.exclude_folders : [] 64 | 65 | folder = each.value 66 | constraint = var.constraint 67 | 68 | boolean_policy { 69 | enforced = var.enforce == false 70 | } 71 | } 72 | 73 | /****************************************** 74 | Exclude projects from policy (boolean constraint) 75 | *****************************************/ 76 | resource "google_project_organization_policy" "policy_boolean_exclude_projects" { 77 | for_each = (local.boolean_policy && !local.project) ? var.exclude_projects : [] 78 | 79 | project = each.value 80 | constraint = var.constraint 81 | 82 | boolean_policy { 83 | enforced = var.enforce == false 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /build/int.cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | timeout: 3600s 16 | steps: 17 | - id: swap-module-refs 18 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 19 | args: ['module-swapper'] 20 | - id: prepare 21 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 22 | args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && prepare_environment'] 23 | env: 24 | - 'TF_VAR_org_id=$_ORG_ID' 25 | - 'TF_VAR_folder_id=$_FOLDER_ID' 26 | - 'TF_VAR_billing_account=$_BILLING_ACCOUNT' 27 | - id: sleep 28 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 29 | args: ['/bin/bash', '-c', 'sleep 30'] 30 | waitFor: 31 | - prepare 32 | # Ruby Test Framework - org policy v1 APIs 33 | - id: create 34 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 35 | args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do create'] 36 | waitFor: 37 | - sleep 38 | - id: converge 39 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 40 | args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do converge'] 41 | waitFor: 42 | - create 43 | - id: verify 44 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 45 | args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do verify'] 46 | waitFor: 47 | - converge 48 | - id: destroy 49 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 50 | args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do destroy'] 51 | waitFor: 52 | - verify 53 | # Boolean Org Enforce Example Test 54 | - id: create all 55 | waitFor: 56 | - create 57 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 58 | args: ['/bin/bash', '-c', 'cft test run TestVersion2BooleanOrgEnforce --test-dir test/integration --stage init --verbose'] 59 | - id: converge org-policy-v2 60 | waitFor: 61 | - create all 62 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 63 | args: ['/bin/bash', '-c', 'cft test run TestVersion2BooleanOrgEnforce --test-dir test/integration --stage apply --verbose'] 64 | - id: verify org-policy-v2 65 | waitFor: 66 | - converge org-policy-v2 67 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 68 | args: ['/bin/bash', '-c', 'cft test run TestVersion2BooleanOrgEnforce --test-dir test/integration --stage verify --verbose'] 69 | - id: destroy org-policy-v2 70 | waitFor: 71 | - verify org-policy-v2 72 | name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 73 | args: ['/bin/bash', '-c', 'cft test run TestVersion2BooleanOrgEnforce --test-dir test/integration --stage destroy --verbose'] 74 | tags: 75 | - 'ci' 76 | - 'integration' 77 | substitutions: 78 | _DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools' 79 | _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '1.23' 80 | -------------------------------------------------------------------------------- /build/lint.cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | steps: 16 | - name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' 17 | id: 'lint' 18 | args: ['/usr/local/bin/test_lint.sh'] 19 | tags: 20 | - 'ci' 21 | - 'lint' 22 | substitutions: 23 | _DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools' 24 | _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '1.23' 25 | -------------------------------------------------------------------------------- /docs/upgrading_to_v3.0.md: -------------------------------------------------------------------------------- 1 | # Upgrading to v3.0 2 | 3 | The v3.0 release of *org-policy* is a backwards incompatible 4 | release. 5 | 6 | ## Migration Instructions 7 | 8 | In previous versions of this module the resource hirerarchy node was not defined explicitly which caused problems when the module is combined with project/folder creation. The `policy_for` variable was introduced to address that issue. 9 | 10 | ### Update for project policies 11 | ```diff 12 | module "project_policy" { 13 | source = "terraform-google-modules/org-policy/google" 14 | - version = "~> 2.0" 15 | + version = "~> 3.0" 16 | 17 | + policy_for = "project" 18 | # ... 19 | } 20 | ``` 21 | 22 | ### Update for folder policies 23 | ```diff 24 | module "folder_policy" { 25 | source = "terraform-google-modules/org-policy/google" 26 | - version = "~> 2.0" 27 | + version = "~> 3.0" 28 | 29 | + policy_for = "folder" 30 | # ... 31 | } 32 | ``` 33 | 34 | ### Update for organization policies 35 | ```diff 36 | module "org_policy" { 37 | source = "terraform-google-modules/org-policy/google" 38 | - version = "~> 2.0" 39 | + version = "~> 3.0" 40 | 41 | + policy_for = "organization" 42 | # ... 43 | } 44 | ``` 45 | -------------------------------------------------------------------------------- /examples/basic_org_policies/README.md: -------------------------------------------------------------------------------- 1 | # Recommended Starting Constraints 2 | 3 | This example shows how to set a basic list of [organization policies](https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints) including: 4 | - Bucket Policy Only (uniform bucket-level access) 5 | - Domain Restricted Sharing 6 | - Allowed External IPs for VM instances 7 | - Skip Default Network Creation 8 | 9 | 10 | ## Inputs 11 | 12 | | Name | Description | Type | Default | Required | 13 | |------|-------------|------|---------|:--------:| 14 | | domains\_to\_allow | The list of domains to allow users from | `list(string)` | n/a | yes | 15 | | organization\_id | The organization id for putting the policy | `string` | n/a | yes | 16 | | vms\_to\_allow | The list of VMs are allowed to use external IP, every element of the list must be identified by the VM instance name, in the form: projects/PROJECT\_ID/zones/ZONE/instances/INSTANCE | `list(string)` | `[]` | no | 17 | 18 | ## Outputs 19 | 20 | No outputs. 21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/basic_org_policies/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "domain-restricted-sharing" { 18 | source = "terraform-google-modules/org-policy/google//modules/domain_restricted_sharing" 19 | version = "~> 6.0" 20 | 21 | policy_for = "organization" 22 | organization_id = var.organization_id 23 | domains_to_allow = var.domains_to_allow 24 | } 25 | 26 | module "skip-default-network" { 27 | source = "terraform-google-modules/org-policy/google//modules/skip_default_network" 28 | version = "~> 6.0" 29 | 30 | policy_for = "organization" 31 | organization_id = var.organization_id 32 | } 33 | 34 | module "bucket-policy-only" { 35 | source = "terraform-google-modules/org-policy/google//modules/bucket_policy_only" 36 | version = "~> 6.0" 37 | 38 | policy_for = "organization" 39 | organization_id = var.organization_id 40 | } 41 | 42 | module "restrict-vm-external-ips" { 43 | source = "terraform-google-modules/org-policy/google//modules/restrict_vm_external_ips" 44 | version = "~> 6.0" 45 | 46 | policy_for = "organization" 47 | organization_id = var.organization_id 48 | vms_to_allow = var.vms_to_allow 49 | } 50 | -------------------------------------------------------------------------------- /examples/basic_org_policies/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "organization_id" { 18 | description = "The organization id for putting the policy" 19 | type = string 20 | } 21 | 22 | variable "domains_to_allow" { 23 | description = "The list of domains to allow users from" 24 | type = list(string) 25 | } 26 | 27 | variable "vms_to_allow" { 28 | description = "The list of VMs are allowed to use external IP, every element of the list must be identified by the VM instance name, in the form: projects/PROJECT_ID/zones/ZONE/instances/INSTANCE" 29 | type = list(string) 30 | default = [] 31 | } 32 | -------------------------------------------------------------------------------- /examples/boolean_org_exclude/README.md: -------------------------------------------------------------------------------- 1 | # Boolean Constraint with Exclusion 2 | This example shows how a boolean constraint (compute.disableSerialPortAccess) can be applied at an org level and selectively disabled on certain folders. 3 | 4 | ## Folder-level 5 | If you wanted to set the policy on a folder level and selectively disable it on certain projects in that folder, you could use a config like this: 6 | 7 | ```hcl 8 | module "folder-disable-serial-port-access-enforce-with-excludes" { 9 | source = "github.com/terraform-google-modules/terraform-google-org-policy" 10 | folder_id = "folders/my-folder-id" 11 | constraint = "compute.disableSerialPortAccess" 12 | enforce = true 13 | policy_type = "boolean" 14 | exclude_projects = ["my-project"] 15 | } 16 | ``` 17 | 18 | 19 | ## Inputs 20 | 21 | | Name | Description | Type | Default | Required | 22 | |------|-------------|------|---------|:--------:| 23 | | excluded\_folder\_id | ID of a folder to exclude from the policy | `string` | n/a | yes | 24 | | organization\_id | The organization id for putting the policy | `string` | n/a | yes | 25 | 26 | ## Outputs 27 | 28 | No outputs. 29 | 30 | 31 | -------------------------------------------------------------------------------- /examples/boolean_org_exclude/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Apply the constraint using the module 19 | *****************************************/ 20 | module "org-disable-serial-port-access-deny-all-with-excludes" { 21 | source = "terraform-google-modules/org-policy/google" 22 | version = "~> 6.0" 23 | 24 | policy_for = "organization" 25 | organization_id = var.organization_id 26 | constraint = "compute.disableSerialPortAccess" 27 | enforce = true 28 | policy_type = "boolean" 29 | exclude_folders = ["folders/${var.excluded_folder_id}"] 30 | } 31 | 32 | -------------------------------------------------------------------------------- /examples/boolean_org_exclude/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "organization_id" { 18 | description = "The organization id for putting the policy" 19 | type = string 20 | } 21 | 22 | variable "excluded_folder_id" { 23 | description = "ID of a folder to exclude from the policy" 24 | type = string 25 | } 26 | -------------------------------------------------------------------------------- /examples/boolean_project_allow/README.md: -------------------------------------------------------------------------------- 1 | # Enabling Boolean Constraint 2 | This example shows how the boolean constraint policy can be used to explicitly **allow** a particular constraint on an individual project, regardless of higher level policies. 3 | 4 | It disables enforcement of the `compute.disableSerialPortAccess` constraint on the given project, ensuring that serial port access can be used in the project. 5 | 6 | 7 | ## Inputs 8 | 9 | | Name | Description | Type | Default | Required | 10 | |------|-------------|------|---------|:--------:| 11 | | project\_id | The project ID to apply the policy to | `string` | n/a | yes | 12 | 13 | ## Outputs 14 | 15 | No outputs. 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/boolean_project_allow/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Apply the constraint using the module 19 | *****************************************/ 20 | module "org-policy" { 21 | source = "terraform-google-modules/org-policy/google" 22 | version = "~> 6.0" 23 | 24 | policy_for = "project" 25 | project_id = var.project_id 26 | constraint = "compute.disableSerialPortAccess" 27 | policy_type = "boolean" 28 | enforce = false 29 | } 30 | -------------------------------------------------------------------------------- /examples/boolean_project_allow/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | description = "The project ID to apply the policy to" 19 | type = string 20 | } 21 | -------------------------------------------------------------------------------- /examples/list_folder_deny/README.md: -------------------------------------------------------------------------------- 1 | # List Deny Constraint 2 | This example shows how a list constraint can be applied to disallow certain services on a folder. In particular, it disallows usage of the Deployment Manager service on a given folder. 3 | 4 | 5 | ## Inputs 6 | 7 | | Name | Description | Type | Default | Required | 8 | |------|-------------|------|---------|:--------:| 9 | | folder\_id | The folder id for putting the policy | `string` | n/a | yes | 10 | 11 | ## Outputs 12 | 13 | No outputs. 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/list_folder_deny/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Apply the constraint using the module 19 | *****************************************/ 20 | module "org-policy" { 21 | source = "terraform-google-modules/org-policy/google" 22 | version = "~> 6.0" 23 | 24 | policy_for = "folder" 25 | folder_id = var.folder_id 26 | constraint = "serviceuser.services" 27 | policy_type = "list" 28 | deny = ["deploymentmanager.googleapis.com"] 29 | deny_list_length = 1 30 | } 31 | -------------------------------------------------------------------------------- /examples/list_folder_deny/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "folder_id" { 18 | description = "The folder id for putting the policy" 19 | type = string 20 | } 21 | -------------------------------------------------------------------------------- /examples/list_org_exclude/README.md: -------------------------------------------------------------------------------- 1 | # List Constraint with Exclusion 2 | 3 | This example shows how to set a list constraint on an org level and selectively disable it. 4 | 5 | Specifically, it sets a trusted image policy so only images from a trusted image project can be used. Then it excludes that project from the policy so alternative images can be tested in that project. 6 | 7 | 8 | ## Inputs 9 | 10 | | Name | Description | Type | Default | Required | 11 | |------|-------------|------|---------|:--------:| 12 | | organization\_id | The organization id for putting the policy | `string` | n/a | yes | 13 | | shared\_reservation\_project\_id | The ID of a project that are allowed to create and own shared reservations in the org | `string` | n/a | yes | 14 | 15 | ## Outputs 16 | 17 | No outputs. 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/list_org_exclude/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Apply the constraint using the module 19 | *****************************************/ 20 | module "org-policy" { 21 | source = "terraform-google-modules/org-policy/google" 22 | version = "~> 6.0" 23 | 24 | policy_for = "organization" 25 | organization_id = var.organization_id 26 | constraint = "compute.sharedReservationsOwnerProjects" 27 | policy_type = "list" 28 | allow = ["projects/${var.shared_reservation_project_id}"] 29 | allow_list_length = "1" 30 | exclude_projects = [var.shared_reservation_project_id] 31 | } 32 | -------------------------------------------------------------------------------- /examples/list_org_exclude/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "organization_id" { 18 | description = "The organization id for putting the policy" 19 | type = string 20 | } 21 | 22 | variable "shared_reservation_project_id" { 23 | description = "The ID of a project that are allowed to create and own shared reservations in the org" 24 | type = string 25 | } 26 | -------------------------------------------------------------------------------- /examples/v2_boolean_org_enforce/README.md: -------------------------------------------------------------------------------- 1 | # Boolean Constraint with option to add multiple rules and conditions 2 | 3 | This example shows how to set a boolean constraint on an org level, with option to add multiple rules and conditions supported by latest Organization Policy APIs. 4 | 5 | This boolean constraint, when set to true, enables OS Login on all newly created Projects. All VM instances created in new projects will have OS Login enabled. On new and existing projects, this constraint prevents metadata updates that disable OS Login at the project or instance level. By default, the OS Login feature is disabled on Compute Engine projects. GKE instances in private clusters running node pool versions 1.20.5-gke.2000 and later support OS Login. GKE instances in public clusters do not currently support OS Login. If this constraint is applied to a Project running public clusters, GKE instances running in that Project may not function properly. 6 | 7 | 8 | ## Inputs 9 | 10 | | Name | Description | Type | Default | Required | 11 | |------|-------------|------|---------|:--------:| 12 | | org\_id | The organization id for applying the policy | `string` | `null` | no | 13 | 14 | ## Outputs 15 | 16 | | Name | Description | 17 | |------|-------------| 18 | | constraint | Policy Constraint Identifier | 19 | | parameterized\_constraint | Policy with parameters for Managed Constraint Identifier | 20 | | policy\_root | Policy Root in the hierarchy for the given policy | 21 | | policy\_root\_id | Project Root ID at which the policy is applied | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/v2_boolean_org_enforce/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /******************************************************** 18 | Apply the sample constraint using the org_policy_v2 module 19 | *******************************************************/ 20 | module "gcp_org_policy_v2" { 21 | source = "terraform-google-modules/org-policy/google//modules/org_policy_v2" 22 | version = "~> 6.0" 23 | 24 | policy_root = "organization" 25 | policy_root_id = var.org_id 26 | rules = [{ 27 | enforcement = true 28 | }] 29 | constraint = "compute.requireOsLogin" 30 | policy_type = "boolean" 31 | } 32 | 33 | module "parameterized_org_policy_v2" { 34 | source = "terraform-google-modules/org-policy/google//modules/org_policy_v2" 35 | version = "~> 7.0" 36 | 37 | policy_root = "organization" 38 | policy_root_id = var.org_id 39 | rules = [{ 40 | enforcement = true 41 | parameters = jsonencode({"allowedDomains" : ["@abc.com"]}) 42 | }] 43 | constraint = "essentialcontacts.managed.allowedContactDomains" 44 | policy_type = "boolean" 45 | } 46 | -------------------------------------------------------------------------------- /examples/v2_boolean_org_enforce/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "policy_root" { 18 | description = "Policy Root in the hierarchy for the given policy" 19 | value = module.gcp_org_policy_v2.policy_root 20 | } 21 | 22 | output "policy_root_id" { 23 | description = "Project Root ID at which the policy is applied" 24 | value = module.gcp_org_policy_v2.policy_root_id 25 | } 26 | 27 | output "constraint" { 28 | description = "Policy Constraint Identifier" 29 | value = module.gcp_org_policy_v2.constraint 30 | } 31 | 32 | output "parameterized_constraint" { 33 | description = "Policy with parameters for Managed Constraint Identifier" 34 | value = module.parameterized_org_policy_v2.constraint 35 | } 36 | -------------------------------------------------------------------------------- /examples/v2_boolean_org_enforce/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | # Organization ID for this example 18 | # It could be Folder or Project ID 19 | variable "org_id" { 20 | description = "The organization id for applying the policy" 21 | type = string 22 | default = null 23 | } 24 | -------------------------------------------------------------------------------- /list_constraints.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Organization policy, allow all (list constraint) 19 | *****************************************/ 20 | resource "google_organization_policy" "org_policy_list_allow_all" { 21 | count = local.organization && local.list_policy && local.enforce == false ? 1 : 0 22 | 23 | org_id = var.organization_id 24 | constraint = var.constraint 25 | 26 | list_policy { 27 | allow { 28 | all = true 29 | } 30 | } 31 | } 32 | 33 | /****************************************** 34 | Folder policy, allow all (list constraint) 35 | *****************************************/ 36 | resource "google_folder_organization_policy" "folder_policy_list_allow_all" { 37 | count = local.folder && local.list_policy && local.enforce == false ? 1 : 0 38 | 39 | folder = var.folder_id 40 | constraint = var.constraint 41 | 42 | list_policy { 43 | allow { 44 | all = true 45 | } 46 | } 47 | } 48 | 49 | /****************************************** 50 | Project policy, allow all (list constraint) 51 | *****************************************/ 52 | resource "google_project_organization_policy" "project_policy_list_allow_all" { 53 | count = local.project && local.list_policy && local.enforce == false ? 1 : 0 54 | 55 | project = var.project_id 56 | constraint = var.constraint 57 | 58 | list_policy { 59 | allow { 60 | all = true 61 | } 62 | } 63 | } 64 | 65 | /****************************************** 66 | Organization policy, deny all (list constraint) 67 | *****************************************/ 68 | resource "google_organization_policy" "org_policy_list_deny_all" { 69 | count = local.organization && local.list_policy && local.enforce == true ? 1 : 0 70 | 71 | org_id = var.organization_id 72 | constraint = var.constraint 73 | 74 | list_policy { 75 | deny { 76 | all = true 77 | } 78 | } 79 | } 80 | 81 | /****************************************** 82 | Folder policy, deny all (list constraint) 83 | *****************************************/ 84 | resource "google_folder_organization_policy" "folder_policy_list_deny_all" { 85 | count = local.folder && local.list_policy && local.enforce == true ? 1 : 0 86 | 87 | folder = var.folder_id 88 | constraint = var.constraint 89 | 90 | list_policy { 91 | deny { 92 | all = true 93 | } 94 | } 95 | } 96 | 97 | /****************************************** 98 | Project policy, deny all (list constraint) 99 | *****************************************/ 100 | resource "google_project_organization_policy" "project_policy_list_deny_all" { 101 | count = local.project && local.list_policy && local.enforce == true ? 1 : 0 102 | 103 | project = var.project_id 104 | constraint = var.constraint 105 | 106 | list_policy { 107 | deny { 108 | all = true 109 | } 110 | } 111 | } 112 | 113 | /****************************************** 114 | Organization policy, deny values (list constraint) 115 | *****************************************/ 116 | resource "google_organization_policy" "org_policy_list_deny_values" { 117 | count = local.organization && local.list_policy && var.deny_list_length > 0 ? 1 : 0 118 | 119 | org_id = var.organization_id 120 | constraint = var.constraint 121 | 122 | list_policy { 123 | deny { 124 | values = var.deny 125 | } 126 | } 127 | } 128 | 129 | /****************************************** 130 | Folder policy, deny values (list constraint) 131 | *****************************************/ 132 | resource "google_folder_organization_policy" "folder_policy_list_deny_values" { 133 | count = local.folder && local.list_policy && var.deny_list_length > 0 ? 1 : 0 134 | 135 | folder = var.folder_id 136 | constraint = var.constraint 137 | 138 | list_policy { 139 | deny { 140 | values = var.deny 141 | } 142 | } 143 | } 144 | 145 | /****************************************** 146 | Project policy, deny values (list constraint) 147 | *****************************************/ 148 | resource "google_project_organization_policy" "project_policy_list_deny_values" { 149 | count = local.project && local.list_policy && var.deny_list_length > 0 ? 1 : 0 150 | 151 | project = var.project_id 152 | constraint = var.constraint 153 | 154 | list_policy { 155 | deny { 156 | values = var.deny 157 | } 158 | } 159 | } 160 | 161 | /****************************************** 162 | Organization policy, allow values (list constraint) 163 | *****************************************/ 164 | resource "google_organization_policy" "org_policy_list_allow_values" { 165 | count = local.organization && local.list_policy && var.allow_list_length > 0 ? 1 : 0 166 | 167 | org_id = var.organization_id 168 | constraint = var.constraint 169 | 170 | list_policy { 171 | allow { 172 | values = var.allow 173 | } 174 | } 175 | } 176 | 177 | /****************************************** 178 | Folder policy, allow values (list constraint) 179 | *****************************************/ 180 | resource "google_folder_organization_policy" "folder_policy_list_allow_values" { 181 | count = local.folder && local.list_policy && var.allow_list_length > 0 ? 1 : 0 182 | 183 | folder = var.folder_id 184 | constraint = var.constraint 185 | 186 | list_policy { 187 | allow { 188 | values = var.allow 189 | } 190 | } 191 | } 192 | 193 | /****************************************** 194 | Project policy, allow values (list constraint) 195 | *****************************************/ 196 | resource "google_project_organization_policy" "project_policy_list_allow_values" { 197 | count = local.project && local.list_policy && var.allow_list_length > 0 ? 1 : 0 198 | 199 | project = var.project_id 200 | constraint = var.constraint 201 | 202 | list_policy { 203 | allow { 204 | values = var.allow 205 | } 206 | } 207 | } 208 | 209 | /****************************************** 210 | Exclude folders from policy (list constraint) 211 | *****************************************/ 212 | resource "google_folder_organization_policy" "folder_policy_list_exclude_folders" { 213 | for_each = (local.list_policy && !local.project) ? var.exclude_folders : [] 214 | 215 | folder = each.value 216 | constraint = var.constraint 217 | 218 | restore_policy { 219 | default = true 220 | } 221 | } 222 | 223 | /****************************************** 224 | Exclude projects from policy (list constraint) 225 | *****************************************/ 226 | resource "google_project_organization_policy" "project_policy_list_exclude_projects" { 227 | for_each = (local.list_policy && !local.project) ? var.exclude_projects : [] 228 | 229 | project = each.value 230 | constraint = var.constraint 231 | 232 | restore_policy { 233 | default = true 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Locals configuration for module logic 19 | *****************************************/ 20 | locals { 21 | organization = var.policy_for == "organization" 22 | folder = var.policy_for == "folder" 23 | project = var.policy_for == "project" 24 | boolean_policy = var.policy_type == "boolean" 25 | list_policy = var.policy_type == "list" && !local.invalid_config 26 | 27 | // If allow/deny list empty and enforce is not set, enforce is set to true 28 | enforce = var.allow_list_length > 0 || var.deny_list_length > 0 ? null : var.enforce != false 29 | invalid_config_case_1 = var.deny_list_length > 0 && var.allow_list_length > 0 30 | 31 | // We use var.enforce here because allow/deny lists can not be used together with enforce flag 32 | invalid_config_case_2 = var.allow_list_length + var.deny_list_length > 0 && var.enforce != null 33 | invalid_config = var.policy_type == "list" && local.invalid_config_case_1 || local.invalid_config_case_2 34 | } 35 | 36 | /****************************************** 37 | Checks a valid configuration for list constraint 38 | *****************************************/ 39 | resource "null_resource" "config_check" { 40 | /* 41 | This resource shows the user a message intentionally 42 | If user sets two (or more) of following variables when policy type is "list": 43 | - allow 44 | - deny 45 | - enforce ("true" or "false") 46 | the configuration is invalid and the message below is shown 47 | */ 48 | count = local.invalid_config ? 1 : 0 49 | 50 | provisioner "local-exec" { 51 | command = "echo 'For list constraints only one of enforce, allow, and deny may be included.'; false" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /metadata.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: blueprints.cloud.google.com/v1alpha1 16 | kind: BlueprintMetadata 17 | metadata: 18 | name: terraform-google-org-policy 19 | annotations: 20 | config.kubernetes.io/local-config: "true" 21 | spec: 22 | info: 23 | title: Google Cloud Organization Policy Terraform Module 24 | source: 25 | repo: https://github.com/terraform-google-modules/terraform-google-org-policy.git 26 | sourceType: git 27 | version: 7.0.0 28 | actuationTool: 29 | flavor: Terraform 30 | version: ">= 1.3" 31 | description: {} 32 | content: 33 | subBlueprints: 34 | - name: bucket_policy_only 35 | location: modules/bucket_policy_only 36 | - name: domain_restricted_sharing 37 | location: modules/domain_restricted_sharing 38 | - name: org_policy_v2 39 | location: modules/org_policy_v2 40 | - name: restrict_vm_external_ips 41 | location: modules/restrict_vm_external_ips 42 | - name: skip_default_network 43 | location: modules/skip_default_network 44 | examples: 45 | - name: basic_org_policies 46 | location: examples/basic_org_policies 47 | - name: boolean_org_exclude 48 | location: examples/boolean_org_exclude 49 | - name: boolean_project_allow 50 | location: examples/boolean_project_allow 51 | - name: list_folder_deny 52 | location: examples/list_folder_deny 53 | - name: list_org_exclude 54 | location: examples/list_org_exclude 55 | - name: v2_boolean_org_enforce 56 | location: examples/v2_boolean_org_enforce 57 | interfaces: 58 | variables: 59 | - name: policy_for 60 | description: "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 61 | varType: string 62 | required: true 63 | - name: organization_id 64 | description: The organization id for putting the policy 65 | varType: string 66 | - name: folder_id 67 | description: The folder id for putting the policy 68 | varType: string 69 | - name: project_id 70 | description: The project id for putting the policy 71 | varType: string 72 | - name: enforce 73 | description: If boolean constraint, whether the policy is enforced at the root; if list constraint, whether to deny all (true) or allow all 74 | varType: bool 75 | - name: allow 76 | description: (Only for list constraints) List of values which should be allowed 77 | varType: list(string) 78 | defaultValue: 79 | - "" 80 | - name: deny 81 | description: (Only for list constraints) List of values which should be denied 82 | varType: list(string) 83 | defaultValue: 84 | - "" 85 | - name: exclude_folders 86 | description: Set of folders to exclude from the policy 87 | varType: set(string) 88 | defaultValue: [] 89 | - name: exclude_projects 90 | description: Set of projects to exclude from the policy 91 | varType: set(string) 92 | defaultValue: [] 93 | - name: constraint 94 | description: The constraint to be applied 95 | varType: string 96 | required: true 97 | - name: policy_type 98 | description: The constraint type to work with (either 'boolean' or 'list') 99 | varType: string 100 | defaultValue: list 101 | - name: allow_list_length 102 | description: The number of elements in the allow list 103 | varType: number 104 | defaultValue: 0 105 | - name: deny_list_length 106 | description: The number of elements in the deny list 107 | varType: number 108 | defaultValue: 0 109 | requirements: 110 | roles: 111 | - level: Project 112 | roles: 113 | - roles/orgpolicy.policyAdmin 114 | - level: Project 115 | roles: 116 | - roles/owner 117 | services: 118 | - cloudresourcemanager.googleapis.com 119 | - storage-api.googleapis.com 120 | - serviceusage.googleapis.com 121 | - orgpolicy.googleapis.com 122 | providerVersions: 123 | - source: hashicorp/google 124 | version: ">= 3.53, < 7" 125 | - source: hashicorp/null 126 | version: ">= 2.1" 127 | -------------------------------------------------------------------------------- /modules/bucket_policy_only/README.md: -------------------------------------------------------------------------------- 1 | # Bucket Policy Only Module 2 | 3 | This Terraform module allows to set a `Uniform Bucket-level Access` [Organization Policy](https://cloud.google.com/storage/docs/uniform-bucket-level-access). The policy may be applied on organization, folder or project level. 4 | 5 | 6 | ## Inputs 7 | 8 | | Name | Description | Type | Default | Required | 9 | |------|-------------|------|---------|:--------:| 10 | | exclude\_folders | Set of folders to exclude from the policy | `set(string)` | `[]` | no | 11 | | exclude\_projects | Set of projects to exclude from the policy | `set(string)` | `[]` | no | 12 | | folder\_id | The folder id for putting the policy | `string` | `null` | no | 13 | | organization\_id | The organization id for putting the policy | `string` | `null` | no | 14 | | policy\_for | Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`. | `string` | n/a | yes | 15 | | project\_id | The project id for putting the policy | `string` | `null` | no | 16 | 17 | ## Outputs 18 | 19 | No outputs. 20 | 21 | 22 | -------------------------------------------------------------------------------- /modules/bucket_policy_only/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "storage-uniform-bucket-level-access" { 18 | source = "../../" 19 | policy_for = var.policy_for 20 | organization_id = var.organization_id 21 | folder_id = var.folder_id 22 | project_id = var.project_id 23 | constraint = "constraints/storage.uniformBucketLevelAccess" 24 | policy_type = "boolean" 25 | enforce = true 26 | exclude_folders = var.exclude_folders 27 | exclude_projects = var.exclude_projects 28 | } 29 | -------------------------------------------------------------------------------- /modules/bucket_policy_only/metadata.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: blueprints.cloud.google.com/v1alpha1 16 | kind: BlueprintMetadata 17 | metadata: 18 | name: terraform-google-org-policy 19 | annotations: 20 | config.kubernetes.io/local-config: "true" 21 | spec: 22 | info: 23 | title: Bucket Policy Only Module 24 | source: 25 | repo: https://github.com/terraform-google-modules/terraform-google-org-policy.git 26 | sourceType: git 27 | dir: /modules/bucket_policy_only 28 | version: 7.0.0 29 | actuationTool: 30 | flavor: Terraform 31 | version: ">= 1.3" 32 | description: {} 33 | content: 34 | examples: 35 | - name: basic_org_policies 36 | location: examples/basic_org_policies 37 | - name: boolean_org_exclude 38 | location: examples/boolean_org_exclude 39 | - name: boolean_project_allow 40 | location: examples/boolean_project_allow 41 | - name: list_folder_deny 42 | location: examples/list_folder_deny 43 | - name: list_org_exclude 44 | location: examples/list_org_exclude 45 | - name: v2_boolean_org_enforce 46 | location: examples/v2_boolean_org_enforce 47 | interfaces: 48 | variables: 49 | - name: policy_for 50 | description: "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 51 | varType: string 52 | required: true 53 | - name: organization_id 54 | description: The organization id for putting the policy 55 | varType: string 56 | - name: folder_id 57 | description: The folder id for putting the policy 58 | varType: string 59 | - name: project_id 60 | description: The project id for putting the policy 61 | varType: string 62 | - name: exclude_folders 63 | description: Set of folders to exclude from the policy 64 | varType: set(string) 65 | defaultValue: [] 66 | - name: exclude_projects 67 | description: Set of projects to exclude from the policy 68 | varType: set(string) 69 | defaultValue: [] 70 | requirements: 71 | roles: 72 | - level: Project 73 | roles: 74 | - roles/orgpolicy.policyAdmin 75 | - level: Project 76 | roles: 77 | - roles/owner 78 | services: 79 | - cloudresourcemanager.googleapis.com 80 | - storage-api.googleapis.com 81 | - serviceusage.googleapis.com 82 | - orgpolicy.googleapis.com 83 | providerVersions: 84 | - source: hashicorp/google 85 | version: ">= 3.53, < 7" 86 | -------------------------------------------------------------------------------- /modules/bucket_policy_only/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "policy_for" { 18 | description = "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 19 | type = string 20 | } 21 | 22 | variable "organization_id" { 23 | description = "The organization id for putting the policy" 24 | type = string 25 | default = null 26 | } 27 | 28 | variable "folder_id" { 29 | description = "The folder id for putting the policy" 30 | type = string 31 | default = null 32 | } 33 | 34 | variable "project_id" { 35 | description = "The project id for putting the policy" 36 | type = string 37 | default = null 38 | } 39 | 40 | variable "exclude_folders" { 41 | description = "Set of folders to exclude from the policy" 42 | type = set(string) 43 | default = [] 44 | } 45 | 46 | variable "exclude_projects" { 47 | description = "Set of projects to exclude from the policy" 48 | type = set(string) 49 | default = [] 50 | } 51 | -------------------------------------------------------------------------------- /modules/bucket_policy_only/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | 21 | google = { 22 | source = "hashicorp/google" 23 | version = ">= 3.53, < 7" 24 | } 25 | } 26 | 27 | provider_meta "google" { 28 | module_name = "blueprints/terraform/terraform-google-org-policy:bucket_policy_only/v7.0.0" 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /modules/domain_restricted_sharing/README.md: -------------------------------------------------------------------------------- 1 | # Domain Restricted Sharing Module 2 | 3 | This Terraform module allows to set a `Domain Restricted Sharing` [Organization Policy](https://cloud.google.com/resource-manager/docs/organization-policy/restricting-domains) for a list of domains. The policy may be applied on organization, folder or project level. 4 | 5 | 6 | ## Inputs 7 | 8 | | Name | Description | Type | Default | Required | 9 | |------|-------------|------|---------|:--------:| 10 | | domains\_to\_allow | The list of domains to allow users from | `list(string)` | n/a | yes | 11 | | exclude\_folders | Set of folders to exclude from the policy | `set(string)` | `[]` | no | 12 | | exclude\_projects | Set of projects to exclude from the policy | `set(string)` | `[]` | no | 13 | | folder\_id | The folder id for putting the policy | `string` | `null` | no | 14 | | organization\_id | The organization id for putting the policy | `string` | `null` | no | 15 | | policy\_for | Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`. | `string` | n/a | yes | 16 | | project\_id | The project id for putting the policy | `string` | `null` | no | 17 | 18 | ## Outputs 19 | 20 | No outputs. 21 | 22 | 23 | -------------------------------------------------------------------------------- /modules/domain_restricted_sharing/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | data "google_organization" "orgs" { 18 | for_each = toset(var.domains_to_allow) 19 | domain = each.value 20 | } 21 | 22 | module "allowed-policy-member-domains" { 23 | source = "../../" 24 | policy_for = var.policy_for 25 | organization_id = var.organization_id 26 | folder_id = var.folder_id 27 | project_id = var.project_id 28 | constraint = "constraints/iam.allowedPolicyMemberDomains" 29 | policy_type = "list" 30 | allow = [for org in data.google_organization.orgs : org["directory_customer_id"]] 31 | allow_list_length = length(var.domains_to_allow) 32 | exclude_folders = var.exclude_folders 33 | exclude_projects = var.exclude_projects 34 | } 35 | -------------------------------------------------------------------------------- /modules/domain_restricted_sharing/metadata.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: blueprints.cloud.google.com/v1alpha1 16 | kind: BlueprintMetadata 17 | metadata: 18 | name: terraform-google-org-policy 19 | annotations: 20 | config.kubernetes.io/local-config: "true" 21 | spec: 22 | info: 23 | title: Domain Restricted Sharing Module 24 | source: 25 | repo: https://github.com/terraform-google-modules/terraform-google-org-policy.git 26 | sourceType: git 27 | dir: /modules/domain_restricted_sharing 28 | version: 7.0.0 29 | actuationTool: 30 | flavor: Terraform 31 | version: ">= 1.3" 32 | description: {} 33 | content: 34 | examples: 35 | - name: basic_org_policies 36 | location: examples/basic_org_policies 37 | - name: boolean_org_exclude 38 | location: examples/boolean_org_exclude 39 | - name: boolean_project_allow 40 | location: examples/boolean_project_allow 41 | - name: list_folder_deny 42 | location: examples/list_folder_deny 43 | - name: list_org_exclude 44 | location: examples/list_org_exclude 45 | - name: v2_boolean_org_enforce 46 | location: examples/v2_boolean_org_enforce 47 | interfaces: 48 | variables: 49 | - name: policy_for 50 | description: "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 51 | varType: string 52 | required: true 53 | - name: organization_id 54 | description: The organization id for putting the policy 55 | varType: string 56 | - name: folder_id 57 | description: The folder id for putting the policy 58 | varType: string 59 | - name: project_id 60 | description: The project id for putting the policy 61 | varType: string 62 | - name: domains_to_allow 63 | description: The list of domains to allow users from 64 | varType: list(string) 65 | required: true 66 | - name: exclude_folders 67 | description: Set of folders to exclude from the policy 68 | varType: set(string) 69 | defaultValue: [] 70 | - name: exclude_projects 71 | description: Set of projects to exclude from the policy 72 | varType: set(string) 73 | defaultValue: [] 74 | requirements: 75 | roles: 76 | - level: Project 77 | roles: 78 | - roles/orgpolicy.policyAdmin 79 | - level: Project 80 | roles: 81 | - roles/owner 82 | services: 83 | - cloudresourcemanager.googleapis.com 84 | - storage-api.googleapis.com 85 | - serviceusage.googleapis.com 86 | - orgpolicy.googleapis.com 87 | providerVersions: 88 | - source: hashicorp/google 89 | version: ">= 3.53, < 7" 90 | -------------------------------------------------------------------------------- /modules/domain_restricted_sharing/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "policy_for" { 18 | description = "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 19 | type = string 20 | } 21 | 22 | variable "organization_id" { 23 | description = "The organization id for putting the policy" 24 | type = string 25 | default = null 26 | } 27 | 28 | variable "folder_id" { 29 | description = "The folder id for putting the policy" 30 | type = string 31 | default = null 32 | } 33 | 34 | variable "project_id" { 35 | description = "The project id for putting the policy" 36 | type = string 37 | default = null 38 | } 39 | 40 | variable "domains_to_allow" { 41 | description = "The list of domains to allow users from" 42 | type = list(string) 43 | } 44 | 45 | variable "exclude_folders" { 46 | description = "Set of folders to exclude from the policy" 47 | type = set(string) 48 | default = [] 49 | } 50 | 51 | variable "exclude_projects" { 52 | description = "Set of projects to exclude from the policy" 53 | type = set(string) 54 | default = [] 55 | } 56 | -------------------------------------------------------------------------------- /modules/domain_restricted_sharing/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | 21 | google = { 22 | source = "hashicorp/google" 23 | version = ">= 3.53, < 7" 24 | } 25 | } 26 | 27 | provider_meta "google" { 28 | module_name = "blueprints/terraform/terraform-google-org-policy:domain_restricted_sharing/v7.0.0" 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /modules/org_policy_v2/README.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Organization Policy v2 Terraform Module 2 | 3 | This Terraform module makes it easier to manage [organization policies](https://cloud.google.com/resource-manager/docs/organization-policy/overview) for your Google Cloud environment, particularly when you want to have exclusion rules. This module will allow you to set a top-level org policy and then disable it on individual projects or folders easily. This module allows **_conditional policy enforcements based on the latest API version_** of the organization policies API. 4 | 5 | Organization Policies are of two types `boolean` and `list`. 6 | 7 | --- 8 | 9 | ## Usage 10 | Example usage is included in the [examples](./examples/org_policy_v2) folder, but simple usage is as follows: 11 | 12 | - Boolean organization policy 13 | 14 | ```hcl 15 | module "gcp_org_policy_v2_bool" { 16 | source = "terraform-google-modules/org-policy/google//modules/org_policy_v2" 17 | version = "~> 5.2.0" 18 | 19 | policy_root = "organization" # either of organization, folder or project 20 | policy_root_id = "123456789" # either of org id, folder id or project id 21 | constraint = "constraint name" # constraint identifier without constraints/ prefix. Example "compute.requireOsLogin" 22 | policy_type = "boolean" # either of list or boolean 23 | exclude_folders = [] 24 | exclude_projects = [] 25 | 26 | rules = [ 27 | # Rule 1 28 | { 29 | enforcement = true 30 | }, 31 | # Rule 2 32 | { 33 | enforcement = true 34 | conditions = [{ 35 | description = "description of the condition" 36 | expression = "resource.matchTagId('tagKeys/123456789', 'tagValues/123456789') && resource.matchTag('123456789/env', 'prod')" 37 | location = "sample-location.log" 38 | title = "Title of the condition" 39 | }] 40 | }, 41 | ] 42 | } 43 | ``` 44 | 45 | - Boolean organization policy with parameters 46 | 47 | ```hcl 48 | module "parameterized_org_policy_v2_bool" { 49 | source = "terraform-google-modules/org-policy/google//modules/org_policy_v2" 50 | version = "~> 7.0" 51 | 52 | policy_root = "organization" # either of organization, folder or project 53 | policy_root_id = "123456789" # either of org id, folder id or project id 54 | constraint = "constraint name" # constraint identifier without constraints/ prefix. Example "essentialcontacts.managed.allowedContactDomains" 55 | policy_type = "boolean" # either of list or boolean 56 | exclude_folders = [] 57 | exclude_projects = [] 58 | 59 | rules = [ 60 | # Rule 1 61 | { 62 | enforcement = false 63 | }, 64 | # Rule 2 65 | { 66 | enforcement = true 67 | parameters = jsonencode({"parameter1" : ["value1", "value2"], "parameter2" : true}) 68 | conditions = [{ 69 | description = "description of the condition" 70 | expression = "resource.matchTagId('tagKeys/123456789', 'tagValues/123456789') && resource.matchTag('123456789/env', 'prod')" 71 | location = "sample-location.log" 72 | title = "Title of the condition" 73 | }] 74 | }, 75 | ] 76 | } 77 | ``` 78 | 79 | - List organization policy 80 | 81 | ```hcl 82 | module "gcp_org_policy_v2_list" { 83 | source = "terraform-google-modules/org-policy/google//modules/org_policy_v2" 84 | version = "~> 7.0" 85 | 86 | policy_root = "organization" # either of organization, folder or project 87 | policy_root_id = "123456789" # either of org id, folder id or project id 88 | constraint = "constraint name" # constraint identifier without constraints/ prefix. Example "gcp.resourceLocations" 89 | policy_type = "list" 90 | 91 | rules = [ 92 | # Rule 1 93 | { 94 | enforcement = true 95 | allow = ["in:us-locations"] 96 | } 97 | ] 98 | } 99 | ``` 100 | 101 | ### Variables 102 | To control module's behavior, change variables' values regarding the following: 103 | 104 | - `constraint`: set this variable with the [constraint value](https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints#available_constraints) in the form `{constraint identifier}`. For example, `serviceuser.services` 105 | - `policy_type`: Specify either `boolean` for boolean policies or `list` for list policies. 106 | - `policy_root`: set one of the following values to determine where the policy is applied. Values should be either one of the below. 107 | - organization 108 | - project 109 | - folder 110 | - `policy_root_id`: set one of the following values to determine where the policy is applied. Based on `policy_root`, either one of the below IDs should be provided. 111 | - organization_id 112 | - project_id 113 | - folder_id 114 | - `exclude_folders`: a list of folder IDs to be excluded from this policy. These folders must be lower in the hierarchy than the policy root. 115 | - `exclude_projects`: a list of project IDs to be excluded from this policy. They must be lower in the hierarchy than the policy root. 116 | - `rules`: Specify policy rules and conditions. Rules contain the following parameters: 117 | - `enforcement`: if `true` or `null`then policy will `deny_all`; if `false` then policy will `allow_all`. Applies for `boolean` based policies. 118 | - `parameters`: Applies for `boolean` type policies for `managed` constraints, if constraint has parameters defined. Pass parameter values when policy enforcement is enabled. Ensure that parameter value types match those defined in the constraint definition. For example: `{"allowedLocations" : ["us-east1", "us-west1"], "allowAll" : true }` 119 | - `allow`: list of values to include in the policy with ALLOW behavior. Set `enforce` to `null` to use it. 120 | - `deny`: list of values to include in the policy with DENY behavior. Set `enforce` to `null` to use it. 121 | - `conditions`: A condition which determines whether this rule is used in the evaluation of the policy. When set, the expression field in the `Expr` must include from 1 to 10 subexpressions, joined by the "||" or "&&" operators. Each subexpression must be of the form "resource.matchTag('/tag_key_short_name, 'tag_value_short_name')". or "resource.matchTagId('tagKeys/key_id', 'tagValues/value_id')". where key_name and value_name are the resource names for Label Keys and Values. These names are available from the Tag Manager Service. An example expression is: "resource.matchTag('123456789/environment, 'prod')". or "resource.matchTagId('tagKeys/123', 'tagValues/456')". Each condition has the following properties: 122 | - `description`: Description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI. 123 | - `expression`: Common Expression Language, or CEL, is the expression language used to specify conditional expressions. A conditional expression consists of one or more statements that are joined using logical operators (&&, ||, or !). For more information, see the [CEL spec](https://github.com/google/cel-spec) and its [language definition](https://github.com/google/cel-spec/blob/master/doc/langdef.md). 124 | - `location`: String indicating the location of the expression for error reporting, e.g. a file name and a position in the file. 125 | - `title`: Title for the expression, i.e. a short string describing its purpose. This can be used e.g. in UIs which allow to enter the expression. 126 | 127 | --- 128 | 129 | ### IMPORTANT 130 | - Boolean policies (with `type: "boolean"`) can set the following variables: 131 | - `enforcement`: if `true` or `null` then the policy is enforced at the root; if `false` then policy is not enforced at the root. 132 | - Following requirements apply, refer [Terraform Documentation](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/org_policy_policy#rules): 133 | - There must be one and only one Policy Rule where condition is unset. 134 | - Boolean Policy Rules with conditions must set enforced to the opposite of the PolicyRule without a condition. 135 | - During policy evaluation, Policy Rules with conditions that are true for a target resource take precedence. 136 | 137 | - List policies (with `type: "list"`) can set `allow` and `deny` with a list of resources to allow or deny. For `enforcement` you can set it as follows: 138 | - set `enforcement` = false for `allow all` 139 | - set `enforcement` = true for `deny all` 140 | 141 | --- 142 | 143 | 144 | ## Inputs 145 | 146 | | Name | Description | Type | Default | Required | 147 | |------|-------------|------|---------|:--------:| 148 | | constraint | The constraint to be applied | `string` | n/a | yes | 149 | | exclude\_folders | Set of folders to exclude from the policy | `set(string)` | `[]` | no | 150 | | exclude\_projects | Set of projects to exclude from the policy | `set(string)` | `[]` | no | 151 | | inherit\_from\_parent | Determines the inheritance behavior for this policy (only supported on list constraints) | `bool` | `"false"` | no | 152 | | policy\_root | Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`. | `string` | `"organization"` | no | 153 | | policy\_root\_id | The policy root id, either of organization\_id, folder\_id or project\_id | `string` | `null` | no | 154 | | policy\_type | The constraint type to work with (either 'boolean' or 'list') | `string` | `"list"` | no | 155 | | rules | List of rules per policy. |
list(object(
{
enforcement = bool
parameters = optional(string, null)
allow = optional(list(string), [])
deny = optional(list(string), [])
conditions = optional(list(object(
{
description = string
expression = string
title = string
location = string
}
)), [])
}
))
| n/a | yes | 156 | 157 | ## Outputs 158 | 159 | | Name | Description | 160 | |------|-------------| 161 | | constraint | Policy Constraint Identifier without constraints/ prefix | 162 | | policy\_root | Policy Root in the hierarchy for the given policy | 163 | | policy\_root\_id | Project Root ID at which the policy is applied | 164 | 165 | 166 | 167 | --- 168 | 169 | ## Compatibility 170 | This module is meant for use with Terraform 1.3+ and tested using Terraform 1.0+. If you find incompatibilities using Terraform >=1.3, please open an issue. 171 | If you haven't 172 | [upgraded](https://www.terraform.io/upgrade-guides/0-13.html) and need a Terraform 173 | 0.12.x-compatible version of this module, the last released version 174 | intended for Terraform 0.12.x is [v4.0.0](https://registry.terraform.io/modules/terraform-google-modules/-org-policy/google/v4.0.0). 175 | 176 | ## Requirements 177 | ### Terraform plugins 178 | - [Terraform](https://www.terraform.io/downloads.html) >= 1.3.0 179 | - [terraform-provider-google](https://github.com/terraform-providers/terraform-provider-google) >= v2.5.0 180 | 181 | ### Permissions 182 | In order to execute this module, the Service Account you run as must have the **Organization Policy Administrator** (`roles/orgpolicy.PolicyAdmin`) role. 183 | 184 | ## Install 185 | ### Terraform 186 | Be sure you have the correct Terraform version (0.12.x), you can choose the binary here: 187 | - https://releases.hashicorp.com/terraform/ 188 | 189 | ### Terraform plugins 190 | 191 | - [terraform-provider-google](https://github.com/terraform-providers/terraform-provider-google) >= v2.5.0 192 | 193 | -------------------------------------------------------------------------------- /modules/org_policy_v2/boolean_constraints.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Organization policy (boolean constraint) 19 | *****************************************/ 20 | resource "google_org_policy_policy" "org_policy_boolean" { 21 | count = local.organization && local.boolean_policy ? 1 : 0 22 | 23 | name = "${local.policy_root}/${var.policy_root_id}/policies/${var.constraint}" 24 | parent = "${local.policy_root}/${var.policy_root_id}" 25 | 26 | spec { 27 | dynamic "rules" { 28 | for_each = local.rules 29 | content { 30 | enforce = rules.value.enforcement != false ? "TRUE" : "FALSE" 31 | parameters = rules.value.parameters 32 | dynamic "condition" { 33 | for_each = { for k, v in rules.value.conditions : k => v if length(rules.value.conditions) > 0 } 34 | content { 35 | description = condition.value.description 36 | expression = condition.value.expression 37 | location = condition.value.location 38 | title = condition.value.title 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | 46 | /****************************************** 47 | Folder policy (boolean constraint) 48 | *****************************************/ 49 | resource "google_org_policy_policy" "folder_policy_boolean" { 50 | count = local.folder && local.boolean_policy ? 1 : 0 51 | 52 | name = "${local.policy_root}/${var.policy_root_id}/policies/${var.constraint}" 53 | parent = "${local.policy_root}/${var.policy_root_id}" 54 | 55 | spec { 56 | dynamic "rules" { 57 | for_each = local.rules 58 | content { 59 | enforce = rules.value.enforcement != false ? "TRUE" : "FALSE" 60 | parameters = rules.value.parameters 61 | dynamic "condition" { 62 | for_each = { for k, v in rules.value.conditions : k => v if length(rules.value.conditions) > 0 } 63 | content { 64 | description = condition.value.description 65 | expression = condition.value.expression 66 | location = condition.value.location 67 | title = condition.value.title 68 | } 69 | } 70 | } 71 | } 72 | } 73 | } 74 | 75 | /****************************************** 76 | Project policy (boolean constraint) 77 | *****************************************/ 78 | resource "google_org_policy_policy" "project_policy_boolean" { 79 | count = local.project && local.boolean_policy ? 1 : 0 80 | 81 | name = "${local.policy_root}/${var.policy_root_id}/policies/${var.constraint}" 82 | parent = "${local.policy_root}/${var.policy_root_id}" 83 | 84 | spec { 85 | dynamic "rules" { 86 | for_each = local.rules 87 | content { 88 | enforce = rules.value.enforcement != false ? "TRUE" : "FALSE" 89 | parameters = rules.value.parameters 90 | dynamic "condition" { 91 | for_each = { for k, v in rules.value.conditions : k => v if length(rules.value.conditions) > 0 } 92 | content { 93 | description = condition.value.description 94 | expression = condition.value.expression 95 | location = condition.value.location 96 | title = condition.value.title 97 | } 98 | } 99 | } 100 | } 101 | } 102 | } 103 | 104 | /****************************************** 105 | Exclude folders from policy (boolean constraint) 106 | *****************************************/ 107 | resource "google_org_policy_policy" "policy_boolean_exclude_folders" { 108 | for_each = (local.boolean_policy && !local.project) ? var.exclude_folders : [] 109 | 110 | name = "folders/${each.value}/policies/${var.constraint}" 111 | parent = "folders/${each.value}" 112 | 113 | spec { 114 | rules { 115 | enforce = "FALSE" 116 | } 117 | } 118 | } 119 | /****************************************** 120 | Exclude projects from policy (boolean constraint) 121 | *****************************************/ 122 | resource "google_org_policy_policy" "policy_boolean_exclude_projects" { 123 | for_each = (local.boolean_policy && !local.project) ? var.exclude_projects : [] 124 | 125 | name = "projects/${each.value}/policies/${var.constraint}" 126 | parent = "projects/${each.value}" 127 | 128 | spec { 129 | rules { 130 | enforce = "FALSE" 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /modules/org_policy_v2/list_constraints.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Organization policy, allow all, deny all, allow values and deny values (list constraint) 19 | *****************************************/ 20 | resource "google_org_policy_policy" "organization_policy" { 21 | count = local.organization && local.list_policy ? 1 : 0 22 | 23 | name = "${local.policy_root}/${var.policy_root_id}/policies/${var.constraint}" 24 | parent = "${local.policy_root}/${var.policy_root_id}" 25 | 26 | spec { 27 | inherit_from_parent = var.inherit_from_parent 28 | dynamic "rules" { 29 | for_each = local.rules 30 | content { 31 | dynamic "condition" { 32 | for_each = { for k, v in rules.value.conditions : k => v if length(rules.value.conditions) > 0 } 33 | content { 34 | description = condition.value.description 35 | expression = condition.value.expression 36 | location = condition.value.location 37 | title = condition.value.title 38 | } 39 | } 40 | allow_all = rules.value.enforcement == false ? "TRUE" : null 41 | deny_all = rules.value.enforcement == true ? "TRUE" : null 42 | dynamic "values" { 43 | for_each = rules.value.allow_list_length > 0 || rules.value.deny_list_length > 0 ? rules.value.values : [] 44 | content { 45 | allowed_values = rules.value.allow_list_length > 0 && rules.value.deny_list_length == 0 ? values.value.allow : null 46 | denied_values = rules.value.deny_list_length > 0 && rules.value.allow_list_length == 0 ? values.value.deny : null 47 | } 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | /****************************************** 55 | Folder policy, allow all, deny all, allow values and deny values (list constraint) 56 | *****************************************/ 57 | resource "google_org_policy_policy" "folder_policy" { 58 | count = local.folder && local.list_policy ? 1 : 0 59 | 60 | name = "${local.policy_root}/${var.policy_root_id}/policies/${var.constraint}" 61 | parent = "${local.policy_root}/${var.policy_root_id}" 62 | 63 | spec { 64 | inherit_from_parent = var.inherit_from_parent 65 | dynamic "rules" { 66 | for_each = local.rules 67 | content { 68 | dynamic "condition" { 69 | for_each = { for k, v in rules.value.conditions : k => v if length(rules.value.conditions) > 0 } 70 | content { 71 | description = condition.value.description 72 | expression = condition.value.expression 73 | location = condition.value.location 74 | title = condition.value.title 75 | } 76 | } 77 | allow_all = rules.value.enforcement == false ? "TRUE" : null 78 | deny_all = rules.value.enforcement == true ? "TRUE" : null 79 | dynamic "values" { 80 | for_each = rules.value.allow_list_length > 0 || rules.value.deny_list_length > 0 ? rules.value.values : [] 81 | content { 82 | allowed_values = rules.value.allow_list_length > 0 && rules.value.deny_list_length == 0 ? values.value.allow : null 83 | denied_values = rules.value.deny_list_length > 0 && rules.value.allow_list_length == 0 ? values.value.deny : null 84 | } 85 | } 86 | } 87 | } 88 | } 89 | } 90 | 91 | /****************************************** 92 | Project policy, allow all, deny all, allow values and deny values (list constraint) 93 | *****************************************/ 94 | resource "google_org_policy_policy" "project_policy" { 95 | count = local.project && local.list_policy ? 1 : 0 96 | 97 | name = "${local.policy_root}/${var.policy_root_id}/policies/${var.constraint}" 98 | parent = "${local.policy_root}/${var.policy_root_id}" 99 | 100 | spec { 101 | inherit_from_parent = var.inherit_from_parent 102 | dynamic "rules" { 103 | for_each = local.rules 104 | content { 105 | dynamic "condition" { 106 | for_each = { for k, v in rules.value.conditions : k => v if length(rules.value.conditions) > 0 } 107 | content { 108 | description = condition.value.description 109 | expression = condition.value.expression 110 | location = condition.value.location 111 | title = condition.value.title 112 | } 113 | } 114 | allow_all = rules.value.enforcement == false ? "TRUE" : null 115 | deny_all = rules.value.enforcement == true ? "TRUE" : null 116 | dynamic "values" { 117 | for_each = rules.value.allow_list_length > 0 || rules.value.deny_list_length > 0 ? rules.value.values : [] 118 | content { 119 | allowed_values = rules.value.allow_list_length > 0 && rules.value.deny_list_length == 0 ? values.value.allow : null 120 | denied_values = rules.value.deny_list_length > 0 && rules.value.allow_list_length == 0 ? values.value.deny : null 121 | } 122 | } 123 | } 124 | } 125 | } 126 | } 127 | 128 | /****************************************** 129 | Exclude folders from policy (list constraint) 130 | *****************************************/ 131 | resource "google_org_policy_policy" "folder_policy_list_exclude_folders" { 132 | for_each = (local.list_policy && !local.project) ? var.exclude_folders : [] 133 | 134 | name = "folders/${each.value}/policies/${var.constraint}" 135 | parent = "folders/${each.value}" 136 | 137 | 138 | spec { 139 | reset = true 140 | } 141 | } 142 | 143 | /****************************************** 144 | Exclude projects from policy (list constraint) 145 | *****************************************/ 146 | resource "google_org_policy_policy" "project_policy_list_exclude_projects" { 147 | for_each = (local.list_policy && !local.project) ? var.exclude_projects : [] 148 | 149 | name = "projects/${each.value}/policies/${var.constraint}" 150 | parent = "projects/${each.value}" 151 | 152 | spec { 153 | reset = true 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /modules/org_policy_v2/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /****************************************** 18 | Locals configuration for module logic 19 | *****************************************/ 20 | locals { 21 | organization = var.policy_root == "organization" 22 | folder = var.policy_root == "folder" 23 | project = var.policy_root == "project" 24 | # Making the policy roots as plural with additional 's' in the end - organizations, folders, projects 25 | policy_root = format("%s%s", var.policy_root, "s") 26 | 27 | boolean_policy = var.policy_type == "boolean" 28 | list_policy = var.policy_type == "list" 29 | 30 | # Appends the rules variable with additional details 31 | # allow and deny list length 32 | # enforcement (true or false) 33 | # values with allow and deny list items 34 | rules = [ 35 | for k, v in var.rules : 36 | merge(v, { 37 | allow_list_length = length(v.allow), 38 | deny_list_length = length(v.deny), 39 | enforcement = length(v.allow) > 0 || length(v.deny) > 0 ? null : v.enforcement, 40 | values = [{ allow = v.allow, deny = v.deny }] 41 | }) 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /modules/org_policy_v2/metadata.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: blueprints.cloud.google.com/v1alpha1 16 | kind: BlueprintMetadata 17 | metadata: 18 | name: terraform-google-org-policy 19 | annotations: 20 | config.kubernetes.io/local-config: "true" 21 | spec: 22 | info: 23 | title: Google Cloud Organization Policy v2 Terraform Module 24 | source: 25 | repo: https://github.com/terraform-google-modules/terraform-google-org-policy.git 26 | sourceType: git 27 | dir: /modules/org_policy_v2 28 | version: 7.0.0 29 | actuationTool: 30 | flavor: Terraform 31 | version: ">= 1.3" 32 | description: {} 33 | content: 34 | examples: 35 | - name: basic_org_policies 36 | location: examples/basic_org_policies 37 | - name: boolean_org_exclude 38 | location: examples/boolean_org_exclude 39 | - name: boolean_project_allow 40 | location: examples/boolean_project_allow 41 | - name: list_folder_deny 42 | location: examples/list_folder_deny 43 | - name: list_org_exclude 44 | location: examples/list_org_exclude 45 | - name: v2_boolean_org_enforce 46 | location: examples/v2_boolean_org_enforce 47 | interfaces: 48 | variables: 49 | - name: policy_root 50 | description: "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 51 | varType: string 52 | defaultValue: organization 53 | - name: policy_root_id 54 | description: The policy root id, either of organization_id, folder_id or project_id 55 | varType: string 56 | - name: exclude_folders 57 | description: Set of folders to exclude from the policy 58 | varType: set(string) 59 | defaultValue: [] 60 | - name: exclude_projects 61 | description: Set of projects to exclude from the policy 62 | varType: set(string) 63 | defaultValue: [] 64 | - name: constraint 65 | description: The constraint to be applied 66 | varType: string 67 | required: true 68 | - name: policy_type 69 | description: The constraint type to work with (either 'boolean' or 'list') 70 | varType: string 71 | defaultValue: list 72 | - name: inherit_from_parent 73 | description: Determines the inheritance behavior for this policy (only supported on list constraints) 74 | varType: bool 75 | defaultValue: "false" 76 | - name: rules 77 | description: List of rules per policy. 78 | varType: |- 79 | list(object( 80 | { 81 | enforcement = bool 82 | parameters = optional(string, null) 83 | allow = optional(list(string), []) 84 | deny = optional(list(string), []) 85 | conditions = optional(list(object( 86 | { 87 | description = string 88 | expression = string 89 | title = string 90 | location = string 91 | } 92 | )), []) 93 | } 94 | )) 95 | required: true 96 | outputs: 97 | - name: constraint 98 | description: Policy Constraint Identifier without constraints/ prefix 99 | - name: policy_root 100 | description: Policy Root in the hierarchy for the given policy 101 | - name: policy_root_id 102 | description: Project Root ID at which the policy is applied 103 | requirements: 104 | roles: 105 | - level: Project 106 | roles: 107 | - roles/orgpolicy.policyAdmin 108 | - level: Project 109 | roles: 110 | - roles/owner 111 | services: 112 | - cloudresourcemanager.googleapis.com 113 | - storage-api.googleapis.com 114 | - serviceusage.googleapis.com 115 | - orgpolicy.googleapis.com 116 | providerVersions: 117 | - source: hashicorp/google 118 | version: ">= 6.14, < 7" 119 | -------------------------------------------------------------------------------- /modules/org_policy_v2/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "policy_root" { 18 | description = "Policy Root in the hierarchy for the given policy" 19 | value = var.policy_root 20 | } 21 | 22 | output "policy_root_id" { 23 | description = "Project Root ID at which the policy is applied" 24 | value = var.policy_root_id 25 | } 26 | 27 | output "constraint" { 28 | description = "Policy Constraint Identifier without constraints/ prefix" 29 | value = var.constraint 30 | } 31 | -------------------------------------------------------------------------------- /modules/org_policy_v2/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "policy_root" { 18 | description = "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 19 | type = string 20 | default = "organization" 21 | validation { 22 | condition = contains(["organization", "folder", "project"], var.policy_root) 23 | error_message = "policy_root should be one of organization, folder, or project" 24 | } 25 | } 26 | 27 | variable "policy_root_id" { 28 | description = "The policy root id, either of organization_id, folder_id or project_id" 29 | type = string 30 | default = null 31 | } 32 | 33 | variable "exclude_folders" { 34 | description = "Set of folders to exclude from the policy" 35 | type = set(string) 36 | default = [] 37 | } 38 | 39 | variable "exclude_projects" { 40 | description = "Set of projects to exclude from the policy" 41 | type = set(string) 42 | default = [] 43 | } 44 | 45 | variable "constraint" { 46 | description = "The constraint to be applied" 47 | type = string 48 | } 49 | 50 | variable "policy_type" { 51 | description = "The constraint type to work with (either 'boolean' or 'list')" 52 | type = string 53 | default = "list" 54 | } 55 | 56 | variable "inherit_from_parent" { 57 | description = "Determines the inheritance behavior for this policy (only supported on list constraints)" 58 | type = bool 59 | default = "false" 60 | } 61 | 62 | variable "rules" { 63 | description = "List of rules per policy." 64 | type = list(object( 65 | { 66 | enforcement = bool 67 | parameters = optional(string, null) 68 | allow = optional(list(string), []) 69 | deny = optional(list(string), []) 70 | conditions = optional(list(object( 71 | { 72 | description = string 73 | expression = string 74 | title = string 75 | location = string 76 | } 77 | )), []) 78 | } 79 | )) 80 | } 81 | -------------------------------------------------------------------------------- /modules/org_policy_v2/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | 21 | google = { 22 | source = "hashicorp/google" 23 | version = ">= 6.14, < 7" 24 | } 25 | } 26 | 27 | provider_meta "google" { 28 | module_name = "blueprints/terraform/terraform-google-org-policy:org_policy_v2/v7.0.0" 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /modules/restrict_vm_external_ips/README.md: -------------------------------------------------------------------------------- 1 | # Allowed External IPs for VM instances Module 2 | 3 | This Terraform module allows to set an `Allowed External IPs for VM instances` [Organization Policy](https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints). The policy may be applied on organization, folder or project level. 4 | 5 | 6 | ## Inputs 7 | 8 | | Name | Description | Type | Default | Required | 9 | |------|-------------|------|---------|:--------:| 10 | | exclude\_folders | Set of folders to exclude from the policy | `set(string)` | `[]` | no | 11 | | exclude\_projects | Set of projects to exclude from the policy | `set(string)` | `[]` | no | 12 | | folder\_id | The folder id for putting the policy | `string` | `null` | no | 13 | | organization\_id | The organization id for putting the policy | `string` | `null` | no | 14 | | policy\_for | Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`. | `string` | n/a | yes | 15 | | project\_id | The project id for putting the policy | `string` | `null` | no | 16 | | vms\_to\_allow | The list of VMs are allowed to use external IP, every element of the list must be identified by the VM instance name, in the form: projects/PROJECT\_ID/zones/ZONE/instances/INSTANCE | `list(string)` | `[]` | no | 17 | 18 | ## Outputs 19 | 20 | No outputs. 21 | 22 | 23 | -------------------------------------------------------------------------------- /modules/restrict_vm_external_ips/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "compute-vm-external-ip-access" { 18 | source = "../../" 19 | policy_for = var.policy_for 20 | organization_id = var.organization_id 21 | folder_id = var.folder_id 22 | project_id = var.project_id 23 | constraint = "constraints/compute.vmExternalIpAccess" 24 | policy_type = "list" 25 | allow = var.vms_to_allow 26 | allow_list_length = length(var.vms_to_allow) 27 | exclude_folders = var.exclude_folders 28 | exclude_projects = var.exclude_projects 29 | } 30 | -------------------------------------------------------------------------------- /modules/restrict_vm_external_ips/metadata.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: blueprints.cloud.google.com/v1alpha1 16 | kind: BlueprintMetadata 17 | metadata: 18 | name: terraform-google-org-policy 19 | annotations: 20 | config.kubernetes.io/local-config: "true" 21 | spec: 22 | info: 23 | title: Allowed External IPs for VM instances Module 24 | source: 25 | repo: https://github.com/terraform-google-modules/terraform-google-org-policy.git 26 | sourceType: git 27 | dir: /modules/restrict_vm_external_ips 28 | version: 7.0.0 29 | actuationTool: 30 | flavor: Terraform 31 | version: ">= 1.3" 32 | description: {} 33 | content: 34 | examples: 35 | - name: basic_org_policies 36 | location: examples/basic_org_policies 37 | - name: boolean_org_exclude 38 | location: examples/boolean_org_exclude 39 | - name: boolean_project_allow 40 | location: examples/boolean_project_allow 41 | - name: list_folder_deny 42 | location: examples/list_folder_deny 43 | - name: list_org_exclude 44 | location: examples/list_org_exclude 45 | - name: v2_boolean_org_enforce 46 | location: examples/v2_boolean_org_enforce 47 | interfaces: 48 | variables: 49 | - name: policy_for 50 | description: "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 51 | varType: string 52 | required: true 53 | - name: organization_id 54 | description: The organization id for putting the policy 55 | varType: string 56 | - name: folder_id 57 | description: The folder id for putting the policy 58 | varType: string 59 | - name: project_id 60 | description: The project id for putting the policy 61 | varType: string 62 | - name: vms_to_allow 63 | description: "The list of VMs are allowed to use external IP, every element of the list must be identified by the VM instance name, in the form: projects/PROJECT_ID/zones/ZONE/instances/INSTANCE" 64 | varType: list(string) 65 | defaultValue: [] 66 | - name: exclude_folders 67 | description: Set of folders to exclude from the policy 68 | varType: set(string) 69 | defaultValue: [] 70 | - name: exclude_projects 71 | description: Set of projects to exclude from the policy 72 | varType: set(string) 73 | defaultValue: [] 74 | requirements: 75 | roles: 76 | - level: Project 77 | roles: 78 | - roles/orgpolicy.policyAdmin 79 | - level: Project 80 | roles: 81 | - roles/owner 82 | services: 83 | - cloudresourcemanager.googleapis.com 84 | - storage-api.googleapis.com 85 | - serviceusage.googleapis.com 86 | - orgpolicy.googleapis.com 87 | providerVersions: 88 | - source: hashicorp/google 89 | version: ">= 3.53, < 7" 90 | -------------------------------------------------------------------------------- /modules/restrict_vm_external_ips/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "policy_for" { 18 | description = "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 19 | type = string 20 | } 21 | 22 | variable "organization_id" { 23 | description = "The organization id for putting the policy" 24 | type = string 25 | default = null 26 | } 27 | 28 | variable "folder_id" { 29 | description = "The folder id for putting the policy" 30 | type = string 31 | default = null 32 | } 33 | 34 | variable "project_id" { 35 | description = "The project id for putting the policy" 36 | type = string 37 | default = null 38 | } 39 | 40 | variable "vms_to_allow" { 41 | description = "The list of VMs are allowed to use external IP, every element of the list must be identified by the VM instance name, in the form: projects/PROJECT_ID/zones/ZONE/instances/INSTANCE" 42 | type = list(string) 43 | default = [] 44 | } 45 | 46 | variable "exclude_folders" { 47 | description = "Set of folders to exclude from the policy" 48 | type = set(string) 49 | default = [] 50 | } 51 | 52 | variable "exclude_projects" { 53 | description = "Set of projects to exclude from the policy" 54 | type = set(string) 55 | default = [] 56 | } 57 | -------------------------------------------------------------------------------- /modules/restrict_vm_external_ips/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | 21 | google = { 22 | source = "hashicorp/google" 23 | version = ">= 3.53, < 7" 24 | } 25 | } 26 | 27 | provider_meta "google" { 28 | module_name = "blueprints/terraform/terraform-google-org-policy:restrict_vm_external_ips/v7.0.0" 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /modules/skip_default_network/README.md: -------------------------------------------------------------------------------- 1 | # Skip Default Network Creation Module 2 | 3 | This Terraform module allows to set a `Skip Default Network Creation` [Organization Policy](https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints). The policy may be applied on organization, folder or project level. 4 | 5 | 6 | ## Inputs 7 | 8 | | Name | Description | Type | Default | Required | 9 | |------|-------------|------|---------|:--------:| 10 | | exclude\_folders | Set of folders to exclude from the policy | `set(string)` | `[]` | no | 11 | | exclude\_projects | Set of projects to exclude from the policy | `set(string)` | `[]` | no | 12 | | folder\_id | The folder id for putting the policy | `string` | `null` | no | 13 | | organization\_id | The organization id for putting the policy | `string` | `null` | no | 14 | | policy\_for | Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`. | `string` | n/a | yes | 15 | | project\_id | The project id for putting the policy | `string` | `null` | no | 16 | 17 | ## Outputs 18 | 19 | No outputs. 20 | 21 | 22 | -------------------------------------------------------------------------------- /modules/skip_default_network/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "compute-skip-default-network" { 18 | source = "../../" 19 | policy_for = var.policy_for 20 | organization_id = var.organization_id 21 | folder_id = var.folder_id 22 | project_id = var.project_id 23 | constraint = "constraints/compute.skipDefaultNetworkCreation" 24 | policy_type = "boolean" 25 | enforce = true 26 | exclude_folders = var.exclude_folders 27 | exclude_projects = var.exclude_projects 28 | } 29 | -------------------------------------------------------------------------------- /modules/skip_default_network/metadata.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: blueprints.cloud.google.com/v1alpha1 16 | kind: BlueprintMetadata 17 | metadata: 18 | name: terraform-google-org-policy 19 | annotations: 20 | config.kubernetes.io/local-config: "true" 21 | spec: 22 | info: 23 | title: Skip Default Network Creation Module 24 | source: 25 | repo: https://github.com/terraform-google-modules/terraform-google-org-policy.git 26 | sourceType: git 27 | dir: /modules/skip_default_network 28 | version: 7.0.0 29 | actuationTool: 30 | flavor: Terraform 31 | version: ">= 1.3" 32 | description: {} 33 | content: 34 | examples: 35 | - name: basic_org_policies 36 | location: examples/basic_org_policies 37 | - name: boolean_org_exclude 38 | location: examples/boolean_org_exclude 39 | - name: boolean_project_allow 40 | location: examples/boolean_project_allow 41 | - name: list_folder_deny 42 | location: examples/list_folder_deny 43 | - name: list_org_exclude 44 | location: examples/list_org_exclude 45 | - name: v2_boolean_org_enforce 46 | location: examples/v2_boolean_org_enforce 47 | interfaces: 48 | variables: 49 | - name: policy_for 50 | description: "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 51 | varType: string 52 | required: true 53 | - name: organization_id 54 | description: The organization id for putting the policy 55 | varType: string 56 | - name: folder_id 57 | description: The folder id for putting the policy 58 | varType: string 59 | - name: project_id 60 | description: The project id for putting the policy 61 | varType: string 62 | - name: exclude_folders 63 | description: Set of folders to exclude from the policy 64 | varType: set(string) 65 | defaultValue: [] 66 | - name: exclude_projects 67 | description: Set of projects to exclude from the policy 68 | varType: set(string) 69 | defaultValue: [] 70 | requirements: 71 | roles: 72 | - level: Project 73 | roles: 74 | - roles/orgpolicy.policyAdmin 75 | - level: Project 76 | roles: 77 | - roles/owner 78 | services: 79 | - cloudresourcemanager.googleapis.com 80 | - storage-api.googleapis.com 81 | - serviceusage.googleapis.com 82 | - orgpolicy.googleapis.com 83 | providerVersions: 84 | - source: hashicorp/google 85 | version: ">= 3.53, < 7" 86 | -------------------------------------------------------------------------------- /modules/skip_default_network/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "policy_for" { 18 | description = "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 19 | type = string 20 | } 21 | 22 | variable "organization_id" { 23 | description = "The organization id for putting the policy" 24 | type = string 25 | default = null 26 | } 27 | 28 | variable "folder_id" { 29 | description = "The folder id for putting the policy" 30 | type = string 31 | default = null 32 | } 33 | 34 | variable "project_id" { 35 | description = "The project id for putting the policy" 36 | type = string 37 | default = null 38 | } 39 | 40 | variable "exclude_folders" { 41 | description = "Set of folders to exclude from the policy" 42 | type = set(string) 43 | default = [] 44 | } 45 | 46 | variable "exclude_projects" { 47 | description = "Set of projects to exclude from the policy" 48 | type = set(string) 49 | default = [] 50 | } 51 | -------------------------------------------------------------------------------- /modules/skip_default_network/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | 21 | google = { 22 | source = "hashicorp/google" 23 | version = ">= 3.53, < 7" 24 | } 25 | } 26 | 27 | provider_meta "google" { 28 | module_name = "blueprints/terraform/terraform-google-org-policy:skip_default_network/v7.0.0" 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | source.sh 2 | -------------------------------------------------------------------------------- /test/fixtures/boolean_org_exclude/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "boolean-org-exclude" { 18 | source = "../../../examples/boolean_org_exclude" 19 | 20 | organization_id = var.org_id 21 | excluded_folder_id = var.folder_id 22 | } 23 | -------------------------------------------------------------------------------- /test/fixtures/boolean_org_exclude/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "org_id" { 18 | value = var.org_id 19 | } 20 | 21 | output "folder_id" { 22 | value = var.folder_id 23 | } 24 | -------------------------------------------------------------------------------- /test/fixtures/boolean_org_exclude/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "org_id" { 18 | type = string 19 | } 20 | 21 | variable "folder_id" { 22 | type = string 23 | } 24 | -------------------------------------------------------------------------------- /test/fixtures/boolean_org_exclude/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">=0.12.6" 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/boolean_project_allow/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "boolean-project-allow" { 18 | source = "../../../examples/boolean_project_allow" 19 | 20 | project_id = var.project_id 21 | } 22 | -------------------------------------------------------------------------------- /test/fixtures/boolean_project_allow/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "project_id" { 18 | value = var.project_id 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/boolean_project_allow/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/boolean_project_allow/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">=0.12.6" 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/list_folder_deny/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "list-folder-deny" { 18 | source = "../../../examples/list_folder_deny" 19 | 20 | folder_id = var.folder_id 21 | } 22 | -------------------------------------------------------------------------------- /test/fixtures/list_folder_deny/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "folder_id" { 18 | value = var.folder_id 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/list_folder_deny/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "folder_id" { 18 | type = string 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/list_folder_deny/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">=0.12.6" 19 | } 20 | -------------------------------------------------------------------------------- /test/fixtures/list_org_exclude/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "list-org-exclude" { 18 | source = "../../../examples/list_org_exclude" 19 | 20 | organization_id = var.org_id 21 | shared_reservation_project_id = var.project_id 22 | } 23 | -------------------------------------------------------------------------------- /test/fixtures/list_org_exclude/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "org_id" { 18 | value = var.org_id 19 | } 20 | 21 | output "project_id" { 22 | value = var.project_id 23 | } 24 | -------------------------------------------------------------------------------- /test/fixtures/list_org_exclude/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "org_id" { 18 | type = string 19 | } 20 | 21 | variable "project_id" { 22 | type = string 23 | } 24 | -------------------------------------------------------------------------------- /test/fixtures/list_org_exclude/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">=0.12.6" 19 | } 20 | -------------------------------------------------------------------------------- /test/integration/boolean_org_exclude/controls/gcloud.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Roles amount are used to test how the module behaves on configuration updates. 16 | # Workaround InSpec lack of support for integer by parsing it from string. 17 | 18 | folder_id = attribute('folder_id') 19 | org_id = attribute('org_id') 20 | 21 | control 'boolean-org-exclude' do 22 | title 'Test boolean exclude org policy is correct' 23 | 24 | describe command("gcloud beta resource-manager org-policies list --organization=#{org_id} --format=json") do 25 | its(:exit_status) { should eq 0 } 26 | its(:stderr) { should eq '' } 27 | 28 | let(:data) do 29 | if subject.exit_status == 0 30 | JSON.parse(subject.stdout).select{|x| x['constraint'] == 'constraints/compute.disableSerialPortAccess'}[0] 31 | else 32 | {} 33 | end 34 | end 35 | 36 | describe "boolean org policy compute.disableSerialPortAccess" do 37 | it "should exist" do 38 | expect(data).to_not be_empty 39 | end 40 | 41 | it "should be enforced" do 42 | expect(data['booleanPolicy']).to include( 43 | "enforced" => true 44 | ) 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /test/integration/boolean_org_exclude/inspec.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | name: boolean_org_exclude 17 | attributes: 18 | - name: org_id 19 | required: true 20 | type: string 21 | - name: folder_id 22 | required: true 23 | type: string 24 | -------------------------------------------------------------------------------- /test/integration/boolean_project_allow/controls/gcloud.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Roles amount are used to test how the module behaves on configuration updates. 16 | # Workaround InSpec lack of support for integer by parsing it from string. 17 | 18 | project_id = attribute('project_id') 19 | 20 | control 'boolean-project-allow' do 21 | title 'Test boolean project allow policy is correct' 22 | 23 | describe command("gcloud beta resource-manager org-policies list --project=#{project_id} --format=json") do 24 | its(:exit_status) { should eq 0 } 25 | its(:stderr) { should eq '' } 26 | 27 | let(:data) do 28 | if subject.exit_status == 0 29 | JSON.parse(subject.stdout).select{|x| x['constraint'] == 'constraints/compute.disableSerialPortAccess'}[0] 30 | else 31 | {} 32 | end 33 | end 34 | 35 | describe "boolean project org policy compute.disableSerialPortAccess" do 36 | it "should exist" do 37 | expect(data).to_not be_empty 38 | end 39 | 40 | it "should not be enforced" do 41 | expect(data['booleanPolicy']).to_not include( 42 | "enforced" => true 43 | ) 44 | end 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /test/integration/boolean_project_allow/inspec.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | name: boolean_project_allow 17 | attributes: 18 | - name: project_id 19 | required: true 20 | type: string 21 | -------------------------------------------------------------------------------- /test/integration/discover_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package test 16 | 17 | import ( 18 | // should be imported to enable testing for GO modules 19 | "testing" 20 | 21 | // should be imported to use terraform helpers in blueprints test framework 22 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" 23 | ) 24 | 25 | // entry function for the test; can be named as Test* 26 | func TestAll(t *testing.T) { 27 | // the helper to autodiscover and test blueprint examples 28 | tft.AutoDiscoverAndTest(t) 29 | } 30 | -------------------------------------------------------------------------------- /test/integration/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/prabhu34/terraform-google-org-policy/test/integration 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.5 6 | 7 | require ( 8 | github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.17.5 9 | github.com/stretchr/testify v1.10.0 10 | ) 11 | 12 | require ( 13 | github.com/agext/levenshtein v1.2.3 // indirect 14 | github.com/alexflint/go-filemutex v1.3.0 // indirect 15 | github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect 16 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect 17 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 18 | github.com/go-errors/errors v1.5.0 // indirect 19 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 20 | github.com/go-openapi/jsonreference v0.20.2 // indirect 21 | github.com/go-openapi/swag v0.23.0 // indirect 22 | github.com/google/gnostic-models v0.6.9 // indirect 23 | github.com/google/go-cmp v0.6.0 // indirect 24 | github.com/gruntwork-io/terratest v0.48.1 // indirect 25 | github.com/hashicorp/errwrap v1.1.0 // indirect 26 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 27 | github.com/hashicorp/go-getter/v2 v2.2.3 // indirect 28 | github.com/hashicorp/go-multierror v1.1.1 // indirect 29 | github.com/hashicorp/go-safetemp v1.0.0 // indirect 30 | github.com/hashicorp/go-version v1.7.0 // indirect 31 | github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f // indirect 32 | github.com/hashicorp/hcl/v2 v2.22.0 // indirect 33 | github.com/hashicorp/terraform-config-inspect v0.0.0-20241129133400-c404f8227ea6 // indirect 34 | github.com/hashicorp/terraform-json v0.24.0 // indirect 35 | github.com/jinzhu/copier v0.4.0 // indirect 36 | github.com/josharian/intern v1.0.0 // indirect 37 | github.com/klauspost/compress v1.16.7 // indirect 38 | github.com/mailru/easyjson v0.7.7 // indirect 39 | github.com/mattn/go-shellwords v1.0.12 // indirect 40 | github.com/mattn/go-zglob v0.0.4 // indirect 41 | github.com/mitchellh/go-homedir v1.1.0 // indirect 42 | github.com/mitchellh/go-testing-interface v1.14.2-0.20210821155943-2d9075ca8770 // indirect 43 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect 44 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect 45 | github.com/tidwall/gjson v1.18.0 // indirect 46 | github.com/tidwall/match v1.1.1 // indirect 47 | github.com/tidwall/pretty v1.2.1 // indirect 48 | github.com/tidwall/sjson v1.2.5 // indirect 49 | github.com/tmccombs/hcl2json v0.6.4 // indirect 50 | github.com/ulikunitz/xz v0.5.11 // indirect 51 | github.com/zclconf/go-cty v1.15.1 // indirect 52 | golang.org/x/crypto v0.31.0 // indirect 53 | golang.org/x/mod v0.22.0 // indirect 54 | golang.org/x/net v0.33.0 // indirect 55 | golang.org/x/sync v0.10.0 // indirect 56 | golang.org/x/sys v0.28.0 // indirect 57 | golang.org/x/text v0.21.0 // indirect 58 | golang.org/x/tools v0.26.0 // indirect 59 | google.golang.org/protobuf v1.35.1 // indirect 60 | gopkg.in/yaml.v3 v3.0.1 // indirect 61 | k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect 62 | sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect 63 | sigs.k8s.io/yaml v1.4.0 // indirect 64 | ) 65 | -------------------------------------------------------------------------------- /test/integration/go.sum: -------------------------------------------------------------------------------- 1 | github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.17.5 h1:nnAKqkgp1eIdBzaMLCvA85Rn+g2ZolmsI1F9tGsQeYY= 2 | github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.17.5/go.mod h1:Bog3kcmtLKgDc4rVVjUDWIpVyUKyUxMAoEPYlph6ql8= 3 | github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= 4 | github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= 5 | github.com/alexflint/go-filemutex v1.3.0 h1:LgE+nTUWnQCyRKbpoceKZsPQbs84LivvgwUymZXdOcM= 6 | github.com/alexflint/go-filemutex v1.3.0/go.mod h1:U0+VA/i30mGBlLCrFPGtTe9y6wGQfNAWPBTekHQ+c8A= 7 | github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= 8 | github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= 9 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= 10 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= 11 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 12 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 13 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 14 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 15 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 16 | github.com/go-errors/errors v1.5.0 h1:/EuijeGOu7ckFxzhkj4CXJ8JaenxK7bKUxpPYqeLHqQ= 17 | github.com/go-errors/errors v1.5.0/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= 18 | github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= 19 | github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= 20 | github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= 21 | github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= 22 | github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= 23 | github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= 24 | github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= 25 | github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= 26 | github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= 27 | github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= 28 | github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= 29 | github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= 30 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 31 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 32 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 33 | github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= 34 | github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 35 | github.com/gruntwork-io/terratest v0.48.1 h1:pnydDjkWbZCUYXvQkr24y21fBo8PfJC5hRGdwbl1eXM= 36 | github.com/gruntwork-io/terratest v0.48.1/go.mod h1:U2EQW4Odlz75XJUH16Kqkr9c93p+ZZtkpVez7GkZFa4= 37 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 38 | github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= 39 | github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 40 | github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= 41 | github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= 42 | github.com/hashicorp/go-getter/v2 v2.2.3 h1:6CVzhT0KJQHqd9b0pK3xSP0CM/Cv+bVhk+jcaRJ2pGk= 43 | github.com/hashicorp/go-getter/v2 v2.2.3/go.mod h1:hp5Yy0GMQvwWVUmwLs3ygivz1JSLI323hdIE9J9m7TY= 44 | github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= 45 | github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= 46 | github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= 47 | github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= 48 | github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= 49 | github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 50 | github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= 51 | github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= 52 | github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= 53 | github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= 54 | github.com/hashicorp/terraform-config-inspect v0.0.0-20241129133400-c404f8227ea6 h1:146llE+6P/9YO8RcHRehzGNiS9+OoirKW9/aML6/JIA= 55 | github.com/hashicorp/terraform-config-inspect v0.0.0-20241129133400-c404f8227ea6/go.mod h1:Gz/z9Hbn+4KSp8A2FBtNszfLSdT2Tn/uAKGuVqqWmDI= 56 | github.com/hashicorp/terraform-json v0.24.0 h1:rUiyF+x1kYawXeRth6fKFm/MdfBS6+lW4NbeATsYz8Q= 57 | github.com/hashicorp/terraform-json v0.24.0/go.mod h1:Nfj5ubo9xbu9uiAoZVBsNOjvNKB66Oyrvtit74kC7ow= 58 | github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= 59 | github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= 60 | github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= 61 | github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 62 | github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= 63 | github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 64 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 65 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 66 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 67 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 68 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 69 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 70 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 71 | github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= 72 | github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 73 | github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= 74 | github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= 75 | github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM= 76 | github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= 77 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 78 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 79 | github.com/mitchellh/go-testing-interface v1.14.2-0.20210821155943-2d9075ca8770 h1:drhDO54gdT/a15GBcMRmunZiNcLgPiFIJa23KzmcvcU= 80 | github.com/mitchellh/go-testing-interface v1.14.2-0.20210821155943-2d9075ca8770/go.mod h1:SO/iHr6q2EzbqRApt+8/E9wqebTwQn5y+UlB04bxzo0= 81 | github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= 82 | github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= 83 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 84 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= 85 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 86 | github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= 87 | github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= 88 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 89 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 90 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 91 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 92 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 93 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 94 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 95 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 96 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 97 | github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= 98 | github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= 99 | github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= 100 | github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= 101 | github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= 102 | github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 103 | github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= 104 | github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 105 | github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= 106 | github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= 107 | github.com/tmccombs/hcl2json v0.6.4 h1:/FWnzS9JCuyZ4MNwrG4vMrFrzRgsWEOVi+1AyYUVLGw= 108 | github.com/tmccombs/hcl2json v0.6.4/go.mod h1:+ppKlIW3H5nsAsZddXPy2iMyvld3SHxyjswOZhavRDk= 109 | github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= 110 | github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= 111 | github.com/zclconf/go-cty v1.15.1 h1:RgQYm4j2EvoBRXOPxhUvxPzRrGDo1eCOhHXuGfrj5S0= 112 | github.com/zclconf/go-cty v1.15.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= 113 | github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= 114 | github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= 115 | golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= 116 | golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= 117 | golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= 118 | golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 119 | golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= 120 | golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= 121 | golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= 122 | golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 123 | golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 124 | golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= 125 | golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 126 | golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= 127 | golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= 128 | golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= 129 | golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= 130 | golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= 131 | golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= 132 | google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= 133 | google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 134 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 135 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 136 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 137 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 138 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 139 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 140 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 141 | k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= 142 | k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= 143 | sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= 144 | sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= 145 | sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA= 146 | sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY= 147 | sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= 148 | sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= 149 | -------------------------------------------------------------------------------- /test/integration/list_folder_deny/controls/gcloud.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Roles amount are used to test how the module behaves on configuration updates. 16 | # Workaround InSpec lack of support for integer by parsing it from string. 17 | 18 | folder_id = attribute('folder_id') 19 | 20 | control 'list-folder-deny' do 21 | title 'Test list folder org policy is correct' 22 | 23 | describe command("gcloud beta resource-manager org-policies list --folder=#{folder_id} --format=json") do 24 | its(:exit_status) { should eq 0 } 25 | its(:stderr) { should eq '' } 26 | 27 | let(:data) do 28 | if subject.exit_status == 0 29 | JSON.parse(subject.stdout).select{|x| x['constraint'] == 'constraints/serviceuser.services'}[0] 30 | else 31 | {} 32 | end 33 | end 34 | 35 | describe "list folder org policy serviceuser.services" do 36 | it "should exist" do 37 | expect(data).to_not be_empty 38 | end 39 | 40 | it "deploymentmanager.googleapis.com should be denied" do 41 | expect(data['listPolicy']).to include( 42 | "deniedValues" => ["deploymentmanager.googleapis.com"] 43 | ) 44 | end 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /test/integration/list_folder_deny/inspec.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | name: list_folder_deny 17 | attributes: 18 | - name: folder_id 19 | required: true 20 | type: string 21 | -------------------------------------------------------------------------------- /test/integration/list_org_exclude/controls/gcloud.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Roles amount are used to test how the module behaves on configuration updates. 16 | # Workaround InSpec lack of support for integer by parsing it from string. 17 | 18 | project_id = attribute('project_id') 19 | org_id = attribute('org_id') 20 | 21 | control 'list-org-exclude' do 22 | title 'Test list exclude org policy is correct' 23 | 24 | describe command("gcloud beta resource-manager org-policies list --organization=#{org_id} --format=json") do 25 | its(:exit_status) { should eq 0 } 26 | its(:stderr) { should eq '' } 27 | 28 | let(:data) do 29 | if subject.exit_status == 0 30 | JSON.parse(subject.stdout).select{|x| x['constraint'] == 'constraints/compute.sharedReservationsOwnerProjects'}[0] 31 | else 32 | {} 33 | end 34 | end 35 | 36 | describe "list exclude org policy compute.sharedReservationsOwnerProjects" do 37 | it "should exist" do 38 | expect(data).to_not be_empty 39 | end 40 | 41 | it "#{project_id} should be allowed" do 42 | expect(data['listPolicy']).to include( 43 | "allowedValues" => ["projects/#{project_id}"] 44 | ) 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /test/integration/list_org_exclude/inspec.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | name: boolean_org_exclude 17 | attributes: 18 | - name: org_id 19 | required: true 20 | type: string 21 | - name: project_id 22 | required: true 23 | type: string 24 | -------------------------------------------------------------------------------- /test/integration/v2_boolean_org_enforce/v2_boolean_org_enforce_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package v2_boolean_org_enforce 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud" 21 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" 22 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/utils" 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | func TestVersion2BooleanOrgEnforce(t *testing.T) { 27 | 28 | orgPolicyv2T := tft.NewTFBlueprintTest(t) 29 | 30 | orgPolicyv2T.DefineVerify( 31 | func(assert *assert.Assertions) { 32 | constraintName := "constraints/" + orgPolicyv2T.GetStringOutput("constraint") 33 | policyRoot := "--" + orgPolicyv2T.GetStringOutput("policy_root") 34 | policyRootId := orgPolicyv2T.GetStringOutput("policy_root_id") 35 | 36 | gcOps := gcloud.WithCommonArgs([]string{policyRoot, policyRootId, "--format", "json"}) 37 | op := gcloud.Run(t, "beta resource-manager org-policies list", gcOps).Array() 38 | 39 | constraintImplemented := utils.GetFirstMatchResult(t, op, "constraint", constraintName).Get("constraint").String() 40 | assert.Equal(constraintImplemented, constraintName, "Org policy is created and exists") 41 | 42 | parameterizedConstraintName := "constraints/" + orgPolicyv2T.GetStringOutput("parameterized_constraint") 43 | parameterizedConstraintImplemented := utils.GetFirstMatchResult(t, op, "constraint", parameterizedConstraintName).Get("constraint").String() 44 | assert.Equal(parameterizedConstraintImplemented, parameterizedConstraintName, "Org policy is created and exists") 45 | }) 46 | orgPolicyv2T.Test() 47 | } 48 | -------------------------------------------------------------------------------- /test/setup/.gitignore: -------------------------------------------------------------------------------- 1 | terraform.tfvars 2 | source.sh 3 | -------------------------------------------------------------------------------- /test/setup/iam.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | locals { 18 | project_roles = [ 19 | "roles/owner" 20 | ] 21 | 22 | organization_roles = [ 23 | "roles/orgpolicy.policyAdmin" 24 | ] 25 | } 26 | 27 | resource "google_service_account" "int_test" { 28 | project = module.project.project_id 29 | account_id = "ci-account" 30 | display_name = "ci-account" 31 | } 32 | 33 | resource "google_project_iam_member" "int_test_project" { 34 | for_each = toset(local.project_roles) 35 | 36 | project = module.project.project_id 37 | role = each.value 38 | member = "serviceAccount:${google_service_account.int_test.email}" 39 | } 40 | 41 | resource "google_organization_iam_member" "int_test" { 42 | for_each = toset(local.organization_roles) 43 | 44 | org_id = var.org_id 45 | role = each.value 46 | member = "serviceAccount:${google_service_account.int_test.email}" 47 | } 48 | 49 | resource "google_service_account_key" "int_test" { 50 | service_account_id = google_service_account.int_test.id 51 | } 52 | -------------------------------------------------------------------------------- /test/setup/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "project" { 18 | source = "terraform-google-modules/project-factory/google" 19 | version = "~> 18.0" 20 | 21 | name = "ci-org-policy" 22 | random_project_id = true 23 | org_id = var.org_id 24 | folder_id = var.folder_id 25 | billing_account = var.billing_account 26 | 27 | activate_apis = [ 28 | "cloudresourcemanager.googleapis.com", 29 | "storage-api.googleapis.com", 30 | "serviceusage.googleapis.com", 31 | "orgpolicy.googleapis.com", 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /test/setup/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "org_id" { 18 | value = var.org_id 19 | } 20 | 21 | output "project_id" { 22 | value = module.project.project_id 23 | } 24 | 25 | output "folder_id" { 26 | value = var.folder_id 27 | } 28 | 29 | output "sa_key" { 30 | value = google_service_account_key.int_test.private_key 31 | sensitive = true 32 | } 33 | -------------------------------------------------------------------------------- /test/setup/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | variable "org_id" { 17 | description = "The numeric organization id" 18 | } 19 | 20 | variable "folder_id" { 21 | description = "The folder to deploy in" 22 | } 23 | 24 | variable "billing_account" { 25 | description = "The billing account id associated with the project, e.g. XXXXXX-YYYYYY-ZZZZZZ" 26 | } 27 | -------------------------------------------------------------------------------- /test/setup/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 0.13" 19 | required_providers { 20 | google = { 21 | source = "hashicorp/google" 22 | version = ">= 3.53.0, < 7" 23 | } 24 | google-beta = { 25 | source = "hashicorp/google-beta" 26 | version = ">= 3.53.0, < 7" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "policy_for" { 18 | description = "Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`." 19 | type = string 20 | } 21 | variable "organization_id" { 22 | description = "The organization id for putting the policy" 23 | type = string 24 | default = null 25 | } 26 | 27 | variable "folder_id" { 28 | description = "The folder id for putting the policy" 29 | type = string 30 | default = null 31 | } 32 | 33 | variable "project_id" { 34 | description = "The project id for putting the policy" 35 | type = string 36 | default = null 37 | } 38 | 39 | variable "enforce" { 40 | description = "If boolean constraint, whether the policy is enforced at the root; if list constraint, whether to deny all (true) or allow all" 41 | type = bool 42 | default = null 43 | } 44 | 45 | variable "allow" { 46 | description = "(Only for list constraints) List of values which should be allowed" 47 | type = list(string) 48 | default = [""] 49 | } 50 | 51 | variable "deny" { 52 | description = "(Only for list constraints) List of values which should be denied" 53 | type = list(string) 54 | default = [""] 55 | } 56 | 57 | variable "exclude_folders" { 58 | description = "Set of folders to exclude from the policy" 59 | type = set(string) 60 | default = [] 61 | } 62 | 63 | variable "exclude_projects" { 64 | description = "Set of projects to exclude from the policy" 65 | type = set(string) 66 | default = [] 67 | } 68 | 69 | variable "constraint" { 70 | description = "The constraint to be applied" 71 | type = string 72 | } 73 | 74 | variable "policy_type" { 75 | description = "The constraint type to work with (either 'boolean' or 'list')" 76 | type = string 77 | default = "list" 78 | } 79 | 80 | variable "allow_list_length" { 81 | description = "The number of elements in the allow list" 82 | type = number 83 | default = 0 84 | } 85 | 86 | variable "deny_list_length" { 87 | description = "The number of elements in the deny list" 88 | type = number 89 | default = 0 90 | } 91 | 92 | -------------------------------------------------------------------------------- /versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | 21 | google = { 22 | source = "hashicorp/google" 23 | version = ">= 3.53, < 7" 24 | } 25 | null = { 26 | source = "hashicorp/null" 27 | version = ">= 2.1" 28 | } 29 | } 30 | 31 | provider_meta "google" { 32 | module_name = "blueprints/terraform/terraform-google-org-policy/v7.0.0" 33 | } 34 | 35 | } 36 | --------------------------------------------------------------------------------