Migrate organizations tests

This commit is contained in:
Julio Castillo 2022-12-02 20:07:15 +01:00
parent 188ad23035
commit b4d3aa2055
40 changed files with 685 additions and 1153 deletions

View File

@ -160,8 +160,7 @@ def basedir():
return BASEDIR
def _generic_plan_summary(module_path, tf_var_files=None, basedir=None,
**tf_vars):
def _generic_plan_summary(module_path, basedir, tf_var_files=None, **tf_vars):
"""
Run a Terraform plan on the module located at `module_path`.
@ -169,8 +168,7 @@ def _generic_plan_summary(module_path, tf_var_files=None, basedir=None,
path or relative to the root of the repository
- basedir: directory root to use for relative paths in
tf_var_files. If None, then paths are relative to the calling
test function
tf_var_files.
- tf_var_files: set of terraform variable files (tfvars) to pass
in to terraform
@ -227,7 +225,7 @@ def _generic_plan_summary(module_path, tf_var_files=None, basedir=None,
binary = os.environ.get('TERRAFORM', 'terraform')
tf = tftest.TerraformTest(test_path, binary=binary)
tf.setup(upgrade=True)
tf_var_files = [basedir / x for x in tf_var_files or []]
tf_var_files = [(basedir / x).resolve() for x in tf_var_files or []]
plan = tf.plan(output=True, refresh=True, tf_var_file=tf_var_files,
tf_vars=tf_vars)
@ -258,16 +256,17 @@ def _generic_plan_summary(module_path, tf_var_files=None, basedir=None,
def generic_plan_summary(request):
'Return a function to generate a PlanSummary.'
def inner(module_path, tf_var_files=None, basedir=None, **tf_vars):
def inner(module_path, basedir=None, tf_var_files=None, **tf_vars):
if basedir is None:
basedir = Path(request.fspath).parent
return _generic_plan_summary(module_path, tf_var_files, basedir, **tf_vars)
return _generic_plan_summary(module_path=module_path, basedir=basedir,
tf_var_files=tf_var_files, **tf_vars)
return inner
def _generic_plan_validator(module_path, inventory_paths, tf_var_files=None,
basedir=None, **tf_vars):
def _generic_plan_validator(module_path, inventory_paths, basedir,
tf_var_files=None, **tf_vars):
summary = _generic_plan_summary(module_path=module_path,
tf_var_files=tf_var_files, basedir=basedir,
**tf_vars)
@ -335,12 +334,14 @@ def _generic_plan_validator(module_path, inventory_paths, tf_var_files=None,
def generic_plan_validator(request):
'Return a function that builds a PlanSummary and compares it to an yaml inventory.'
def inner(module_path, inventory_paths, tf_var_files=None, basedir=None,
def inner(module_path, inventory_paths, basedir=None, tf_var_files=None,
**tf_vars):
if basedir is None:
basedir = Path(request.fspath).parent
return _generic_plan_validator(module_path, inventory_paths, tf_var_files,
basedir, **tf_vars)
return _generic_plan_validator(module_path=module_path,
inventory_paths=inventory_paths,
basedir=basedir, tf_var_files=tf_var_paths,
**tf_vars)
return inner
@ -362,6 +363,9 @@ class FabricTestFile(pytest.File):
inventory=inventory, tfvars=tfvars)
from icecream import ic
class FabricTestItem(pytest.Item):
def __init__(self, name, parent, module, inventory, tfvars):
@ -371,8 +375,8 @@ class FabricTestItem(pytest.Item):
self.tfvars = tfvars
def runtest(self):
_generic_plan_validator(self.module, self.inventory, self.tfvars,
self.parent.path.parent)
s = _generic_plan_validator(self.module, self.inventory,
self.parent.path.parent, self.tfvars)
def reportinfo(self):
return self.path, None, self.name

View File

@ -1,705 +0,0 @@
# TODO: missing all local_file and gcs objects
values:
google_organization_iam_binding.org_admin_delegated:
condition:
- description: Automation service account delegated grants.
expression: api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/accesscontextmanager.policyAdmin','roles/compute.orgFirewallPolicyAdmin','roles/compute.xpnAdmin','roles/orgpolicy.policyAdmin','roles/billing.admin','roles/billing.costsManager','roles/billing.user'])
title: automation_sa_delegated_grants
members:
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: organizations/123456789012/roles/organizationIamAdmin
module.automation-project.data.google_bigquery_default_service_account.bq_sa[0]:
project: fast-prod-iac-core-0
module.automation-project.data.google_storage_project_service_account.gcs_sa[0]:
project: fast-prod-iac-core-0
user_project: null
module.automation-project.google_project.project[0]:
auto_create_network: false
billing_account: 000000-111111-222222
folder_id: null
labels: null
name: fast-prod-iac-core-0
org_id: '123456789012'
project_id: fast-prod-iac-core-0
skip_delete: false
module.automation-project.google_project_iam_binding.authoritative["roles/cloudbuild.builds.editor"]:
condition: []
members:
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
project: fast-prod-iac-core-0
role: roles/cloudbuild.builds.editor
module.automation-project.google_project_iam_binding.authoritative["roles/iam.serviceAccountAdmin"]:
condition: []
members:
- group:gcp-devops@fast.example.com
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
project: fast-prod-iac-core-0
role: roles/iam.serviceAccountAdmin
module.automation-project.google_project_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]:
condition: []
members:
- group:gcp-devops@fast.example.com
- group:gcp-organization-admins@fast.example.com
project: fast-prod-iac-core-0
role: roles/iam.serviceAccountTokenCreator
module.automation-project.google_project_iam_binding.authoritative["roles/iam.workloadIdentityPoolAdmin"]:
condition: []
members:
- group:gcp-organization-admins@fast.example.com
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
project: fast-prod-iac-core-0
role: roles/iam.workloadIdentityPoolAdmin
module.automation-project.google_project_iam_binding.authoritative["roles/owner"]:
condition: []
members:
- serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
project: fast-prod-iac-core-0
role: roles/owner
module.automation-project.google_project_iam_binding.authoritative["roles/source.admin"]:
condition: []
members:
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
project: fast-prod-iac-core-0
role: roles/source.admin
module.automation-project.google_project_iam_binding.authoritative["roles/storage.admin"]:
condition: []
members:
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
project: fast-prod-iac-core-0
role: roles/storage.admin
module.automation-project.google_project_iam_member.servicenetworking[0]:
condition: []
project: fast-prod-iac-core-0
role: roles/servicenetworking.serviceAgent
module.automation-project.google_project_service.project_services["accesscontextmanager.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: accesscontextmanager.googleapis.com
module.automation-project.google_project_service.project_services["bigquery.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: bigquery.googleapis.com
module.automation-project.google_project_service.project_services["bigqueryreservation.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: bigqueryreservation.googleapis.com
module.automation-project.google_project_service.project_services["bigquerystorage.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: bigquerystorage.googleapis.com
module.automation-project.google_project_service.project_services["billingbudgets.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: billingbudgets.googleapis.com
module.automation-project.google_project_service.project_services["cloudbilling.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: cloudbilling.googleapis.com
module.automation-project.google_project_service.project_services["cloudbuild.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: cloudbuild.googleapis.com
module.automation-project.google_project_service.project_services["cloudkms.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: cloudkms.googleapis.com
module.automation-project.google_project_service.project_services["cloudresourcemanager.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: cloudresourcemanager.googleapis.com
module.automation-project.google_project_service.project_services["compute.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: compute.googleapis.com
module.automation-project.google_project_service.project_services["container.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: container.googleapis.com
module.automation-project.google_project_service.project_services["essentialcontacts.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: essentialcontacts.googleapis.com
module.automation-project.google_project_service.project_services["iam.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: iam.googleapis.com
module.automation-project.google_project_service.project_services["iamcredentials.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: iamcredentials.googleapis.com
module.automation-project.google_project_service.project_services["orgpolicy.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: orgpolicy.googleapis.com
module.automation-project.google_project_service.project_services["pubsub.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: pubsub.googleapis.com
module.automation-project.google_project_service.project_services["servicenetworking.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: servicenetworking.googleapis.com
module.automation-project.google_project_service.project_services["serviceusage.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: serviceusage.googleapis.com
module.automation-project.google_project_service.project_services["sourcerepo.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: sourcerepo.googleapis.com
module.automation-project.google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: stackdriver.googleapis.com
module.automation-project.google_project_service.project_services["storage-component.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: storage-component.googleapis.com
module.automation-project.google_project_service.project_services["storage.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: storage.googleapis.com
module.automation-project.google_project_service.project_services["sts.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-iac-core-0
service: sts.googleapis.com
module.automation-project.google_project_service_identity.jit_si["pubsub.googleapis.com"]:
project: fast-prod-iac-core-0
service: pubsub.googleapis.com
module.automation-project.google_project_service_identity.servicenetworking[0]:
project: fast-prod-iac-core-0
service: servicenetworking.googleapis.com
module.automation-tf-bootstrap-gcs.google_storage_bucket.bucket:
cors: []
custom_placement_config: []
default_event_based_hold: null
encryption: []
force_destroy: false
labels: null
lifecycle_rule: []
location: EU
logging: []
name: fast-prod-iac-core-bootstrap-0
project: fast-prod-iac-core-0
requester_pays: null
retention_policy: []
storage_class: MULTI_REGIONAL
uniform_bucket_level_access: true
versioning:
- enabled: true
website: []
module.automation-tf-bootstrap-sa.google_service_account.service_account[0]:
account_id: fast-prod-bootstrap-0
description: null
disabled: false
display_name: Terraform organization bootstrap service account.
project: fast-prod-iac-core-0
module.automation-tf-bootstrap-sa.google_service_account_iam_binding.roles["roles/iam.serviceAccountTokenCreator"]:
condition: []
members: null
role: roles/iam.serviceAccountTokenCreator
module.automation-tf-bootstrap-sa.google_storage_bucket_iam_member.bucket-roles["fast-prod-iac-core-outputs-0-roles/storage.admin"]:
bucket: fast-prod-iac-core-outputs-0
condition: []
role: roles/storage.admin
module.automation-tf-cicd-gcs.google_storage_bucket.bucket:
cors: []
custom_placement_config: []
default_event_based_hold: null
encryption: []
force_destroy: false
labels: null
lifecycle_rule: []
location: EU
logging: []
name: fast-prod-iac-core-cicd-0
project: fast-prod-iac-core-0
requester_pays: null
retention_policy: []
storage_class: MULTI_REGIONAL
uniform_bucket_level_access: true
versioning:
- enabled: true
website: []
module.automation-tf-cicd-gcs.google_storage_bucket_iam_binding.bindings["roles/storage.objectAdmin"]:
bucket: fast-prod-iac-core-cicd-0
condition: []
members:
- serviceAccount:fast-prod-cicd-0@fast-prod-iac-core-0.iam.gserviceaccount.com
role: roles/storage.objectAdmin
module.automation-tf-cicd-provisioning-sa.google_service_account.service_account[0]:
account_id: fast-prod-cicd-0
description: null
disabled: false
display_name: Terraform stage 1 CICD service account.
project: fast-prod-iac-core-0
module.automation-tf-cicd-provisioning-sa.google_service_account_iam_binding.roles["roles/iam.serviceAccountTokenCreator"]:
condition: []
members: null
role: roles/iam.serviceAccountTokenCreator
module.automation-tf-cicd-provisioning-sa.google_storage_bucket_iam_member.bucket-roles["fast-prod-iac-core-outputs-0-roles/storage.admin"]:
bucket: fast-prod-iac-core-outputs-0
condition: []
role: roles/storage.admin
module.automation-tf-output-gcs.google_storage_bucket.bucket:
cors: []
custom_placement_config: []
default_event_based_hold: null
encryption: []
force_destroy: false
labels: null
lifecycle_rule: []
location: EU
logging: []
name: fast-prod-iac-core-outputs-0
project: fast-prod-iac-core-0
requester_pays: null
retention_policy: []
storage_class: MULTI_REGIONAL
uniform_bucket_level_access: true
versioning:
- enabled: true
website: []
module.automation-tf-resman-gcs.google_storage_bucket.bucket:
cors: []
custom_placement_config: []
default_event_based_hold: null
encryption: []
force_destroy: false
labels: null
lifecycle_rule: []
location: EU
logging: []
name: fast-prod-iac-core-resman-0
project: fast-prod-iac-core-0
requester_pays: null
retention_policy: []
storage_class: MULTI_REGIONAL
uniform_bucket_level_access: true
versioning:
- enabled: true
website: []
module.automation-tf-resman-gcs.google_storage_bucket_iam_binding.bindings["roles/storage.objectAdmin"]:
bucket: fast-prod-iac-core-resman-0
condition: []
members:
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
role: roles/storage.objectAdmin
module.automation-tf-resman-sa.google_service_account.service_account[0]:
account_id: fast-prod-resman-0
description: null
disabled: false
display_name: Terraform stage 1 resman service account.
project: fast-prod-iac-core-0
module.automation-tf-resman-sa.google_service_account_iam_binding.roles["roles/iam.serviceAccountTokenCreator"]:
condition: []
members: null
role: roles/iam.serviceAccountTokenCreator
module.automation-tf-resman-sa.google_storage_bucket_iam_member.bucket-roles["fast-prod-iac-core-outputs-0-roles/storage.admin"]:
bucket: fast-prod-iac-core-outputs-0
condition: []
role: roles/storage.admin
module.billing-export-dataset[0].google_bigquery_dataset.default:
dataset_id: billing_export
default_encryption_configuration: []
default_partition_expiration_ms: null
default_table_expiration_ms: null
delete_contents_on_destroy: false
description: Terraform managed.
friendly_name: Billing export.
labels: null
location: EU
project: fast-prod-billing-exp-0
module.billing-export-project[0].data.google_bigquery_default_service_account.bq_sa[0]:
project: fast-prod-billing-exp-0
module.billing-export-project[0].data.google_storage_project_service_account.gcs_sa[0]:
project: fast-prod-billing-exp-0
user_project: null
module.billing-export-project[0].google_project.project[0]:
auto_create_network: false
billing_account: 000000-111111-222222
folder_id: null
labels: null
name: fast-prod-billing-exp-0
org_id: '123456789012'
project_id: fast-prod-billing-exp-0
skip_delete: false
module.billing-export-project[0].google_project_iam_binding.authoritative["roles/owner"]:
condition: []
members:
- serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
project: fast-prod-billing-exp-0
role: roles/owner
module.billing-export-project[0].google_project_service.project_services["bigquery.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-billing-exp-0
service: bigquery.googleapis.com
module.billing-export-project[0].google_project_service.project_services["bigquerydatatransfer.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-billing-exp-0
service: bigquerydatatransfer.googleapis.com
module.billing-export-project[0].google_project_service.project_services["storage.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-billing-exp-0
service: storage.googleapis.com
module.log-export-dataset[0].google_bigquery_dataset.default:
dataset_id: audit_export
default_encryption_configuration: []
default_partition_expiration_ms: null
default_table_expiration_ms: null
delete_contents_on_destroy: false
description: Terraform managed.
friendly_name: Audit logs export.
labels: null
location: EU
project: fast-prod-audit-logs-0
module.log-export-project.data.google_bigquery_default_service_account.bq_sa[0]:
project: fast-prod-audit-logs-0
module.log-export-project.data.google_storage_project_service_account.gcs_sa[0]:
project: fast-prod-audit-logs-0
user_project: null
module.log-export-project.google_project.project[0]:
auto_create_network: false
billing_account: 000000-111111-222222
folder_id: null
labels: null
name: fast-prod-audit-logs-0
org_id: '123456789012'
project_id: fast-prod-audit-logs-0
skip_delete: false
module.log-export-project.google_project_iam_binding.authoritative["roles/owner"]:
condition: []
members:
- serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
project: fast-prod-audit-logs-0
role: roles/owner
module.log-export-project.google_project_service.project_services["bigquery.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-audit-logs-0
service: bigquery.googleapis.com
module.log-export-project.google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-audit-logs-0
service: stackdriver.googleapis.com
module.log-export-project.google_project_service.project_services["storage.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: fast-prod-audit-logs-0
service: storage.googleapis.com
module.organization.google_bigquery_dataset_iam_member.bq-sinks-binding["audit-logs"]:
condition: []
role: roles/bigquery.dataEditor
module.organization.google_bigquery_dataset_iam_member.bq-sinks-binding["vpc-sc"]:
condition: []
role: roles/bigquery.dataEditor
module.organization.google_logging_organization_sink.sink["audit-logs"]:
description: audit-logs (Terraform-managed).
disabled: false
exclusions: []
filter: logName:"/logs/cloudaudit.googleapis.com%2Factivity" OR logName:"/logs/cloudaudit.googleapis.com%2Fsystem_event"
include_children: true
name: audit-logs
org_id: '123456789012'
module.organization.google_logging_organization_sink.sink["vpc-sc"]:
description: vpc-sc (Terraform-managed).
disabled: false
exclusions: []
filter: protoPayload.metadata.@type="type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
include_children: true
name: vpc-sc
org_id: '123456789012'
module.organization.google_organization_iam_binding.authoritative["roles/browser"]:
condition: []
members:
- domain:fast.example.com
org_id: '123456789012'
role: roles/browser
module.organization.google_organization_iam_binding.authoritative["roles/cloudasset.owner"]:
condition: []
members:
- group:gcp-network-admins@fast.example.com
- group:gcp-organization-admins@fast.example.com
- group:gcp-security-admins@fast.example.com
org_id: '123456789012'
role: roles/cloudasset.owner
module.organization.google_organization_iam_binding.authoritative["roles/cloudsupport.admin"]:
condition: []
members:
- group:gcp-organization-admins@fast.example.com
org_id: '123456789012'
role: roles/cloudsupport.admin
module.organization.google_organization_iam_binding.authoritative["roles/cloudsupport.techSupportEditor"]:
condition: []
members:
- group:gcp-devops@fast.example.com
- group:gcp-network-admins@fast.example.com
- group:gcp-security-admins@fast.example.com
org_id: '123456789012'
role: roles/cloudsupport.techSupportEditor
module.organization.google_organization_iam_binding.authoritative["roles/compute.osAdminLogin"]:
condition: []
members:
- group:gcp-organization-admins@fast.example.com
org_id: '123456789012'
role: roles/compute.osAdminLogin
module.organization.google_organization_iam_binding.authoritative["roles/compute.osLoginExternalUser"]:
condition: []
members:
- group:gcp-organization-admins@fast.example.com
org_id: '123456789012'
role: roles/compute.osLoginExternalUser
module.organization.google_organization_iam_binding.authoritative["roles/iam.securityReviewer"]:
condition: []
members:
- group:gcp-security-admins@fast.example.com
org_id: '123456789012'
role: roles/iam.securityReviewer
module.organization.google_organization_iam_binding.authoritative["roles/logging.admin"]:
condition: []
members:
- group:gcp-security-admins@fast.example.com
- serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/logging.admin
module.organization.google_organization_iam_binding.authoritative["roles/logging.viewer"]:
condition: []
members:
- group:gcp-devops@fast.example.com
org_id: '123456789012'
role: roles/logging.viewer
module.organization.google_organization_iam_binding.authoritative["roles/monitoring.viewer"]:
condition: []
members:
- group:gcp-devops@fast.example.com
org_id: '123456789012'
role: roles/monitoring.viewer
module.organization.google_organization_iam_binding.authoritative["roles/owner"]:
condition: []
members:
- group:gcp-organization-admins@fast.example.com
org_id: '123456789012'
role: roles/owner
module.organization.google_organization_iam_binding.authoritative["roles/resourcemanager.folderAdmin"]:
condition: []
members:
- group:gcp-organization-admins@fast.example.com
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/resourcemanager.folderAdmin
module.organization.google_organization_iam_binding.authoritative["roles/resourcemanager.organizationAdmin"]:
condition: []
members:
- group:gcp-organization-admins@fast.example.com
- serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/resourcemanager.organizationAdmin
module.organization.google_organization_iam_binding.authoritative["roles/resourcemanager.projectCreator"]:
condition: []
members:
- group:gcp-organization-admins@fast.example.com
- serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/resourcemanager.projectCreator
module.organization.google_organization_iam_binding.authoritative["roles/resourcemanager.projectMover"]:
condition: []
members:
- serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/resourcemanager.projectMover
module.organization.google_organization_iam_binding.authoritative["roles/resourcemanager.tagAdmin"]:
condition: []
members:
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/resourcemanager.tagAdmin
module.organization.google_organization_iam_binding.authoritative["roles/resourcemanager.tagUser"]:
condition: []
members:
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/resourcemanager.tagUser
module.organization.google_organization_iam_binding.authoritative["roles/securitycenter.admin"]:
condition: []
members:
- group:gcp-security-admins@fast.example.com
org_id: '123456789012'
role: roles/securitycenter.admin
module.organization.google_organization_iam_custom_role.roles["organizationIamAdmin"]:
description: Terraform-managed.
org_id: '123456789012'
permissions:
- resourcemanager.organizations.get
- resourcemanager.organizations.getIamPolicy
- resourcemanager.organizations.setIamPolicy
role_id: organizationIamAdmin
stage: GA
title: Custom role organizationIamAdmin
module.organization.google_organization_iam_custom_role.roles["serviceProjectNetworkAdmin"]:
description: Terraform-managed.
org_id: '123456789012'
permissions:
- compute.globalOperations.get
- compute.networks.get
- compute.networks.updatePeering
- compute.organizations.disableXpnResource
- compute.organizations.enableXpnResource
- compute.projects.get
- compute.subnetworks.getIamPolicy
- compute.subnetworks.setIamPolicy
- dns.networks.bindPrivateDNSZone
- resourcemanager.projects.get
role_id: serviceProjectNetworkAdmin
stage: GA
title: Custom role serviceProjectNetworkAdmin
module.organization.google_organization_iam_member.additive["roles/accesscontextmanager.policyAdmin-group:gcp-security-admins@fast.example.com"]:
condition: []
member: group:gcp-security-admins@fast.example.com
org_id: '123456789012'
role: roles/accesscontextmanager.policyAdmin
module.organization.google_organization_iam_member.additive["roles/billing.admin-group:gcp-billing-admins@fast.example.com"]:
condition: []
member: group:gcp-billing-admins@fast.example.com
org_id: '123456789012'
role: roles/billing.admin
module.organization.google_organization_iam_member.additive["roles/billing.admin-group:gcp-organization-admins@fast.example.com"]:
condition: []
member: group:gcp-organization-admins@fast.example.com
org_id: '123456789012'
role: roles/billing.admin
module.organization.google_organization_iam_member.additive["roles/billing.admin-serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com"]:
condition: []
member: serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/billing.admin
module.organization.google_organization_iam_member.additive["roles/billing.admin-serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com"]:
condition: []
member: serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/billing.admin
module.organization.google_organization_iam_member.additive["roles/billing.costsManager-group:gcp-billing-admins@fast.example.com"]:
condition: []
member: group:gcp-billing-admins@fast.example.com
org_id: '123456789012'
role: roles/billing.costsManager
module.organization.google_organization_iam_member.additive["roles/billing.costsManager-group:gcp-organization-admins@fast.example.com"]:
condition: []
member: group:gcp-organization-admins@fast.example.com
org_id: '123456789012'
role: roles/billing.costsManager
module.organization.google_organization_iam_member.additive["roles/billing.costsManager-serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com"]:
condition: []
member: serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/billing.costsManager
module.organization.google_organization_iam_member.additive["roles/billing.costsManager-serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com"]:
condition: []
member: serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/billing.costsManager
module.organization.google_organization_iam_member.additive["roles/compute.orgFirewallPolicyAdmin-group:gcp-network-admins@fast.example.com"]:
condition: []
member: group:gcp-network-admins@fast.example.com
org_id: '123456789012'
role: roles/compute.orgFirewallPolicyAdmin
module.organization.google_organization_iam_member.additive["roles/compute.xpnAdmin-group:gcp-network-admins@fast.example.com"]:
condition: []
member: group:gcp-network-admins@fast.example.com
org_id: '123456789012'
role: roles/compute.xpnAdmin
module.organization.google_organization_iam_member.additive["roles/iam.organizationRoleAdmin-group:gcp-security-admins@fast.example.com"]:
condition: []
member: group:gcp-security-admins@fast.example.com
org_id: '123456789012'
role: roles/iam.organizationRoleAdmin
module.organization.google_organization_iam_member.additive["roles/iam.organizationRoleAdmin-serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com"]:
condition: []
member: serviceAccount:fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/iam.organizationRoleAdmin
module.organization.google_organization_iam_member.additive["roles/orgpolicy.policyAdmin-group:gcp-organization-admins@fast.example.com"]:
condition: []
member: group:gcp-organization-admins@fast.example.com
org_id: '123456789012'
role: roles/orgpolicy.policyAdmin
module.organization.google_organization_iam_member.additive["roles/orgpolicy.policyAdmin-group:gcp-security-admins@fast.example.com"]:
condition: []
member: group:gcp-security-admins@fast.example.com
org_id: '123456789012'
role: roles/orgpolicy.policyAdmin
module.organization.google_organization_iam_member.additive["roles/orgpolicy.policyAdmin-serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com"]:
condition: []
member: serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
org_id: '123456789012'
role: roles/orgpolicy.policyAdmin
counts:
google_bigquery_dataset: 2
google_bigquery_dataset_iam_member: 2
google_bigquery_default_service_account: 3
google_logging_organization_sink: 2
google_organization_iam_binding: 19
google_organization_iam_custom_role: 2
google_organization_iam_member: 16
google_project: 3
google_project_iam_binding: 9
google_project_iam_member: 1
google_project_service: 29
google_project_service_identity: 2
google_service_account: 3
google_service_account_iam_binding: 3
google_storage_bucket: 4
google_storage_bucket_iam_binding: 2
google_storage_bucket_iam_member: 3
google_storage_bucket_object: 5
google_storage_project_service_account: 3
local_file: 5
outputs:
automation: __missing__
billing_dataset: __missing__
cicd_repositories: {}
custom_roles:
organization_iam_admin: organizations/123456789012/roles/organizationIamAdmin
service_project_network_admin: organizations/123456789012/roles/serviceProjectNetworkAdmin
federated_identity:
pool: null
providers: {}
outputs_bucket: fast-prod-iac-core-outputs-0
project_ids:
automation: fast-prod-iac-core-0
billing-export: fast-prod-billing-exp-0
log-export: fast-prod-audit-logs-0
service_accounts:
bootstrap: fast-prod-bootstrap-0@fast-prod-iac-core-0.iam.gserviceaccount.com
cicd: fast-prod-cicd-0@fast-prod-iac-core-0.iam.gserviceaccount.com
resman: fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
tfvars: __missing__

View File

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

View File

@ -20,11 +20,11 @@ import pytest
import yaml
@pytest.fixture(scope='session')
def tfvars_to_yaml():
@pytest.fixture()
def tfvars_to_yaml(request):
def converter(source, dest, from_var, to_var=None):
p_fixture = pathlib.Path(inspect.stack()[1].filename).parent / 'fixture'
p_fixture = pathlib.Path(request.path).parent
p_source = p_fixture / source
if not p_source.exists():
raise ValueError(f"tfvars '{source}' not found")

View File

@ -31,13 +31,14 @@ def test_policy_list(plan_runner):
def test_factory_policy_boolean(plan_runner, tfvars_to_yaml, tmp_path):
dest = tmp_path / 'policies.yaml'
tfvars_to_yaml('test.orgpolicies-boolean.tfvars', dest, 'org_policies')
tfvars_to_yaml('fixture/test.orgpolicies-boolean.tfvars', dest,
'org_policies')
_, resources = plan_runner(org_policies_data_path=f'"{tmp_path}"')
validate_policy_boolean(resources)
def test_factory_policy_list(plan_runner, tfvars_to_yaml, tmp_path):
dest = tmp_path / 'policies.yaml'
tfvars_to_yaml('test.orgpolicies-list.tfvars', dest, 'org_policies')
tfvars_to_yaml('fixture/test.orgpolicies-list.tfvars', dest, 'org_policies')
_, resources = plan_runner(org_policies_data_path=f'"{tmp_path}"')
validate_policy_list(resources)

View File

@ -40,7 +40,8 @@ def test_vpc_routes(generic_plan_summary, next_hop_type, next_hop):
next_hop = "global/gateways/default-internet-gateway"
}
}''' % (next_hop_type, next_hop)
summary = generic_plan_summary('modules/net-vpc', ['common.tfvars'],
summary = generic_plan_summary('modules/net-vpc',
tf_var_files=['common.tfvars'],
routes=var_routes)
assert len(summary.values) == 3
route = summary.values[f'google_compute_route.{next_hop_type}["next-hop"]']

View File

@ -0,0 +1,6 @@
iam_audit_config = {
allServices = {
DATA_READ = [],
DATA_WRITE = ["user:me@example.org"]
}
}

View File

@ -0,0 +1,2 @@
counts:
google_organization_iam_audit_config: 1

View File

@ -0,0 +1 @@
organization_id = "organizations/1234567890"

View File

@ -0,0 +1,45 @@
firewall_policies = {
policy1 = {
allow-ingress = {
description = ""
direction = "INGRESS"
action = "allow"
priority = 100
ranges = ["10.0.0.0/8"]
ports = {
tcp = ["22"]
}
target_service_accounts = null
target_resources = null
logging = false
}
deny-egress = {
description = ""
direction = "EGRESS"
action = "deny"
priority = 200
ranges = ["192.168.0.0/24"]
ports = {
tcp = ["443"]
}
target_service_accounts = null
target_resources = null
logging = false
}
}
policy2 = {
allow-ingress = {
description = ""
direction = "INGRESS"
action = "allow"
priority = 100
ranges = ["10.0.0.0/8"]
ports = {
tcp = ["22"]
}
target_service_accounts = null
target_resources = null
logging = false
}
}
}

View File

@ -0,0 +1,59 @@
values:
google_compute_firewall_policy.policy["policy1"]:
parent: organizations/1234567890
short_name: policy1
google_compute_firewall_policy.policy["policy2"]:
parent: organizations/1234567890
short_name: policy2
google_compute_firewall_policy_rule.rule["policy1-allow-ingress"]:
action: allow
direction: INGRESS
disabled: null
enable_logging: false
match:
- dest_ip_ranges: null
layer4_configs:
- ip_protocol: tcp
ports:
- '22'
src_ip_ranges:
- 10.0.0.0/8
priority: 100
target_resources: null
target_service_accounts: null
google_compute_firewall_policy_rule.rule["policy1-deny-egress"]:
action: deny
direction: EGRESS
disabled: null
enable_logging: false
match:
- dest_ip_ranges:
- 192.168.0.0/24
layer4_configs:
- ip_protocol: tcp
ports:
- '443'
src_ip_ranges: null
priority: 200
target_resources: null
target_service_accounts: null
google_compute_firewall_policy_rule.rule["policy2-allow-ingress"]:
action: allow
direction: INGRESS
disabled: null
enable_logging: false
match:
- dest_ip_ranges: null
layer4_configs:
- ip_protocol: tcp
ports:
- '22'
src_ip_ranges:
- 10.0.0.0/8
priority: 100
target_resources: null
target_service_accounts: null
counts:
google_compute_firewall_policy: 2
google_compute_firewall_policy_rule: 3

View File

@ -0,0 +1,5 @@
firewall_policy_factory = {
cidr_file = "../../tests/modules/organization/data/firewall-cidrs.yaml"
policy_name = "factory-1"
rules_file = "../../tests/modules/organization/data/firewall-rules.yaml"
}

View File

@ -0,0 +1,47 @@
values:
google_compute_firewall_policy.policy["factory-1"]:
description: null
parent: organizations/1234567890
short_name: factory-1
timeouts: null
google_compute_firewall_policy_rule.rule["factory-1-allow-admins"]:
action: allow
description: Access from the admin subnet to all subnets
direction: INGRESS
disabled: null
enable_logging: null
match:
- dest_ip_ranges: null
layer4_configs:
- ip_protocol: all
ports: []
src_ip_ranges:
- 10.0.0.0/8
- 172.168.0.0/12
- 192.168.0.0/16
priority: 1000
target_resources: null
target_service_accounts: null
timeouts: null
google_compute_firewall_policy_rule.rule["factory-1-allow-ssh-from-iap"]:
action: allow
description: Enable SSH from IAP
direction: INGRESS
disabled: null
enable_logging: null
match:
- dest_ip_ranges: null
layer4_configs:
- ip_protocol: tcp
ports:
- '22'
src_ip_ranges:
- 35.235.240.0/20
priority: 1002
target_resources: null
target_service_accounts: null
timeouts: null
counts:
google_compute_firewall_policy: 1
google_compute_firewall_policy_rule: 2

View File

@ -0,0 +1,13 @@
values:
google_compute_firewall_policy.policy["factory-1"]: {}
google_compute_firewall_policy.policy["policy1"]: {}
google_compute_firewall_policy.policy["policy2"]: {}
google_compute_firewall_policy_rule.rule["factory-1-allow-admins"]: {}
google_compute_firewall_policy_rule.rule["factory-1-allow-ssh-from-iap"]: {}
google_compute_firewall_policy_rule.rule["policy1-allow-ingress"]: {}
google_compute_firewall_policy_rule.rule["policy1-deny-egress"]: {}
google_compute_firewall_policy_rule.rule["policy2-allow-ingress"]: {}
counts:
google_compute_firewall_policy: 3
google_compute_firewall_policy_rule: 5

View File

@ -0,0 +1,18 @@
group_iam = {
"owners@example.org" = [
"roles/owner",
"roles/resourcemanager.folderAdmin"
],
"viewers@example.org" = [
"roles/viewer"
]
}
iam = {
"roles/owner" = [
"user:one@example.org",
"user:two@example.org"
],
"roles/browser" = [
"domain:example.org"
]
}

View File

@ -0,0 +1,30 @@
values:
google_organization_iam_binding.authoritative["roles/browser"]:
condition: []
members:
- domain:example.org
org_id: '1234567890'
role: roles/browser
google_organization_iam_binding.authoritative["roles/owner"]:
condition: []
members:
- group:owners@example.org
- user:one@example.org
- user:two@example.org
org_id: '1234567890'
role: roles/owner
google_organization_iam_binding.authoritative["roles/resourcemanager.folderAdmin"]:
condition: []
members:
- group:owners@example.org
org_id: '1234567890'
role: roles/resourcemanager.folderAdmin
google_organization_iam_binding.authoritative["roles/viewer"]:
condition: []
members:
- group:viewers@example.org
org_id: '1234567890'
role: roles/viewer
counts:
google_organization_iam_binding: 4

View File

@ -0,0 +1,4 @@
iam = {
"user:one@example.org" = ["roles/owner"],
"user:two@example.org" = ["roles/owner", "roles/editor"]
}

View File

@ -0,0 +1,17 @@
values:
google_organization_iam_binding.authoritative["user:one@example.org"]:
condition: []
members:
- roles/owner
org_id: '1234567890'
role: user:one@example.org
google_organization_iam_binding.authoritative["user:two@example.org"]:
condition: []
members:
- roles/editor
- roles/owner
org_id: '1234567890'
role: user:two@example.org
counts:
google_organization_iam_binding: 2

View File

@ -0,0 +1,29 @@
logging_sinks = {
warning = {
destination = "mybucket"
type = "storage"
filter = "severity=WARNING"
}
info = {
destination = "projects/myproject/datasets/mydataset"
type = "bigquery"
filter = "severity=INFO"
disabled = true
}
notice = {
destination = "projects/myproject/topics/mytopic"
type = "pubsub"
filter = "severity=NOTICE"
include_children = false
}
debug = {
destination = "projects/myproject/locations/global/buckets/mybucket"
type = "logging"
filter = "severity=DEBUG"
include_children = false
exclusions = {
no-compute = "logName:compute"
no-container = "logName:container"
}
}
}

View File

@ -0,0 +1,72 @@
values:
google_bigquery_dataset_iam_member.bq-sinks-binding["info"]:
condition: []
dataset_id: mydataset
project: myproject
role: roles/bigquery.dataEditor
google_logging_organization_sink.sink["debug"]:
description: debug (Terraform-managed).
destination: logging.googleapis.com/projects/myproject/locations/global/buckets/mybucket
disabled: false
exclusions:
- description: null
disabled: false
filter: logName:compute
name: no-compute
- description: null
disabled: false
filter: logName:container
name: no-container
filter: severity=DEBUG
include_children: false
name: debug
org_id: '1234567890'
google_logging_organization_sink.sink["info"]:
description: info (Terraform-managed).
destination: bigquery.googleapis.com/projects/myproject/datasets/mydataset
disabled: true
exclusions: []
filter: severity=INFO
include_children: true
name: info
org_id: '1234567890'
google_logging_organization_sink.sink["notice"]:
description: notice (Terraform-managed).
destination: pubsub.googleapis.com/projects/myproject/topics/mytopic
disabled: false
exclusions: []
filter: severity=NOTICE
include_children: false
name: notice
org_id: '1234567890'
google_logging_organization_sink.sink["warning"]:
description: warning (Terraform-managed).
destination: storage.googleapis.com/mybucket
disabled: false
exclusions: []
filter: severity=WARNING
include_children: true
name: warning
org_id: '1234567890'
google_project_iam_member.bucket-sinks-binding["debug"]:
condition:
- expression: resource.name.endsWith('projects/myproject/locations/global/buckets/mybucket')
title: debug bucket writer
project: myproject
role: roles/logging.bucketWriter
google_pubsub_topic_iam_member.pubsub-sinks-binding["notice"]:
condition: []
project: myproject
role: roles/pubsub.publisher
topic: mytopic
google_storage_bucket_iam_member.storage-sinks-binding["warning"]:
bucket: mybucket
condition: []
role: roles/storage.objectCreator
counts:
google_bigquery_dataset_iam_member: 1
google_logging_organization_sink: 4
google_project_iam_member: 1
google_pubsub_topic_iam_member: 1
google_storage_bucket_iam_member: 1

View File

@ -0,0 +1,4 @@
logging_exclusions = {
exclusion1 = "resource.type=gce_instance"
exclusion2 = "severity=NOTICE"
}

View File

@ -0,0 +1,16 @@
values:
google_logging_organization_exclusion.logging-exclusion["exclusion1"]:
description: exclusion1 (Terraform-managed).
disabled: null
filter: resource.type=gce_instance
name: exclusion1
org_id: '1234567890'
google_logging_organization_exclusion.logging-exclusion["exclusion2"]:
description: exclusion2 (Terraform-managed).
disabled: null
filter: severity=NOTICE
name: exclusion2
org_id: '1234567890'
counts:
google_logging_organization_exclusion: 2

View File

@ -0,0 +1,39 @@
values:
google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]:
name: organizations/1234567890/policies/iam.disableServiceAccountKeyCreation
parent: organizations/1234567890
spec:
- inherit_from_parent: null
reset: null
rules:
- allow_all: null
condition: []
deny_all: null
enforce: 'TRUE'
values: []
timeouts: null
google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]:
name: organizations/1234567890/policies/iam.disableServiceAccountKeyUpload
parent: organizations/1234567890
spec:
- inherit_from_parent: null
reset: null
rules:
- allow_all: null
condition: []
deny_all: null
enforce: 'FALSE'
values: []
- allow_all: null
condition:
- description: test condition
expression: resource.matchTagId(aa, bb)
location: xxx
title: condition
deny_all: null
enforce: 'TRUE'
values: []
timeouts: null
counts:
google_org_policy_policy: 2

View File

@ -0,0 +1,23 @@
values:
google_org_policy_custom_constraint.constraint["custom.dataprocNoMoreThan10Workers"]:
action_type: DENY
condition: resource.config.workerConfig.numInstances + resource.config.secondaryWorkerConfig.numInstances > 10
method_types:
- CREATE
- UPDATE
name: custom.dataprocNoMoreThan10Workers
parent: organizations/1234567890
resource_types:
- dataproc.googleapis.com/Cluster
google_org_policy_custom_constraint.constraint["custom.gkeEnableAutoUpgrade"]:
action_type: ALLOW
condition: resource.management.autoUpgrade == true
method_types:
- CREATE
name: custom.gkeEnableAutoUpgrade
parent: organizations/1234567890
resource_types:
- container.googleapis.com/NodePool
counts:
google_org_policy_custom_constraint: 2

View File

@ -3,6 +3,7 @@ org_policies = {
deny = { all = true }
}
"iam.allowedPolicyMemberDomains" = {
inherit_from_parent = true
allow = {
values = ["C0xxxxxxx", "C0yyyyyyy"]
}

View File

@ -0,0 +1,71 @@
values:
google_org_policy_policy.default["compute.restrictLoadBalancerCreationForTypes"]:
name: organizations/1234567890/policies/compute.restrictLoadBalancerCreationForTypes
parent: organizations/1234567890
spec:
- inherit_from_parent: null
reset: null
rules:
- allow_all: null
condition: []
deny_all: null
enforce: null
values:
- allowed_values: null
denied_values:
- in:EXTERNAL
- allow_all: null
condition:
- description: test condition
expression: resource.matchTagId(aa, bb)
location: xxx
title: condition
deny_all: null
enforce: null
values:
- allowed_values:
- EXTERNAL_1
denied_values: null
- allow_all: 'TRUE'
condition:
- description: test condition2
expression: resource.matchTagId(cc, dd)
location: xxx
title: condition2
deny_all: null
enforce: null
values: []
timeouts: null
google_org_policy_policy.default["compute.vmExternalIpAccess"]:
name: organizations/1234567890/policies/compute.vmExternalIpAccess
parent: organizations/1234567890
spec:
- inherit_from_parent: null
reset: null
rules:
- allow_all: null
condition: []
deny_all: 'TRUE'
enforce: null
values: []
timeouts: null
google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]:
name: organizations/1234567890/policies/iam.allowedPolicyMemberDomains
parent: organizations/1234567890
spec:
- inherit_from_parent: true
reset: null
rules:
- allow_all: null
condition: []
deny_all: null
enforce: null
values:
- allowed_values:
- C0xxxxxxx
- C0yyyyyyy
denied_values: null
timeouts: null
counts:
google_org_policy_policy: 3

View File

@ -0,0 +1,62 @@
values:
google_tags_tag_key.default["bar"]:
description: Managed by the Terraform organization module.
parent: organizations/1234567890
purpose: null
purpose_data: null
short_name: bar
google_tags_tag_key.default["foo"]:
description: Managed by the Terraform organization module.
parent: organizations/1234567890
purpose: null
purpose_data: null
short_name: foo
google_tags_tag_key.default["foobar"]:
description: Foobar tag.
parent: organizations/1234567890
purpose: null
purpose_data: null
short_name: foobar
google_tags_tag_key.default["net_environment"]:
description: Managed by the Terraform organization module.
parent: organizations/1234567890
purpose: GCE_FIREWALL
purpose_data:
network: foobar
short_name: net_environment
google_tags_tag_key_iam_binding.default["foobar:roles/resourcemanager.tagAdmin"]:
condition: []
members:
- user:user1@example.com
- user:user2@example.com
role: roles/resourcemanager.tagAdmin
google_tags_tag_value.default["foobar/one"]:
description: Managed by the Terraform organization module.
short_name: one
google_tags_tag_value.default["foobar/three"]:
description: Foobar 3.
short_name: three
google_tags_tag_value.default["foobar/two"]:
description: Foobar 2.
short_name: two
google_tags_tag_value_iam_binding.default["foobar/three:roles/resourcemanager.tagAdmin"]:
condition: []
members:
- user:user4@example.com
role: roles/resourcemanager.tagAdmin
google_tags_tag_value_iam_binding.default["foobar/three:roles/resourcemanager.tagViewer"]:
condition: []
members:
- user:user3@example.com
role: roles/resourcemanager.tagViewer
google_tags_tag_value_iam_binding.default["foobar/two:roles/resourcemanager.tagViewer"]:
condition: []
members:
- user:user3@example.com
role: roles/resourcemanager.tagViewer
counts:
google_tags_tag_key: 4
google_tags_tag_key_iam_binding: 1
google_tags_tag_value: 3
google_tags_tag_value_iam_binding: 3

View File

@ -1,62 +0,0 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def test_audit_config(plan_runner):
"Test audit config."
iam_audit_config = '{allServices={DATA_READ=[], DATA_WRITE=["user:me@example.org"]}}'
_, resources = plan_runner(iam_audit_config=iam_audit_config)
assert len(resources) == 1
log_types = set(
r['log_type'] for r in resources[0]['values']['audit_log_config'])
assert log_types == set(['DATA_READ', 'DATA_WRITE'])
def test_iam(plan_runner):
"Test IAM."
group_iam = (
'{'
'"owners@example.org" = ["roles/owner", "roles/resourcemanager.folderAdmin"],'
'"viewers@example.org" = ["roles/viewer"]'
'}')
iam = ('{'
'"roles/owner" = ["user:one@example.org", "user:two@example.org"],'
'"roles/browser" = ["domain:example.org"]'
'}')
_, resources = plan_runner(group_iam=group_iam, iam=iam)
roles = sorted([(r['values']['role'], sorted(r['values']['members']))
for r in resources
if r['type'] == 'google_organization_iam_binding'])
assert roles == [
('roles/browser', ['domain:example.org']),
('roles/owner', [
'group:owners@example.org', 'user:one@example.org',
'user:two@example.org'
]),
('roles/resourcemanager.folderAdmin', ['group:owners@example.org']),
('roles/viewer', ['group:viewers@example.org']),
]
def test_iam_additive_members(plan_runner):
"Test IAM additive members."
iam = ('{"user:one@example.org" = ["roles/owner"],'
'"user:two@example.org" = ["roles/owner", "roles/editor"]}')
_, resources = plan_runner(iam_additive_members=iam)
roles = set((r['values']['role'], r['values']['member'])
for r in resources
if r['type'] == 'google_organization_iam_member')
assert roles == set([('roles/owner', 'user:one@example.org'),
('roles/owner', 'user:two@example.org'),
('roles/editor', 'user:two@example.org')])

View File

@ -1,130 +0,0 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
_FACTORY = '''
{
cidr_file = "data/firewall-cidrs.yaml"
policy_name = "factory-1"
rules_file = "data/firewall-rules.yaml"
}
'''
_POLICIES = '''
{
policy1 = {
allow-ingress = {
description = ""
direction = "INGRESS"
action = "allow"
priority = 100
ranges = ["10.0.0.0/8"]
ports = {
tcp = ["22"]
}
target_service_accounts = null
target_resources = null
logging = false
}
deny-egress = {
description = ""
direction = "EGRESS"
action = "deny"
priority = 200
ranges = ["192.168.0.0/24"]
ports = {
tcp = ["443"]
}
target_service_accounts = null
target_resources = null
logging = false
}
}
policy2 = {
allow-ingress = {
description = ""
direction = "INGRESS"
action = "allow"
priority = 100
ranges = ["10.0.0.0/8"]
ports = {
tcp = ["22"]
}
target_service_accounts = null
target_resources = null
logging = false
}
}
}
'''
def test_custom(plan_runner):
'Test custom firewall policies.'
_, resources = plan_runner(firewall_policies=_POLICIES)
assert len(resources) == 5
policies = [r for r in resources
if r['type'] == 'google_compute_firewall_policy']
rules = [r for r in resources
if r['type'] == 'google_compute_firewall_policy_rule']
assert set(r['index'] for r in policies) == set([
'policy1', 'policy2'
])
assert set(r['index'] for r in rules) == set([
'policy1-deny-egress', 'policy2-allow-ingress', 'policy1-allow-ingress'
])
def test_factory(plan_runner):
'Test firewall policy factory.'
_, resources = plan_runner(firewall_policy_factory=_FACTORY)
assert len(resources) == 3
policies = [r for r in resources
if r['type'] == 'google_compute_firewall_policy']
rules = [r for r in resources
if r['type'] == 'google_compute_firewall_policy_rule']
assert set(r['index'] for r in policies) == set([
'factory-1'
])
assert set(r['index'] for r in rules) == set([
'factory-1-allow-admins', 'factory-1-allow-ssh-from-iap'
])
def test_factory_name(plan_runner):
'Test firewall policy factory default name.'
factory = _FACTORY.replace('"factory-1"', 'null')
_, resources = plan_runner(firewall_policy_factory=factory)
assert len(resources) == 3
policies = [r for r in resources
if r['type'] == 'google_compute_firewall_policy']
assert set(r['index'] for r in policies) == set([
'factory'
])
def test_combined(plan_runner):
'Test combined rules.'
_, resources = plan_runner(firewall_policies=_POLICIES,
firewall_policy_factory=_FACTORY)
assert len(resources) == 8
policies = [r for r in resources
if r['type'] == 'google_compute_firewall_policy']
rules = [r for r in resources
if r['type'] == 'google_compute_firewall_policy_rule']
assert set(r['index'] for r in policies) == set([
'factory-1', 'policy1', 'policy2'
])
assert set(r['index'] for r in rules) == set([
'factory-1-allow-admins', 'factory-1-allow-ssh-from-iap',
'policy1-deny-egress', 'policy2-allow-ingress', 'policy1-allow-ingress'
])

View File

@ -1,126 +0,0 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from collections import Counter
def test_sinks(plan_runner):
"Test folder-level sinks."
tfvars = 'test.logging-sinks.tfvars'
_, resources = plan_runner(tf_var_file=tfvars)
assert len(resources) == 8
resource_types = Counter([r["type"] for r in resources])
assert resource_types == {
"google_logging_organization_sink": 4,
"google_bigquery_dataset_iam_member": 1,
"google_project_iam_member": 1,
"google_pubsub_topic_iam_member": 1,
"google_storage_bucket_iam_member": 1,
}
sinks = [
r for r in resources if r["type"] == "google_logging_organization_sink"
]
assert sorted([r["index"] for r in sinks]) == [
"debug",
"info",
"notice",
"warning",
]
values = [(
r["index"],
r["values"]["filter"],
r["values"]["destination"],
r["values"]["include_children"],
) for r in sinks]
assert sorted(values) == [
(
"debug",
"severity=DEBUG",
"logging.googleapis.com/projects/myproject/locations/global/buckets/mybucket",
False,
),
(
"info",
"severity=INFO",
"bigquery.googleapis.com/projects/myproject/datasets/mydataset",
True,
),
(
"notice",
"severity=NOTICE",
"pubsub.googleapis.com/projects/myproject/topics/mytopic",
False,
),
("warning", "severity=WARNING", "storage.googleapis.com/mybucket", True),
]
bindings = [r for r in resources if "member" in r["type"]]
values = [(r["index"], r["type"], r["values"]["role"]) for r in bindings]
assert sorted(values) == [
("debug", "google_project_iam_member", "roles/logging.bucketWriter"),
("info", "google_bigquery_dataset_iam_member",
"roles/bigquery.dataEditor"),
("notice", "google_pubsub_topic_iam_member", "roles/pubsub.publisher"),
("warning", "google_storage_bucket_iam_member",
"roles/storage.objectCreator"),
]
exclusions = [(r["index"], r["values"]["exclusions"]) for r in sinks]
assert sorted(exclusions) == [
(
"debug",
[
{
"description": None,
"disabled": False,
"filter": "logName:compute",
"name": "no-compute",
},
{
"description": None,
"disabled": False,
"filter": "logName:container",
"name": "no-container",
},
],
),
("info", []),
("notice", []),
("warning", []),
]
def test_exclusions(plan_runner):
"Test folder-level logging exclusions."
logging_exclusions = ("{"
'exclusion1 = "resource.type=gce_instance", '
'exclusion2 = "severity=NOTICE", '
"}")
_, resources = plan_runner(logging_exclusions=logging_exclusions)
assert len(resources) == 2
exclusions = [
r for r in resources
if r["type"] == "google_logging_organization_exclusion"
]
assert sorted([r["index"] for r in exclusions]) == [
"exclusion1",
"exclusion2",
]
values = [(r["index"], r["values"]["filter"]) for r in exclusions]
assert sorted(values) == [
("exclusion1", "resource.type=gce_instance"),
("exclusion2", "severity=NOTICE"),
]

View File

@ -1,4 +1,4 @@
# Copyright 2022 Google LLC
# 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -14,46 +14,34 @@
import pathlib
from .validate_policies import validate_policy_boolean, validate_policy_list, validate_policy_custom_constraints
import pytest
_params = ['boolean', 'list']
def test_policy_boolean(plan_runner):
"Test boolean org policy."
tfvars = 'test.orgpolicies-boolean.tfvars'
_, resources = plan_runner(tf_var_file=tfvars)
validate_policy_boolean(resources)
def test_policy_list(plan_runner):
"Test list org policy."
tfvars = 'test.orgpolicies-list.tfvars'
_, resources = plan_runner(tf_var_file=tfvars)
validate_policy_list(resources)
def test_policy_custom_constraints(plan_runner):
"Test org policy custom constraints."
tfvars = 'test.orgpolicy-custom-constraints.tfvars'
_, resources = plan_runner(tf_var_file=tfvars)
validate_policy_custom_constraints(resources)
def test_factory_policy_boolean(plan_runner, tfvars_to_yaml, tmp_path):
@pytest.mark.parametrize('policy_type', _params)
def test_policy_factory(generic_plan_summary, tfvars_to_yaml, tmp_path,
policy_type):
dest = tmp_path / 'policies.yaml'
tfvars_to_yaml('test.orgpolicies-boolean.tfvars', dest, 'org_policies')
_, resources = plan_runner(org_policies_data_path=f'"{tmp_path}"')
validate_policy_boolean(resources)
tfvars_to_yaml(f'org_policies_{policy_type}.tfvars', dest, 'org_policies')
tfvars_plan = generic_plan_summary(
'modules/organization',
tf_var_files=['common.tfvars', f'org_policies_{policy_type}.tfvars'])
yaml_plan = generic_plan_summary('modules/organization',
tf_var_files=['common.tfvars'],
org_policies_data_path=f'{tmp_path}')
assert tfvars_plan.values == yaml_plan.values
def test_factory_policy_list(plan_runner, tfvars_to_yaml, tmp_path):
dest = tmp_path / 'policies.yaml'
tfvars_to_yaml('test.orgpolicies-list.tfvars', dest, 'org_policies')
_, resources = plan_runner(org_policies_data_path=f'"{tmp_path}"')
validate_policy_list(resources)
def test_factory_policy_custom_constraints(plan_runner, tfvars_to_yaml, tmp_path):
def test_custom_constraint_factory(generic_plan_summary, tfvars_to_yaml,
tmp_path):
dest = tmp_path / 'constraints.yaml'
tfvars_to_yaml('test.orgpolicy-custom-constraints.tfvars', dest, 'org_policy_custom_constraints')
_, resources = plan_runner(org_policy_custom_constraints_data_path=f'"{tmp_path}"')
validate_policy_custom_constraints(resources)
tfvars_to_yaml(f'org_policies_custom_constraints.tfvars', dest,
'org_policy_custom_constraints')
tfvars_plan = generic_plan_summary(
'modules/organization',
tf_var_files=['common.tfvars', f'org_policies_custom_constraints.tfvars'])
yaml_plan = generic_plan_summary(
'modules/organization', tf_var_files=['common.tfvars'],
org_policy_custom_constraints_data_path=f'{tmp_path}')
assert tfvars_plan.values == yaml_plan.values

View File

@ -1,52 +0,0 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def test_resource_tags(plan_runner):
'Test resource tags.'
_, resources = plan_runner(tf_var_file='test.resource_tags.tfvars')
assert len(resources) == 10
resource_values = {}
for r in resources:
resource_values.setdefault(r['type'], []).append(r['values'])
assert len(resource_values['google_tags_tag_key']) == 3
assert len(resource_values['google_tags_tag_value']) == 3
result = [
r['role'] for r in resource_values['google_tags_tag_value_iam_binding']
]
expected = [
'roles/resourcemanager.tagAdmin',
'roles/resourcemanager.tagViewer',
'roles/resourcemanager.tagViewer'
]
assert result == expected
def test_network_tags(plan_runner):
'Test network tags.'
_, resources = plan_runner(tf_var_file='test.network_tags.tfvars')
assert len(resources) == 1
resource_values = {}
for r in resources:
resource_values.setdefault(r['type'], []).append(r['values'])
google_tags_tag_key = resource_values['google_tags_tag_key'][0]
assert google_tags_tag_key['purpose'] == "GCE_FIREWALL"
assert google_tags_tag_key['purpose_data']['network'] == "foobar"
def test_bindings(plan_runner):
'Test tag bindings.'
tag_bindings = '{foo = "tagValues/123456789012"}'
_, resources = plan_runner(tag_bindings=tag_bindings)
assert len(resources) == 1

View File

@ -0,0 +1,66 @@
module: modules/organization
tests:
audit_config:
tfvars:
- common.tfvars
- audit_config.tfvars
iam:
tfvars:
- common.tfvars
- iam.tfvars
iam_additive:
tfvars:
- common.tfvars
- iam_additive.tfvars
logging:
tfvars:
- common.tfvars
- logging.tfvars
logging_exclusions:
tfvars:
- common.tfvars
- logging_exclusions.tfvars
org_policies_list:
tfvars:
- common.tfvars
- org_policies_list.tfvars
org_policies_boolean:
tfvars:
- common.tfvars
- org_policies_boolean.tfvars
org_policies_custom_constraints:
tfvars:
- common.tfvars
- org_policies_custom_constraints.tfvars
tags:
tfvars:
- common.tfvars
- network_tags.tfvars
- resource_tags.tfvars
inventory:
- tags.yaml
firewall_policies:
tfvars:
- common.tfvars
- firewall_policies.tfvars
firewall_policies_factory:
tfvars:
- common.tfvars
- firewall_policies_factory.tfvars
firewall_policies_factory_combined:
tfvars:
- common.tfvars
- firewall_policies.tfvars
- firewall_policies_factory.tfvars

View File

@ -31,13 +31,14 @@ def test_policy_list(plan_runner):
def test_factory_policy_boolean(plan_runner, tfvars_to_yaml, tmp_path):
dest = tmp_path / 'policies.yaml'
tfvars_to_yaml('test.orgpolicies-boolean.tfvars', dest, 'org_policies')
tfvars_to_yaml('fixture/test.orgpolicies-boolean.tfvars', dest,
'org_policies')
_, resources = plan_runner(org_policies_data_path=f'"{tmp_path}"')
validate_policy_boolean(resources)
def test_factory_policy_list(plan_runner, tfvars_to_yaml, tmp_path):
dest = tmp_path / 'policies.yaml'
tfvars_to_yaml('test.orgpolicies-list.tfvars', dest, 'org_policies')
tfvars_to_yaml('fixture/test.orgpolicies-list.tfvars', dest, 'org_policies')
_, resources = plan_runner(org_policies_data_path=f'"{tmp_path}"')
validate_policy_list(resources)