From 31904e603b93069865e7b31ca4c37fee27b4a1bf Mon Sep 17 00:00:00 2001 From: Tikster123 Date: Tue, 16 Dec 2025 21:07:53 +1100 Subject: [PATCH 1/9] feat: Migrate GKE Backup policies to new modular helper system - Migrated 52 policy files from monolithic to modular helpers - Added new modular helper system in policies/_helpers/ - Created comprehensive test inputs for all policies - Fixed OPA evaluation errors with duplicate function definitions - Implemented all 6 resource types with proper validations --- docs/gcp/_helpers/helpers.md | 856 ++++++++++++++++++ .../description/.terraform.lock.hcl | 21 + .../backup_channel/description/c.tf | 7 + .../backup_channel/description/config.tf | 15 + .../backup_channel/description/nc.tf | 7 + .../backup_channel/description/plan.json | Bin 0 -> 17920 bytes .../destination_project/.terraform.lock.hcl | 21 + .../backup_channel/destination_project/c.tf | 6 + .../destination_project/config.tf | 15 + .../backup_channel/destination_project/nc.tf | 6 + .../destination_project/plan.json | Bin 0 -> 17394 bytes .../backup_channel/labels/.terraform.lock.hcl | 21 + .../backup_for_gke/backup_channel/labels/c.tf | 13 + .../backup_channel/labels/config.tf | 15 + .../backup_channel/labels/nc.tf | 7 + .../backup_channel/labels/plan.json | Bin 0 -> 20978 bytes .../location/.terraform.lock.hcl | 21 + .../backup_channel/location/c.tf | 6 + .../backup_channel/location/config.tf | 15 + .../backup_channel/location/nc.tf | 6 + .../backup_channel/location/plan.json | Bin 0 -> 17334 bytes .../backup_channel/name/.terraform.lock.hcl | 21 + .../backup_for_gke/backup_channel/name/c.tf | 6 + .../backup_channel/name/config.tf | 16 + .../backup_for_gke/backup_channel/name/nc.tf | 6 + .../backup_channel/name/plan.json | Bin 0 -> 17196 bytes .../all_namespaces/.terraform.lock.hcl | 21 + .../backup_plan/all_namespaces/c.tf | 16 + .../backup_plan/all_namespaces/config.tf | 14 + .../backup_plan/all_namespaces/nc.tf | 12 + .../backup_plan/all_namespaces/plan.json | Bin 0 -> 13814 bytes .../backup_config/.terraform.lock.hcl | 21 + .../backup_plan/backup_config/c.tf | 20 + .../backup_plan/backup_config/config.tf | 14 + .../backup_plan/backup_config/nc.tf | 13 + .../backup_plan/backup_config/plan.json | Bin 0 -> 14690 bytes .../.terraform.lock.hcl | 21 + .../backup_plan/backup_delete_lock_days/c.tf | 19 + .../backup_delete_lock_days/config.tf | 14 + .../backup_plan/backup_delete_lock_days/nc.tf | 14 + .../backup_delete_lock_days/plan.json | Bin 0 -> 14182 bytes .../backup_schedule/.terraform.lock.hcl | 21 + .../backup_plan/backup_schedule/c.tf | 11 + .../backup_plan/backup_schedule/config.tf | 14 + .../backup_plan/backup_schedule/nc.tf | 11 + .../backup_plan/backup_schedule/plan.json | Bin 0 -> 11018 bytes .../deactivated/.terraform.lock.hcl | 21 + .../backup_plan/deactivated/c.tf | 7 + .../backup_plan/deactivated/config.tf | 14 + .../backup_plan/deactivated/nc.tf | 7 + .../backup_plan/deactivated/plan.json | Bin 0 -> 10120 bytes .../description/.terraform.lock.hcl | 21 + .../backup_plan/description/c.tf | 7 + .../backup_plan/description/config.tf | 14 + .../backup_plan/description/nc.tf | 7 + .../backup_plan/description/plan.json | Bin 0 -> 10790 bytes .../encryption_key/.terraform.lock.hcl | 21 + .../backup_plan/encryption_key/c.tf | 17 + .../backup_plan/encryption_key/config.tf | 14 + .../backup_plan/encryption_key/nc.tf | 13 + .../backup_plan/encryption_key/plan.json | Bin 0 -> 14654 bytes .../include_secrets/.terraform.lock.hcl | 21 + .../backup_plan/include_secrets/c.tf | 14 + .../backup_plan/include_secrets/config.tf | 14 + .../backup_plan/include_secrets/nc.tf | 0 .../backup_plan/include_secrets/plan.json | Bin 0 -> 7546 bytes .../backup_plan/labels/.terraform.lock.hcl | 21 + .../backup_for_gke/backup_plan/labels/c.tf | 14 + .../backup_plan/labels/config.tf | 14 + .../backup_for_gke/backup_plan/labels/nc.tf | 7 + .../backup_plan/labels/plan.json | Bin 0 -> 11928 bytes .../backup_plan/name/.terraform.lock.hcl | 21 + .../gcp/backup_for_gke/backup_plan/name/c.tf | 6 + .../backup_for_gke/backup_plan/name/config.tf | 14 + .../gcp/backup_for_gke/backup_plan/name/nc.tf | 6 + .../backup_for_gke/backup_plan/name/plan.json | Bin 0 -> 9796 bytes .../permissive_mode/.terraform.lock.hcl | 21 + .../backup_plan/permissive_mode/c.tf | 0 .../backup_plan/permissive_mode/config.tf | 14 + .../backup_plan/permissive_mode/nc.tf | 0 .../backup_plan/permissive_mode/plan.json | Bin 0 -> 878 bytes .../retention_policy/.terraform.lock.hcl | 21 + .../backup_plan/retention_policy/c.tf | 12 + .../backup_plan/retention_policy/config.tf | 14 + .../backup_plan/retention_policy/nc.tf | 12 + .../backup_plan/retention_policy/plan.json | Bin 0 -> 11138 bytes .../custom_roles/.terraform.lock.hcl | 21 + .../backup_plan_iam/custom_roles/c.tf | 11 + .../backup_plan_iam/custom_roles/config.tf | 14 + .../backup_plan_iam/custom_roles/nc.tf | 11 + .../backup_plan_iam/custom_roles/plan.json | Bin 0 -> 8420 bytes .../domain_access/.terraform.lock.hcl | 21 + .../backup_plan_iam/domain_access/c.tf | 12 + .../backup_plan_iam/domain_access/config.tf | 14 + .../backup_plan_iam/domain_access/nc.tf | 11 + .../backup_plan_iam/domain_access/plan.json | Bin 0 -> 8180 bytes .../.terraform.lock.hcl | 21 + .../external_service_accounts/c.tf | 12 + .../external_service_accounts/config.tf | 14 + .../external_service_accounts/nc.tf | 12 + .../external_service_accounts/plan.json | Bin 0 -> 9422 bytes .../backup_plan_iam/federated_identities/c.tf | 0 .../federated_identities/config.tf | 0 .../federated_identities/nc.tf | 0 .../federated_identities/plan.json | Bin 0 -> 424 bytes .../members/.terraform.lock.hcl | 21 + .../backup_plan_iam/members/c.tf | 8 + .../backup_plan_iam/members/config.tf | 14 + .../backup_plan_iam/members/nc.tf | 8 + .../backup_plan_iam/members/plan.json | Bin 0 -> 7874 bytes .../project_roles/.terraform.lock.hcl | 21 + .../backup_plan_iam/project_roles/c.tf | 12 + .../backup_plan_iam/project_roles/config.tf | 14 + .../backup_plan_iam/project_roles/nc.tf | 12 + .../backup_plan_iam/project_roles/plan.json | Bin 0 -> 8816 bytes .../backup_plan_iam/role/.terraform.lock.hcl | 21 + .../backup_for_gke/backup_plan_iam/role/c.tf | 12 + .../backup_plan_iam/role/config.tf | 14 + .../backup_for_gke/backup_plan_iam/role/nc.tf | 11 + .../backup_plan_iam/role/plan.json | Bin 0 -> 8186 bytes .../description/.terraform.lock.hcl | 21 + .../restore_channel/description/c.tf | 7 + .../restore_channel/description/config.tf | 14 + .../restore_channel/description/nc.tf | 7 + .../restore_channel/description/plan.json | Bin 0 -> 8928 bytes .../destination_project/.terraform.lock.hcl | 21 + .../restore_channel/destination_project/c.tf | 7 + .../destination_project/config.tf | 0 .../restore_channel/destination_project/nc.tf | 6 + .../destination_project/plan.json | 0 .../labels/.terraform.lock.hcl | 21 + .../restore_channel/labels/c.tf | 14 + .../restore_channel/labels/config.tf | 14 + .../restore_channel/labels/nc.tf | 7 + .../restore_channel/labels/plan.json | Bin 0 -> 10246 bytes .../location/.terraform.lock.hcl | 21 + .../restore_channel/location/c.tf | 6 + .../restore_channel/location/config.tf | 14 + .../restore_channel/location/nc.tf | 6 + .../restore_channel/location/plan.json | Bin 0 -> 8078 bytes .../restore_channel/name/.terraform.lock.hcl | 21 + .../backup_for_gke/restore_channel/name/c.tf | 7 + .../restore_channel/name/config.tf | 14 + .../backup_for_gke/restore_channel/name/nc.tf | 6 + .../restore_channel/name/plan.json | Bin 0 -> 8424 bytes .../all_namespaces/.terraform.lock.hcl | 21 + .../restore_plan/all_namespaces/c.tf | 23 + .../restore_plan/all_namespaces/config.tf | 14 + .../restore_plan/all_namespaces/nc.tf | 12 + .../restore_plan/all_namespaces/plan.json | Bin 0 -> 17512 bytes .../restore_plan/cluster/.terraform.lock.hcl | 21 + .../backup_for_gke/restore_plan/cluster/c.tf | 0 .../restore_plan/cluster/config.tf | 14 + .../backup_for_gke/restore_plan/cluster/nc.tf | 11 + .../restore_plan/cluster/plan.json | Bin 0 -> 8286 bytes .../.terraform.lock.hcl | 21 + .../restore_plan/cluster_resource_scope/c.tf | 0 .../cluster_resource_scope/config.tf | 14 + .../restore_plan/cluster_resource_scope/nc.tf | 17 + .../cluster_resource_scope/plan.json | Bin 0 -> 9526 bytes .../conflict_plan/.terraform.lock.hcl | 21 + .../restore_plan/conflict_plan/c.tf | 15 + .../restore_plan/conflict_plan/config.tf | 14 + .../restore_plan/conflict_plan/nc.tf | 15 + .../restore_plan/conflict_plan/plan.json | Bin 0 -> 16802 bytes .../excluded_namespaces/.terraform.lock.hcl | 21 + .../restore_plan/excluded_namespaces/c.tf | 0 .../excluded_namespaces/config.tf | 14 + .../restore_plan/excluded_namespaces/nc.tf | 0 .../excluded_namespaces/plan.json | Bin 0 -> 878 bytes .../field_actions/.terraform.lock.hcl | 21 + .../restore_plan/field_actions/c.tf | 38 + .../restore_plan/field_actions/config.tf | 14 + .../restore_plan/field_actions/nc.tf | 0 .../restore_plan/field_actions/plan.json | Bin 0 -> 12746 bytes .../.terraform.lock.hcl | 21 + .../namespaced_resource_restore_mode/c.tf | 15 + .../config.tf | 14 + .../namespaced_resource_restore_mode/nc.tf | 15 + .../plan.json | Bin 0 -> 16802 bytes .../transformation_rules/.terraform.lock.hcl | 21 + .../restore_plan/transformation_rules/c.tf | 30 + .../transformation_rules/config.tf | 14 + .../restore_plan/transformation_rules/nc.tf | 15 + .../transformation_rules/plan.json | Bin 0 -> 19132 bytes .../volume_bindings/.terraform.lock.hcl | 21 + .../restore_plan/volume_bindings/c.tf | 18 + .../restore_plan/volume_bindings/config.tf | 14 + .../restore_plan/volume_bindings/nc.tf | 18 + .../restore_plan/volume_bindings/plan.json | Bin 0 -> 17614 bytes .../volume_data_restore/.terraform.lock.hcl | 21 + .../restore_plan/volume_data_restore/c.tf | 15 + .../volume_data_restore/config.tf | 14 + .../restore_plan/volume_data_restore/nc.tf | 15 + .../volume_data_restore/plan.json | Bin 0 -> 16922 bytes .../cross_project_groups/.terraform.lock.hcl | 21 + .../cross_project_groups/c.tf | 0 .../cross_project_groups/config.tf | 14 + .../cross_project_groups/nc.tf | 12 + .../cross_project_groups/plan.json | Bin 0 -> 4834 bytes .../domain_access/.terraform.lock.hcl | 21 + .../restore_plan_iam/domain_access/c.tf | 0 .../restore_plan_iam/domain_access/config.tf | 14 + .../restore_plan_iam/domain_access/nc.tf | 0 .../restore_plan_iam/domain_access/plan.json | Bin 0 -> 878 bytes .../restore_plan_iam/member_count/c.tf | 0 .../restore_plan_iam/member_count/config.tf | 0 .../restore_plan_iam/member_count/nc.tf | 11 + .../restore_plan_iam/member_count/plan.json | Bin 0 -> 424 bytes .../personal_emails/.terraform.lock.hcl | 21 + .../restore_plan_iam/personal_emails/c.tf | 12 + .../personal_emails/config.tf | 14 + .../restore_plan_iam/personal_emails/nc.tf | 13 + .../personal_emails/plan.json | Bin 0 -> 8648 bytes .../project_roles/.terraform.lock.hcl | 21 + .../restore_plan_iam/project_roles/c.tf | 11 + .../restore_plan_iam/project_roles/config.tf | 14 + .../restore_plan_iam/project_roles/nc.tf | 0 .../restore_plan_iam/project_roles/plan.json | Bin 0 -> 4792 bytes .../public_access/.terraform.lock.hcl | 21 + .../restore_plan_iam/public_access/c.tf | 12 + .../restore_plan_iam/public_access/config.tf | 14 + .../restore_plan_iam/public_access/nc.tf | 0 .../restore_plan_iam/public_access/plan.json | Bin 0 -> 5050 bytes .../restore_permissions/.terraform.lock.hcl | 21 + .../restore_plan_iam/restore_permissions/c.tf | 11 + .../restore_permissions/config.tf | 14 + .../restore_permissions/nc.tf | 11 + .../restore_permissions/plan.json | Bin 0 -> 8276 bytes .../restore_plan_iam/role/.terraform.lock.hcl | 21 + .../backup_for_gke/restore_plan_iam/role/c.tf | 12 + .../restore_plan_iam/role/config.tf | 14 + .../restore_plan_iam/role/nc.tf | 11 + .../restore_plan_iam/role/plan.json | Bin 0 -> 8486 bytes .../service_accounts/.terraform.lock.hcl | 21 + .../restore_plan_iam/service_accounts/c.tf | 12 + .../service_accounts/config.tf | 14 + .../restore_plan_iam/service_accounts/nc.tf | 12 + .../service_accounts/plan.json | Bin 0 -> 9530 bytes policies/_helpers/README.md | 665 ++++++++++++++ policies/_helpers/helpers.rego | 249 +++++ policies/_helpers/policies/blacklist.rego | 81 ++ .../_helpers/policies/element_blacklist.rego | 109 +++ .../_helpers/policies/pattern_blacklist.rego | 91 ++ .../_helpers/policies/pattern_whitelist.rego | 92 ++ policies/_helpers/policies/range.rego | 88 ++ policies/_helpers/policies/whitelist.rego | 72 ++ policies/_helpers/shared.rego | 165 ++++ .../backup_channel/description/policy.rego | 17 + .../destination_project/policy.rego | 17 + .../backup_channel/labels/policy.rego | 17 + .../backup_channel/location/policy.rego | 17 + .../backup_channel/name/policy.rego | 17 + .../backup_for_gke/backup_channel/vars.rego | 8 + .../backup_plan/all_namespaces/policy.rego | 17 + .../backup_plan/backup_config/policy.rego | 17 + .../backup_delete_lock_days/policy.rego | 17 + .../backup_plan/backup_schedule/policy.rego | 17 + .../backup_plan/deactivated/policy.rego | 17 + .../backup_plan/description/policy.rego | 17 + .../backup_plan/encryption_key/policy.rego | 17 + .../backup_plan/include_secrets/policy.rego | 17 + .../backup_plan/labels/policy.rego | 17 + .../backup_plan/name/policy.rego | 17 + .../backup_plan/permissive_mode/policy.rego | 17 + .../backup_plan/retention_policy/policy.rego | 17 + .../gcp/backup_for_gke/backup_plan/vars.rego | 8 + .../backup_plan_iam/custom_roles/policy.rego | 17 + .../backup_plan_iam/domain_access/policy.rego | 17 + .../external_service_accounts/policy.rego | 17 + .../federated_identities/policy.rego | 17 + .../backup_plan_iam/members/policy.rego | 17 + .../backup_plan_iam/project_roles/policy.rego | 17 + .../backup_plan_iam/role/policy.rego | 17 + .../backup_for_gke/backup_plan_iam/vars.rego | 8 + .../restore_channel/description/policy.rego | 17 + .../destination_project/policy.rego | 17 + .../restore_channel/labels/policy.rego | 17 + .../restore_channel/location/policy.rego | 17 + .../restore_channel/name/policy.rego | 17 + .../backup_for_gke/restore_channel/vars.rego | 8 + .../restore_plan/all_namespaces/policy.rego | 17 + .../restore_plan/cluster/policy.rego | 17 + .../cluster_resource_scope/policy.rego | 17 + .../restore_plan/conflict_policy/policy.rego | 17 + .../restore_plan/descripttion/policy.rego | 17 + .../excluded_namespaces/policy.rego | 17 + .../restore_plan/field_actions/policy.rego | 17 + .../transformation_rules/policy.rego | 17 + .../gcp/backup_for_gke/restore_plan/vars.rego | 8 + .../restore_plan/volume_bindings/policy.rego | 17 + .../volume_data_restore/policy.rego | 17 + .../domain_access/policy.rego | 17 + .../restore_plan_iam/member_count/policy.rego | 17 + .../personal_emails/policy.rego | 17 + .../project_roles/policy.rego | 17 + .../public_access/policy.rego | 17 + .../restore_permissions/policy.rego | 17 + .../restore_plan_iam/role/policy.rego | 17 + .../service_accounts/policy.rego | 17 + .../backup_for_gke/restore_plan_iam/vars.rego | 8 + templates/gcp/c.tf | 6 + templates/gcp/config.tf | 11 + templates/gcp/nc.tf | 6 + templates/gcp/policy.rego | 121 +++ templates/gcp/vars.rego | 8 + tests/_helpers/README.md | 175 ++++ tests/_helpers/blacklist_test.rego | 315 +++++++ tests/_helpers/check_ux.sh | 82 ++ tests/_helpers/element_blacklist_test.rego | 412 +++++++++ .../fixtures/gcp_access_level/plan.json | 507 +++++++++++ tests/_helpers/fixtures/gcp_project/plan.json | 606 +++++++++++++ .../fixtures/gcp_storage_bucket/plan.json | 368 ++++++++ tests/_helpers/pattern_blacklist_test.rego | 430 +++++++++ tests/_helpers/pattern_whitelist_test.rego | 428 +++++++++ tests/_helpers/policy_debug.sh | 136 +++ tests/_helpers/range_test.rego | 234 +++++ tests/_helpers/shared_test.rego | 326 +++++++ tests/_helpers/smoke_test_helpers.sh | 122 +++ tests/_helpers/unit_test_helpers.sh | 103 +++ tests/_helpers/whitelist_test.rego | 345 +++++++ 321 files changed, 10590 insertions(+) create mode 100644 docs/gcp/_helpers/helpers.md create mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_channel/destination_project/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_channel/destination_project/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/destination_project/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/destination_project/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/destination_project/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_channel/labels/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_channel/labels/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/labels/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/labels/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/labels/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_channel/location/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_channel/location/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/location/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/location/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/location/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_channel/name/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_channel/name/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/name/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/name/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_channel/name/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/all_namespaces/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/all_namespaces/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/all_namespaces/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/all_namespaces/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/all_namespaces/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_config/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_config/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_config/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_config/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_schedule/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_schedule/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_schedule/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_schedule/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/backup_schedule/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/deactivated/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/deactivated/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/deactivated/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/deactivated/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/encryption_key/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/encryption_key/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/encryption_key/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/include_secrets/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/include_secrets/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/include_secrets/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/include_secrets/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/include_secrets/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/labels/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/labels/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/labels/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/labels/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/labels/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/name/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/name/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/name/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/name/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/name/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/permissive_mode/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/permissive_mode/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/permissive_mode/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/permissive_mode/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/permissive_mode/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/retention_policy/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/retention_policy/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/retention_policy/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/retention_policy/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/retention_policy/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/members/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/members/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/members/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/members/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/members/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/plan.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/role/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/role/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/role/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/role/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/role/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_channel/destination_project/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_channel/destination_project/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/destination_project/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/destination_project/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/destination_project/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_channel/labels/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_channel/labels/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/labels/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/labels/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/labels/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_channel/location/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_channel/location/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/location/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/location/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/location/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_channel/name/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_channel/name/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/name/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/name/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_channel/name/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/all_namespaces/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/all_namespaces/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/all_namespaces/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/all_namespaces/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/all_namespaces/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/conflict_plan/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/conflict_plan/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/conflict_plan/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/conflict_plan/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/conflict_plan/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/field_actions/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/field_actions/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/field_actions/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/field_actions/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/transformation_rules/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/transformation_rules/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/transformation_rules/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/transformation_rules/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/transformation_rules/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_bindings/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_bindings/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_bindings/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_bindings/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_bindings/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/member_count/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/member_count/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/member_count/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/member_count/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/project_roles/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/project_roles/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/project_roles/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/project_roles/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/project_roles/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/public_access/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/public_access/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/public_access/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/public_access/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/public_access/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/role/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/role/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/role/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/role/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/role/plan.json create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/service_accounts/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/service_accounts/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/service_accounts/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/service_accounts/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/service_accounts/plan.json create mode 100644 policies/_helpers/README.md create mode 100644 policies/_helpers/helpers.rego create mode 100644 policies/_helpers/policies/blacklist.rego create mode 100644 policies/_helpers/policies/element_blacklist.rego create mode 100644 policies/_helpers/policies/pattern_blacklist.rego create mode 100644 policies/_helpers/policies/pattern_whitelist.rego create mode 100644 policies/_helpers/policies/range.rego create mode 100644 policies/_helpers/policies/whitelist.rego create mode 100644 policies/_helpers/shared.rego create mode 100644 policies/gcp/backup_for_gke/backup_channel/description/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_channel/destination_project/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_channel/labels/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_channel/location/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_channel/name/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_channel/vars.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/all_namespaces/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/backup_schedule/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/deactivated/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/description/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/include_secrets/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/labels/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/name/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/permissive_mode/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/retention_policy/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/vars.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/custom_roles/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/domain_access/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/federated_identities/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/members/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/project_roles/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/role/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/vars.rego create mode 100644 policies/gcp/backup_for_gke/restore_channel/description/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_channel/destination_project/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_channel/labels/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_channel/location/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_channel/name/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_channel/vars.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/all_namespaces/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/cluster_resource_scope/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/conflict_policy/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/descripttion/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/field_actions/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/transformation_rules/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/vars.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/volume_data_restore/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/domain_access/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/member_count/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/personal_emails/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/project_roles/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/public_access/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/restore_permissions/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/role/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/service_accounts/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/vars.rego create mode 100644 templates/gcp/c.tf create mode 100644 templates/gcp/config.tf create mode 100644 templates/gcp/nc.tf create mode 100644 templates/gcp/policy.rego create mode 100644 templates/gcp/vars.rego create mode 100644 tests/_helpers/README.md create mode 100644 tests/_helpers/blacklist_test.rego create mode 100644 tests/_helpers/check_ux.sh create mode 100644 tests/_helpers/element_blacklist_test.rego create mode 100644 tests/_helpers/fixtures/gcp_access_level/plan.json create mode 100644 tests/_helpers/fixtures/gcp_project/plan.json create mode 100644 tests/_helpers/fixtures/gcp_storage_bucket/plan.json create mode 100644 tests/_helpers/pattern_blacklist_test.rego create mode 100644 tests/_helpers/pattern_whitelist_test.rego create mode 100644 tests/_helpers/policy_debug.sh create mode 100644 tests/_helpers/range_test.rego create mode 100644 tests/_helpers/shared_test.rego create mode 100644 tests/_helpers/smoke_test_helpers.sh create mode 100644 tests/_helpers/unit_test_helpers.sh create mode 100644 tests/_helpers/whitelist_test.rego diff --git a/docs/gcp/_helpers/helpers.md b/docs/gcp/_helpers/helpers.md new file mode 100644 index 000000000..9fe0bc140 --- /dev/null +++ b/docs/gcp/_helpers/helpers.md @@ -0,0 +1,856 @@ +# terraform.gcp.helpers Documentation + +**Tested on:** OPA Version 1.2.0, Rego Version v1
+**Purpose:** Provides helper functions for GCP Terraform compliance policies, including resource handling, array checks, attribute formatting, range tests, and empty value handling. + +## +**Last updated:** 21 September 2025 (T2 2025)
+**By:** Visal Dam + +--- +## Table of Contents + +1. [Architecture](#architecture) +2. [Utility Functions](#utility-functions) +3. [Entry Functions](#entry-functions) +4. [Policy Types](#policy-types) +5. [Tips](#tips) +6. [Development Team](#development-team) +--- + +## Architecture +The helpers is built on Rego, which is a declarative language. Hence, development is very different compared to popular functional langauges. + +In a declarative language, think of functions as being built out of conditions which are all assumed true. If any condition is not, then the function does not execute any further. + +Development of the helpers should be backwards-compatible. All new features should ensure that previously-made policies remain supported - unless you come across something far too critical. + +Our policies check for non-compliance. When a condition or situation is "triggered", it means that the resource(s) - and by extension the entire configuration - is non-compliant. + +Our policies assess only values that are prone to misconfiguration. This is the main objective of the PDE. This means that values that are not allowed Terraform are irrelevant; otherwise, they would not be generated in the json plan in the firt place. For example, consider the attribute "number_of_cpus", which should take integer values by default. Hence, policies or methods to check if the input is a string is irrelevant. + +## Utility Functions +### get_resource_name() +```rego +get_resource_name(this_nc_resource, value_name) = resource_name if { + this_nc_resource.values[value_name] + resource_name := this_nc_resource.values[value_name] +} else = resource_name if { + resource_name := this_nc_resource[value_name] +} else = null if { + print(sprintf("Resource name for '%s' was not found! Your 'resource_value_name' in vars is wrong. Try 'resource_value_name': 'name'.", [this_nc_resource.type])) +} +``` +#### Notes +Likely to be depreceated - just have all resources collected by resource_name, set to c1, c2, ..., nc1, nc2, ... etc. + +### resource_type_match() +```rego +# for resource filtering +resource_type_match(resource, resource_type) if { + resource.type == resource_type +} +``` +#### Notes +A json plan may contain multiple resources. This function ensures that only the resources of interest are collected. + +### get_all_resources() +```rego +# returns all resouce blocks in json plan of given type +get_all_resources(resource_type) = resources if +{ + resources := [ + resource | + resource := input.planned_values.root_module.resources[_] + resource_type_match(resource, resource_type) + ] +} +``` +#### Notes +This returns all the resource blocks (their config values and attributes) in the json plan, based on their resource type. + +### get_policy_type() +```rego +# extract policy type +get_policy_type(chosen_type) = policy_type if { + policy_type := policy_types[_] + policy_type == chosen_type +} +``` +#### Notes +Simple array checker. + +### Attribute Path Mapping +```rego +# returns workable string for Rego's object.get() +format_attribute_path(attribute_path) = string_path if { + is_array(attribute_path) + string_path := concat(".", get_attribute_path(attribute_path)) +} + +format_attribute_path(attribute_path) = string_path if { + is_string(attribute_path) + string_path := replace(attribute_path, "_", " ") +} + +# converts given attribute path into workable string for Rego's object.get() +get_attribute_path(attribute_path) = result if { + is_array(attribute_path) + result := [ val | + x := attribute_path[_] + val := convert_value(x) + ] +} + +# converts values from an int to a string but leaves strings as is +convert_value(x) = string if { + type_name(x) == "number" + string := sprintf("[%v]", [x]) +} + +convert_value(x) = x if { + type_name(x) == "string" +} +``` +#### Notes +N/A + +### Presence Checks() +```rego +# empty_message: if empty, return fomratted warning +empty_message(value) = msg if { + is_empty(value) + msg = " (!!!EMPTY!!!)" +} + +# empty_message: if present, return nothing (space) +empty_message(value) = msg if { + not is_empty(value) + msg = "" +} + +# checks if value is empty space +is_empty(value) if { + value == "" +} +``` +#### Notes +Checks if assessed value is empty. Integrable functions where it is added by default to all messages to be formatted. If empty, displays warning. If not, leaves as is. + +### get_value_from_array() +```rego +get_value_from_array(arr, key) = value if { + some i + obj := arr[i] + obj[key] != null + value := obj[key] +} +``` +#### Notes +N/A + +### check_empty_set() +```rego +# checks if a set is empty and returns a message if it is +check_empty_set(set,msg) = return if { + count(set) == 0 + return := [msg] +} +check_empty_set(set,msg) = return if { + count(set) != 0 + return := set +} +``` +#### Notes +N/A + +### intersection_all() +```rego +intersection_all(sets) = result if { + result = {x | + x = sets[0][_] + all_other := [s | s := sets[_]] + every s in all_other { x in s } + } +} +``` +#### Notes +Custom intersection function, used in processing resource violations. + +## Entry Functions + +### Main +```rego +get_multi_summary(situations, variables) = summary if { + resource_type := variables.resource_type + friendly_resource_name := variables.friendly_resource_name + value_name := variables.resource_value_name + all_resources := get_all_resources(resource_type) + violations := check_violations(resource_type, situations, friendly_resource_name, value_name) + violations_object := process_violations(violations) + formatted_message := format_violations(violations_object) + summary := { + "message": array.concat( + [sprintf("Total %s detected: %d ", [friendly_resource_name, count(all_resources)])], + formatted_message + ), + "details": violations_object + } +} else := "Policy type not supported." +``` +#### Notes +Unpacks the policy into its core components. Situtations have their descriptions, remedies, and conditions (as well as each condition's attribute paths, allowed/disallowed values, and policy types) extracted. + +All resources of interest from the json plan are extracted. Then, we for each resource, we check for non-compliance at the situation level (check_violations() below). Remember that for a situation composed of multiple conditions c1, c2, ..., etc., all of the conditions must be triggered for the situation to be triggered. For a policy composed of multiple situations, any of those triggered situations will trigger the entire policy. + +### Policy Selectors +
+select_policy_logic() + +```rego +select_policy_logic(resource_type, attribute_path, values_formatted, friendly_resource_name, chosen_type, value_name) = results if { + chosen_type == policy_types[0] # Blacklist + results := get_blacklist_violations(resource_type, attribute_path, values_formatted, friendly_resource_name, value_name) +} + +select_policy_logic(resource_type, attribute_path, values_formatted, friendly_resource_name, chosen_type, value_name) = results if { + chosen_type == policy_types[1] # Whitelist + results := get_whitelist_violations(resource_type, attribute_path, values_formatted, friendly_resource_name, value_name) +} + +select_policy_logic(resource_type, attribute_path, values_formatted, friendly_resource_name, chosen_type, value_name) = results if { + chosen_type == policy_types[2] # Range (Upper and lower bounds) + values_formatted_range := format_range_input(values_formatted[0], values_formatted[1]) + results := get_range_violations(resource_type, attribute_path, values_formatted_range, friendly_resource_name, value_name) +} + +select_policy_logic(resource_type, attribute_path, values_formatted, friendly_resource_name, chosen_type, value_name) = results if { + chosen_type == policy_types[3] # Patterns (B) + results := get_pattern_blacklist_violations(resource_type, attribute_path, values_formatted, friendly_resource_name, value_name) +} + +select_policy_logic(resource_type, attribute_path, values_formatted, friendly_resource_name, chosen_type, value_name) = results if { + chosen_type == policy_types[4] # Patterns (W) + results := get_pattern_whitelist_violations(resource_type, attribute_path, values_formatted, friendly_resource_name, value_name) +} +``` +
+ +#### Notes +N/A + +### check_violations() +```rego +check_violations(resource_type, situations, friendly_resource_name, value_name) = violations if { + some i + violations := [ + msg | + msg := check_conditions(resource_type, situations[i], friendly_resource_name, value_name) + ] +} +``` +#### Notes +This function operates at the policy -> situation(s) level. For each situation (in the list of situations), we call check_conditions() below. + +### check_conditions() +```rego +check_conditions(resource_type, situation, friendly_resource_name, value_name) = violations if { + messages := [ + msg | + condition := situation[_] + condition_name := condition.condition + attribute_path := condition.attribute_path + values := condition.values + pol := lower(condition.policy_type) + pol == get_policy_type(pol) + values_formatted = array_check(values) + msg := {condition_name : select_policy_logic(resource_type, attribute_path, values_formatted, friendly_resource_name, pol, value_name)} + ] + sd := get_value_from_array(situation,"situation_description") + remedies := get_value_from_array(situation,"remedies") + violations := { + "situation_description": sd, + "remedies": remedies, + "all_conditions": messages + } +} +``` +#### Notes +This function operates at the situation -> conditon(s) level. Here we enumerate each condition for a situation, extracting key components. We are now working on the condition level. We then apply policy logic depending on the policy type. We also format the inputs to expected forms. We collect all instances of non-compliance as "msg" dictionary objects, which contains the output non-compliance message for that specific condition. + +Once all triggered conditions have been collected, they are returned and mapped to their corresponding situations in the "violations" dictionary object. I.e., this function returns all triggered conditions for a given situation. "all_conditions": [{c1 : [{msg, nc}, {msg, nc}, ...]}, {c2 :[{msg, nc}, ...]}, ... : [...], ...}] for the given situation. + +### Processing Resource Violations +```rego +process_violations(violations) = situation_summary if { + # in each set of rules, get each unique nc resource name and each violation message + situation := [ + {sit_desc : {"remedies": remedies, "conds": conds}} | + this_sit := violations[_] + sit_desc := this_sit.situation_description + remedies := this_sit.remedies + conds := this_sit.all_conditions + ] + + # create a set containing only the nc resource for each situation + resource_sets := [ {sit_desc : resource_set} | + this_sit := situation[_] + some key, val in this_sit + sit_desc := key + this_condition := val.conds + resource_set := [nc | + some keyy, vall in this_condition[_] + nc := {x | x := vall[_].name}] + ] + + # implements AND logic per situation + overall_nc_resources := [ {sit_desc : intersec} | + this_set := resource_sets[_] + some key, val in this_set + sit_desc := key + intersec := intersection_all(val) + ] + + # final formating + resource_message := [ {sit : msg} | + some key, val in overall_nc_resources[_] + sit := key + msg := check_empty_set(val, "All passed") + ] + + # operate per situation: returns the entire details + situation_summary := [ summary | + this_sit := situation[_] + some key, val in this_sit + sit_name := key + details := val.conds + remedies := val.remedies + nc_all := object.get(resource_message[_], sit_name, null) + nc_all != null + + summary := { + "situation" : sit_name, + "remedies" : remedies, + "non_compliant_resources" : nc_all, + "details" : details + } + ] +} + +format_violations(violations_object) = formatted_message if { + formatted_message := [ + [ sd, nc, remedies] | + some i + this_sit := violations_object[i] + sd := sprintf("Situation %d: %s",[i+1, this_sit.situation]) + resources_value := [value | + value := this_sit.non_compliant_resources[_] + ] + nc := sprintf("Non-Compliant Resources: %s", [concat(", ", resources_value)]) + remedies := sprintf("Potential Remedies: %s", [concat(", ", this_sit.remedies)]) + ] +} +``` +#### Notes +Finally, after each situation has their condition(s) assessed via check_conditions(), the "violations" dictionary object is filled for the entire policy, detailing all situations and their triggered conditions (if any). The main idea in process_violations() is to implement AND and OR logic. + +situation := [...] returns a list of situations and their conditions. Consider a policy that contains two situations sit1 and sit2. They each have two conditions. For sit1, the same resources, nc1 and nc2, trigger both conditions. For sit2, nc1 triggers c1 but not nc2; and nc2 triggers c2 but not nc1. + +Click each of the below to expand. + +
+situation + +```json +situation = [ + { + "sit1": { + "remedies": "...", + "conds": [ + { + "c1": [ + { + "msg": "...", + "nc": "nc1" + }, + { + "msg": "...", + "nc": "nc2" + }, + ], + "c2": [ + { + "msg": "...", + "nc": "nc1" + }, + { + "msg": "...", + "nc": "nc2" + }, + ], + ...other conditions (if any) + } + ] + }, + "sit2": { + "remedies": "...", + "conds": [ + { + "c1": [ + { + "msg": "...", + "nc": "nc1" // note how only nc1 here for c1 + }, + ], + "c2": [ + { + "msg": "...", + "nc": "nc2" // note how only nc2 here for c2 + }, + ], + ...other conditions (if any) + } + ] + }, + ...other situations (if any) + } +] +``` +The situations are evaluated and each of the conditions, triggered or otherwise, are listed alongside the non-compliant resource that triggered it. + +
+ +
+overall_nc_resources + +```json +overall_nc_resources = [ + { + "sit1": ["nc1", "nc2"], + "sit2": [] // empty, as both conditions must share the same nc resource(s) + } +] +``` + +Afterwards, for each situation we perform an INTERSECTION operation for all of their conditions based on the non-compliant resource. We see that as both nc1 and nc2 are in c1 and c2, the overall non-compliant resource for this situation (after having triggered ALL of its conditions) are listed. + +For sit2, as not all of the conditions share the same resource, the result from the INTERSECTION operation is empty. + +
+ +
+resource_message + +```json +resource_message: [ + { + "sit1": ["c", "nc"] + }, + { + "sit2": ["All passed"] + } +] +``` + +Finally, we structure the situations into individual blocks. For any empty sets, we simply assign the message "All passed". +
+ +
+situation_summary + +```json +situation_summary: [ + { + "non_compliant_resources": ["nc1", "nc2"], + "remedies": ["..."], + "situation": "sit1", + "details": [ + { + "c1": [ + { + "message": "...", + "name": "nc1" + }, + { + "message": "...", + "name": "nc2" + } + ] + }, + { + "c2": [ + { + "message": "...", + "name": "nc1" + }, + { + "message": "...", + "name": "nc2" + } + ] + } + ] + }, + { + "non_compliant_resources": ["All passed"], + "remedies": ["..."], + "situation": "sit2", + "details": [ + { + "c1": [ + { + "message": "...", + "name": "nc1" + } + ] + }, + { + "c2": [ + { + "message": "...", + "name": "nc2" + } + ] + } + ] + }, +] +``` + +Finally, we return the resources that are truly non-compliant per situation. In terms of resources, if all conditions in a situation are triggered, the sitaution is triggered; hence why sit2 results in "All passed" as both resources only triggered a single condition each. If any situation is triggered, then the policy as a whole is triggered; the config contains some non-compliant resource(s). + +The above block is what is returned for engineers to view the inticate details of a triggered policy violation, namely, which specific condition was triggered and by which resource(s). +
+ +## Policy Types + +```rego +policy_types := ["blacklist", "whitelist", "range", "pattern blacklist", "pattern whitelist"] +``` + +### Blacklisting +#### Checking +```rego +# ***** Entry Function ***** +get_blacklisted_resources(resource_type, attribute_path, blacklisted_values) = resources if { + resources := [ + resource | + resource := input.planned_values.root_module.resources[_] + resource_type_match(resource, resource_type) + array_contains(blacklisted_values, object.get(resource.values, attribute_path, null), "blacklist") + ] +} + +# if single element (function name: Bl1) +array_contains(arr, elem, pol) if { + not is_array(elem) + arr[_] == elem +} + +# if array (function name: Bl2) +array_contains(arr, elem, pol) if { + is_array(elem) + pol == "blacklist" + arr_to_set = {x | x := arr[_]} + elem_to_set = {x | x := elem[_]} + count(arr_to_set & elem_to_set) > 0 +} +``` +Blacklisting is the simplest policy, and two functions are used to support two main types of inputs: + +1) Single elements: consider an array of disallowed values, a = [1, 2, 3, 4, 5]. Given an element input, i = 3, Bl1 iterates through a, and if 3 is spotted, non-compliance is triggered. +2) Arrays: consider an array of disallowed values, a = [1, 2, 3, 4, 5]. Given an array input, i = [2, 5, 3] (order not important), Bl2 turns both into sets and applies the INTERSECTION (&) set operation. Any elements shared between the two is counted; if greater than 0, non-compliance is triggered. + +These two functions are iteratively applied to each resource block in the json plan; the 'resource := input.planned_values.root_module.resources[_]' block goes through each resource dictionary block in the json plan under the planned_values -> root_module -> resources. + +#### Collecting +```rego +# iterates through given set of resources, applies Bl functions to each +get_blacklist_violations(resource_type, attribute_path, blacklisted_values, friendly_resource_name, value_name) = results if { + string_path := format_attribute_path(attribute_path) + results := + [ { "name": get_resource_name(this_nc_resource, value_name), + "message": msg + } | + nc_resources := get_blacklisted_resources(resource_type, attribute_path, blacklisted_values) + this_nc_resource = nc_resources[_] + this_nc_attribute = object.get(this_nc_resource.values, attribute_path, null) + msg := format_blacklist_message(friendly_resource_name, get_resource_name(this_nc_resource, value_name), string_path, this_nc_attribute, empty_message(this_nc_attribute), blacklisted_values) + ] +} +``` +get_blacklist_violations() iterates through the given json input of resource configs, applying the Bl functions to each. We begin with a list operation in rego to assign values to a dictionary: "name" and "msg". All non-compliant resources are collected based on what happens when the Bl functions are applied. + +Then, for each of the non-compliant resources, we use Rego's object.get to get the non-compliant attribute. +```rego +# displays non-compliant message for given non-compliant resources +format_blacklist_message(friendly_resource_name, resource_value_name, string_path, nc_value, empty, nc_values) = msg if { + msg := sprintf( + "%s '%s' has '%s' set to '%v'%s. This is blacklisted: %v", + [friendly_resource_name, resource_value_name, string_path, nc_value, empty, nc_values] + ) +} +``` +Finally, we use the collected information to display an informative message, namely, that the detected value is non-compliant because it is listed in the array of disallowed values. + +#### Notes +N/A + +### Whitelisting +#### Checking +```rego +# ***** Entry Function ***** +get_nc_whitelisted_resources(resource_type, attribute_path, compliant_values) = resources if { + resources := [ + resource | + resource := input.planned_values.root_module.resources[_] + resource_type_match(resource, resource_type) + # Test array of array and deeply nested values + not array_contains(compliant_values, object.get(resource.values, attribute_path, null), "whitelist") + ] +} + +# if single element (function name: Wl1) +array_contains(arr, elem, pol) if { + not is_array(elem) + arr[_] == elem +} + +# if array (function name: Wl2) +array_contains(arr, elem, pol) if { + is_array(elem) + pol == "whitelist" + arr_to_set = {x | x := arr[_]} + elem_to_set = {x | x := elem[_]} + object.subset(arr_to_set, elem_to_set) +} +``` + +Whitelisting is the opposite of Blacklisting. It follows the exact opposite logic for single elements, but not for array elements. +1) Single elements: consider an array of allowed values, a = [1, 2, 3, 4, 5]. Given an element input, i = 3, Wl1 iterates through a. It seems that 3 is in the list, and thus the resource is compliant. The opposite is true for a different input, say, i = 6. +2) Arrays: consider an array of allowed values, a = [1, 2, 3, 4, 5]. Given an array input, i = [2, 5, 8], Wl2 converts them into sets and applies the SUBSET set operation. A resource is only compliant if i is a direct subset of a. In this case, while a and i share 2 and 5, i contains 8, which is not in a. Thus, non-compliant is triggered. If i = [5, 3, 2], then the resource is compliant as a and i share all elements in i. + +#### Collecting +Same logic as in Blacklisting. + +#### Notes +N/A + +### Range +#### Checking +```rego +# ***** Entry Function ***** +get_nc_range_resources(resource_type, attribute_path, range_values) = resources if { + resources := [ + resource | + resource := input.planned_values.root_module.resources[_] + resource_type_match(resource, resource_type) + not test_value_range(range_values, to_number(object.get(resource.values, attribute_path, null))) + ] +} + +test_value_range(range_values, value) if { + test_lower_range(range_values, value) + test_upper_range(range_values, value) +} + +# ***** Lower bound checks ***** +test_lower_range(range_values,value) = true if { + # Check value exists + not is_null(range_values.lower_bound) + value >= range_values.lower_bound +} + +# null indicates no higher bound +test_lower_range(range_values,value) = true if { + is_null(range_values.lower_bound) +} + +# ***** Upper bound checks ***** +test_upper_range(range_values,value) = true if { + # Check value exists + not is_null(range_values.upper_bound) + value <= range_values.upper_bound +} + +# null indicates no higher bound +test_upper_range(range_values,value) = true if { + is_null(range_values.upper_bound) +} +``` + +The Range policy type performs a seemingly simple purpose: to check that a given integer input i is within a certain range, defined by lower and upper bounds L and U, respectively; i.e., L <= i <= U. However, many utility sub-functions are needed to ensure that this purpose is met, namely, datatype checking and handling cases where a range is not defined as between two bounds, but rather (either) a min/max. + +If L = 100 and U = 200, then i = 150 is compliant, however both i = 99 and i = 201 are non-compliant. To handle a minimum value for i, simply set L = 100 and U = null; thus any i >= 100 is compliant with no limits. Likewise, setting L = null and U = 100 means only i <= 100 is compliant with no limits. + +#### Collecting +```rego +get_range_violations(resource_type, attribute_path, range_values, friendly_resource_name, value_name) = results if { + unpacked_range_values = range_values + string_path := format_attribute_path(attribute_path) + results := + [ { "name": get_resource_name(this_nc_resource, value_name), + "message": msg + } | + nc_resources := get_nc_range_resources(resource_type, attribute_path, unpacked_range_values) + this_nc_resource = nc_resources[_] + this_nc_attribute = object.get(this_nc_resource.values, attribute_path, null) + msg := format_range_validation_message(friendly_resource_name, get_resource_name(this_nc_resource, value_name), string_path, this_nc_attribute, empty_message(this_nc_attribute), unpacked_range_values) + ] +} +``` + +```rego +format_range_validation_message(friendly_resource_name, resource_value_name, attribute_path_string, nc_value, empty, range_values) = msg if { + upper_bound := get_upper_bound(range_values) + lower_bound := get_lower_bound(range_values) + msg := sprintf( + "%s '%s' has '%s' set to '%s'%s. It should be set between '%s and %s'.", + [friendly_resource_name, resource_value_name, attribute_path_string, nc_value, empty, lower_bound, upper_bound] + ) +} + +get_upper_bound(range_values) = bound if { + not is_null(range_values.upper_bound) + bound := sprintf("%v", [range_values.upper_bound]) +} + +get_upper_bound(range_values) = "Inf" if { + is_null(range_values.upper_bound) +} + +get_lower_bound(range_values) = bound if { + not is_null(range_values.lower_bound) + bound := sprintf("%v", [range_values.lower_bound]) +} + +get_lower_bound(range_values) = "-Inf" if { + is_null(range_values.lower_bound) +} +``` + +#### Notes +N/A + +### Patterns (Blacklisting & Whitelisting) +Note that Patterns Blacklist and Whitelist use the same pattern logic in get_target_list(), just treating non-compliance differently. Hence, we will only be discussing the Pattern Blacklist method. +#### Checking +```rego +# returns a list of the found values based on a given pattern +get_target_list(resource, attribute_path, target) = target_list if { + p := regex.replace(target, "\\*", "([^/]+)") + target_value := object.get(resource.values, attribute_path, null) + matches := regex.find_all_string_submatch_n(p, target_value, 1)[0] + target_list := array.slice(matches, 1, count(matches)) +} else := "Wrong pattern" + +# iterates through target list and given disallowed/allowed patterns +get_nc_pattern_blacklist(resource, attribute_path, target, patterns) = ncc if { + target_list = get_target_list(resource, attribute_path, target) + ncc := [ + {"value": target_list[i], "allowed": patterns[i]} | # note: "allowed" should be "disallowed" here due to mistake from copying over + some i + array_contains(patterns[i], target_list[i], "blacklist") + ] +} + +# returns the non-compliant resources where a disallowed value was found +get_nc_pattern_blacklist_resources(resource_type, attribute_path, values) = resources if { + resources := [ + resource | + target := values[0] + patterns := values[1] + resource := input.planned_values.root_module.resources[_] + resource_type_match(resource, resource_type) + count(get_nc_pattern_blacklist(resource, attribute_path, target, patterns)) > 0 + ] +} +``` +For a given pattern, get_target_list() first replaces all instances of the * character with the simple regex pattern ([^/]+), which is used for simple searches of all alpha-numerical-symbolic characters. For a given pattern P = a/\*/c/\*/e this creates the regex search for a/**([^/]+)**/c/**([^/]+)**/e. Then we simply find this pattern in the json; if the input string i = a/**b**/c/**d**/e, then we have a match. We strip off b and d into a 'target' list, which is returned. Note their positions. + +Next, for a given array of arrays of disallowed patterns, get_nc_pattern_blacklist() simply checks, in order, whether or not the 'target' values are in the disallowed strings. Any value that fits is returned, alongside the pattern. So, consider the following array of array of disallowed patterns: A = [[array of patterns], [array of patterns]] = [[1, #, b], [2, e, %]]. Matching target_list[i] and A[i], we see that b is in [1, #, b], but that d is not in [2, e, %]. Hence, we have found a non-complaint value. + +Finally, based on get_nc_pattern_blacklist(), the resulting non-complaint values are counted. Any one match (as we are blacklisting) will result in the count of values greater than 0. +#### Collecting + +```rego +get_pattern_blacklist_violations(resource_type, attribute_path, values_formatted, friendly_resource_name, value_name) = results if { + string_path := format_attribute_path(attribute_path) + results := + [ { "name": get_resource_name(this_nc_resource, value_name), + "message": msg + } | + nc_resources := get_nc_pattern_blacklist_resources(resource_type, attribute_path, values_formatted) + this_nc_resource = nc_resources[_] + nc := get_nc_pattern_blacklist(this_nc_resource, attribute_path, values_formatted[0], values_formatted[1]) + this_nc := nc[_] + msg := format_pattern_blacklist_message(friendly_resource_name, get_resource_name(this_nc_resource, value_name), string_path, final_formatter(object.get(this_nc_resource.values, attribute_path, null), this_nc.value), empty_message(this_nc.value), this_nc.allowed) + ] +} + +format_pattern_blacklist_message(friendly_resource_name, resource_value_name, attribute_path_string, nc_value, empty, allowed_values) = msg if { + msg := sprintf( + "%s '%s' has '%s' set to '%s'%s. This is blacklisted: %s", + [friendly_resource_name, resource_value_name, attribute_path_string, nc_value, empty, allowed_values] + ) +} + +final_formatter(target, sub_pattern) = final_format if { + final_format := regex.replace(target, sub_pattern, sprintf("'%s'", [sub_pattern])) +} +``` +Follows the same formatting logic as above. Returns all inputted and collected information to the user. Namely, each detected disallowed value is collected and displayed alongside the given disallowed pattern list for clarity. + +#### Notes +1) The Pattern methods will only work as intended if the desired pattern to be checked exists. If you provide a pattern, say a/\*/d which is not found, then get_target_list() will fail. Hence, the Pattern method is meant for attributes whose values can be repeated often, such as compliant/non-compliant directory paths. +2) Due to (1), for other patterns, simply add a new situation (OR logic) to detect other patterns in your policies. + +## Tips +### Debugging +When debugging custom functions, it is useful to print values as the function executes. This is done in Rego using sprintf(). +```rego +print(sprintf("This is a custom message. val1: %v, val2: %v", [val1, val2])) +``` +We add a print() to force it to show on output. Otherwise, sprintf() will only output results when the --explain=notes flag is used in the opa eval command. Notice how the values in the array maps to the formatted string. Make sure to comment them out before deployment. + +Likewise, we use also use flags in the opa eval command for debugging: + +``` +--explain=fails +--explain=full +--explain=notes +``` + +We usually use --explain=fails when a policy fails to determine the root cause. The other two are not usually used. These flags will output the entire Rego execution process from function to function, so it can be overwhelming. + +### Development +You should create a seperate workfolder for helpers development, mimicking the same file and folder structure as the PDE. + +You should commit changes to the helpers in dev in a seperate PR always! You can simply edit the contents of the helpers.rego file there. Do not publish changes to the helpers in your service PRs. Only the development team should be making changes to the helpers. + +You should have your changes tested and looked at by others too, just in case. + +Changes and features should be backwards compatible, unless it is something truly critical. + +The OPA version is very important. Some members may have installed a version of OPA incompatible with the helper functions. Make sure everyone uses at least version 1.2.0+. + +Do not be scared by how complex the helpers seem; that's just Rego being Rego. The functionalities are rather simple when decoupled into their core operations. + +Lastly, do not hesitate to come up with new features, functionalities, or problem-solving perspectives. If an idea is not currently supported by the current utility functions, create your own! Likewise, feel free to improve existing ones - just make sure they're backwards compatible. You do not have to stick with what has been layed down; rather, use them as a means to go forward. + +Good luck, and have fun! + +## Development Team + +Contributions from individuals to the helpers.rego across trimester iterations. + +### T1 2025 +VISAL DAM
+PATRICK STUART
+SAMIRA FALAHAZANDEHI + +### T2 2025 +VISAL DAM
+PATRICK STUART
+SEBASTIAN EDGE + diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/c.tf b/inputs/gcp/backup_for_gke/backup_channel/description/c.tf new file mode 100644 index 000000000..a94202b1c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/description/c.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_backup_channel" "c" { + name = "backup-channel-with-desc" + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" + description = "Production backup channel for GKE cluster backup operations" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/config.tf b/inputs/gcp/backup_for_gke/backup_channel/description/config.tf new file mode 100644 index 000000000..6d33dfcda --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/description/config.tf @@ -0,0 +1,15 @@ +##### DO NOT EDIT ###### + +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf new file mode 100644 index 000000000..1660c215e --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_backup_channel" "nc" { + name = "backup-channel-no-desc" + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" + # Missing description - non-compliant +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/plan.json b/inputs/gcp/backup_for_gke/backup_channel/description/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..8d3f9032567ab52861833517b08be9b9fa96399a GIT binary patch literal 17920 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 E1tg%^*#H0l literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/labels/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf b/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf new file mode 100644 index 000000000..fd65e38f1 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf @@ -0,0 +1,13 @@ +resource "google_gke_backup_backup_channel" "c" { + name = "backup-channel-with-labels" + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" + + labels = { + environment = "production" + team = "platform" + compliance = "required" + cost-center = "engineering" + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/config.tf b/inputs/gcp/backup_for_gke/backup_channel/labels/config.tf new file mode 100644 index 000000000..6d33dfcda --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/config.tf @@ -0,0 +1,15 @@ +##### DO NOT EDIT ###### + +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/labels/nc.tf new file mode 100644 index 000000000..8333763bc --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/nc.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_backup_channel" "nc" { + name = "backup-channel-no-labels" + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" + # Missing labels - non-compliant +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/plan.json b/inputs/gcp/backup_for_gke/backup_channel/labels/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..5f736387db5b7c8121d759f25a09f70271f4df21 GIT binary patch literal 20978 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 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/name/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/name/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/c.tf b/inputs/gcp/backup_for_gke/backup_channel/name/c.tf new file mode 100644 index 000000000..1c7a84080 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/name/c.tf @@ -0,0 +1,6 @@ +resource "google_gke_backup_backup_channel" "c" { + name = "prod-backup-channel-001" + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/config.tf b/inputs/gcp/backup_for_gke/backup_channel/name/config.tf new file mode 100644 index 000000000..4a5fbbd4e --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/name/config.tf @@ -0,0 +1,16 @@ +##### DO NOT EDIT ###### + +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +# Add this variable definition if you want to use var.gcp_project +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/name/nc.tf new file mode 100644 index 000000000..6e20ccd02 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/name/nc.tf @@ -0,0 +1,6 @@ +resource "google_gke_backup_backup_channel" "nc" { + name = "" # Non-compliant: Empty name + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/plan.json b/inputs/gcp/backup_for_gke/backup_channel/name/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..4104c268a4131b668fbc8388196b0bccadb8c2b4 GIT binary patch literal 17196 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 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/c.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_config/c.tf new file mode 100644 index 000000000..728f37368 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/c.tf @@ -0,0 +1,20 @@ +resource "google_gke_backup_backup_plan" "c" { + name = "secure-backup-config" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + backup_config { + include_volume_data = true + include_secrets = false # SECURITY: Never backup secrets + #all_namespaces = false # SECURITY: Principle of least privilege + + selected_namespaces { + namespaces = ["production", "critical-apps"] # SECURITY: Only backup what's needed + } + + encryption_key { # SECURITY: Customer-managed encryption + gcp_kms_encryption_key = "projects/fluent-coder-468700-h4/locations/australia-southeast1/keyRings/backup-keyring/cryptoKeys/backup-key" + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/config.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_config/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_config/nc.tf new file mode 100644 index 000000000..b6dcedf71 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/nc.tf @@ -0,0 +1,13 @@ +resource "google_gke_backup_backup_plan" "nc" { + name = "insecure-backup-config" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + backup_config { + include_volume_data = true + include_secrets = true # SECURITY RISK: Secrets exposed in backups + all_namespaces = true # SECURITY RISK: Overly broad scope + # SECURITY RISK: No encryption specified + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/plan.json b/inputs/gcp/backup_for_gke/backup_plan/backup_config/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..f2c0457e973517cf3b2efbfade7230dad47451f6 GIT binary patch literal 14690 zcmeHO+in{-5an}${)C<*%SzKW^)K|T$Wshsq3UA0mR5!?ZiOPh-u4_GO-QaJ@2)B* z>u3=;l9uFfICEw=9M1mx&)=@&CT{K)ZsrDVdCVyFbu2#5~r@aZ|U( zQ*krd{>ss(i=J~g@;r6jJNJ`&?|ycd_}6uJ_}y`z@Q-{yV$=XD%F%b^*J)G(ADn&e zr7-hU*Pc(~V}X%NJYR#$q5sa7Yrld4XpZolJw%VIBDGsjBg5wdS~IMDfYA@2!WE~# zjK>S~khH~zt(-c_@plVKqiv6s+klewIDSseN9wcB)Qk)1_Lp$t2+>9}P=vVcKRmmzcuggtD(GdIqj+dZZHi~$RvA%>9 z>fpKu?&jc&HY=V;VF13R17e$&*2QlkcIBl>$**9Ky)FO0p-&FUaBM8M?zWxQ%JyC) zfw}t?tJ@qLLyNodlH=GR_*i??WEeraCRSGXPHjxU;nY8;q>KHZz&S?~XBlX4tph)f zD5F1+T@z_DjHcz?d;gW;x4Z&piM2@{=zHj2%{aDYnob-rI98j z6R%s^BW5ULwipNIqrWt6Q;s;h>}ce70-_~wOR3ObafOsku-_so#z5i(Jtb4_fVR;+vc72<-M6T=6#Sde~Jfq-*$y3;pU-E ze91cx-rE&v@J6lpOqm$Q734s-6wI9R){+qg@u1t$n43EJFXqTC%1PH0S~4Gr@y5vR zf#cZ}^~Cw_eHmLtzH8)9(^cwu99ijhD9yK0E+L1Q##@K_SB=41%V56Qa?YtQdG1E2 z4(971vMQc!=LufJ>){qHz)hr&PuUQDz|B!=!$vSHjAr0=5XYHjHgIrW%}~= z?wHj;ukG%*&EoF6zi&aK^hr%f8e53Gh7v0T>q$S@tPt7W!PzT3- zo3Zw8bwE7EdZl%o8fj65B7n39&vX-CcNSM;swZ)Ox_bbf8hE?VR`^z{@Qw8w*Sn^5 z&C2(U-CrIds(!Y5R6|92x{T?vhwi+}V|SvkZj~*^Xg=jNm^WcHF>{!qo?O`eS{03~ z3g5Vws>HPue)*ZFimXC5=98~tEK)sO;ZlXVo#jM(H=;355^8Sk=8n`4wN{z=8smk6 zV=8OoOv>)5r^@^```5x?%JuVAwbIVM8r5nmtzO5fnM|+dP0HG@AE|=h z)JGNl-)<)9|I<8`Pqm#OwRJ;#xmBeYZ*twgEU(EPs$Nc|8D8qf@A!} yyu!El?jw5YHc4;(Y(B4sRLsKJgH}Q6d@qJK6vcME`jk2Li*l)=l%oK41Oa3 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/c.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/c.tf new file mode 100644 index 000000000..6e0d0bd6d --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/c.tf @@ -0,0 +1,19 @@ +resource "google_gke_backup_backup_plan" "c" { + name = "ransomware-protected-backup" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + retention_policy { + backup_delete_lock_days = 30 # SECURE: 30-day protection against deletion + backup_retain_days = 180 + } + + backup_config { + include_volume_data = true + include_secrets = false + selected_namespaces { + namespaces = ["production"] + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/config.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/nc.tf new file mode 100644 index 000000000..e14e250a7 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/nc.tf @@ -0,0 +1,14 @@ +resource "google_gke_backup_backup_plan" "nc" { + name = "vulnerable-to-deletion" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + # SECURITY RISK: No retention policy means no delete protection + + backup_config { + include_volume_data = true + include_secrets = false + all_namespaces = true + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/plan.json b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..a104c8e3fefd77e7175162406599e35db831c822 GIT binary patch literal 14182 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 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/c.tf b/inputs/gcp/backup_for_gke/backup_plan/deactivated/c.tf new file mode 100644 index 000000000..abec5bfe7 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/c.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_backup_plan" "c" { + name = "active-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + deactivated = false # SECURITY: Backup plan is active +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/config.tf b/inputs/gcp/backup_for_gke/backup_plan/deactivated/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/deactivated/nc.tf new file mode 100644 index 000000000..b0717a294 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/nc.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_backup_plan" "nc" { + name = "deactivated-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + deactivated = true # SECURITY RISK: No backups being created +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/plan.json b/inputs/gcp/backup_for_gke/backup_plan/deactivated/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..751c2ff790104caae843e53f3676e226e85044ad GIT binary patch literal 10120 zcmeHN+iuf95S?cvej?B0%B9fn;E5`-++5ny#EEh#RES>(&e`Ls*NIaSNTC!fN>h7h zXJ_ZObJ_3TzF5P?HnW9IEwz;;c4H$vE$s?#GmM_%+qIVU@cRPaRTy6Y+UM<_)3ukF z+0AF(V9o+~Q#-c_uq^TZ)JVaF4Q!6J=NO;aM~n@yj*oKQ#MXE#YR36f2AC!wXEqEp zHSLwXvA1?&9ekR0iRXrW#fNmyF)PK6GQbYQJ{@a82Unj3E=&W~b)eJfSYYN7@7JJm z5dP=LS=d1eoI|`Pgz#}!#C8#IB>26?Xo9_`n0*Z_+;REIX>0*P+!h_abIK^g_X3!P zImF6tfyp6$eNC-L?9)4JPKD%h1KEkwNuZ*D`BZH=1VGT*EA7+-Je6=B@Ld}dJ z2Y9m%JL8TxLS2gWbcr1tqLXc4oMC^oH(41mr1>i3*#z%XXt1^983y;AgBS zq*^{i^U7MFl@HMaVWI6%BJ^g`2KvDnR-%R627aEIw07I79-8;0iFQt}x5}mK{Fij7 zJz0>V^o#oNC+u=RJrs?{=P^$e;-;n_+xKUXyL994djEos+W*t{K0W{Mp0@V>9zRu| zmGwDLp99m%I7jC|KR*o`h+N7!LIPjTh&Kx{yP~5yV-TN?n=!l~xnZ&D6*jzJwN=hd#4thLl<%g@i2 z!U7ZIAsMPC8Eozo{<@_f+aeFiE||ZuCPP}{h>F#c&3B5V=}nkFs}jX*j}y6}a9Tj-Br(EZw#XOzLW9)D0x+5i99YNL6K^+~`(LtPp z?TRLzZgkKOeU~`PWCyb79`R)0?zgM7@f?RL_u4eGoSl>*n7xbZ}da zUD!A(@@~NW@=Zd2S^c7N?^(Tsk$nytq7Jq99bGH7V-0GQ^hbFE^OCr;^RLAt%1f$G z*@6qI6fuLU+HXYGzeA~&Vhi1Og`z{dJBko?Y1Zbw3r6GY^zxUzAZiXd zb%wv}@Ga2i-*t1NsEB%ReRn6HG;mMCEckc396|16vorO+200 zd;H&lZ|m4Q{O#c$*#|(Y`aj3a32tKey)|NSJt72cnAmx9h;^UMaovRCT_?Ze5}zZ_ H?V0@mb_OH8 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/c.tf b/inputs/gcp/backup_for_gke/backup_plan/description/c.tf new file mode 100644 index 000000000..87204987d --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/description/c.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_backup_plan" "c" { + name = "backup-plan-with-description" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + description = "Daily backup plan for production GKE cluster with 90-day retention policy. Backs up critical namespaces and persistent volumes." +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/config.tf b/inputs/gcp/backup_for_gke/backup_plan/description/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/description/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf new file mode 100644 index 000000000..8d591462b --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_backup_plan" "nc" { + name = "backup-plan-no-description" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + # Missing description - non-compliant +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/plan.json b/inputs/gcp/backup_for_gke/backup_plan/description/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..276c68ce81f0ab5b2ec210cc2d81a7c186dcd791 GIT binary patch literal 10790 zcmeHNOK;Oa5S}v<|G~-`w@G;vdPE=&TscuymYXzfY2rk2(h?#5I`Dn_dFyrJ6bH3X zS}RIo?_+k}J2SgKe|)o!4Q*mG8(V5~OYG84@Rr*-S~K(>;M=nu+r$4eeCMuzhS7fB z<~cokj+wn;<|XFL05`Q`8v#m=_5&jZr`ESA)}Eq&VqehL$2z{3^G3EntFRdsZyCnK z7&) zIocP%vhSYRbLc2Y0ds(Mju1RjMQEoEMuPtf^d_J^#q0|}A;r}?VkatYaq(}}~P97noO(VK&JGvKp>e`-;vB|A=| zb|IA%gJQ)sZXZSFWhuFYXf zyO9AG7`LS3PD(0V2dPn%sPp#^PZ~}_b>b%wLmZ5KxCQm3~srB1kqCfi*19d|7c>J_~iefzwSxR;3}mZLXwlI2+G z$lvfj&2&>Z-ae1HcM>+W|F(Cy4E847__uppiATH3$yYwKUCvuFy;(DRDr2{Y;_EZ` zw${(LetujV+sMx!UFS;NNy1Dgfv;xVp1I6J5mB4>bX+WZyLnH@XCHSmx~1kalkvRo zpp8;u4#9jykrQJ|W#!6YLeIy1U6GZC8^(o{aGNQ$nNpi6`PxjIDb;1Jzu!SiKa(Jv z%8`-+9Xr62^6uu5pE4;{C|G4%g~9sQYMZhKu1PPg+9ESs z))?ti$ph6gLu|Im)fkm~KVPM(>`98XJ-htGw*QLWbepK}g zRWtn=nfy$31Y_c1aqe`t=easVV6~(@T@Pa;fBtc^d=qzXUh%uaa1?r%eA9pU6}V%+BwZbkB&D>u#PeeCDp;$q#|b2I)mKcCi0 zp=WBgLYOCRSDVp_RgLyullckH{`t?7Kw1&|4)IHynBkVdrrSwnz1-g)*?e1tIFQcA zc#0bCR;@R?`M%EoYlkgX;o@B#RrDA^@jj8N=FRRR`e?{k zQdPqnV-MHPyNBCSd-f8iwLSdDc-yy6c<#b0>9>npj-N4_5nPISywS77lWtWKN?7}& e^$|MnwXue^+E3rd$c!FPb-%KT_uZb_6Z-`%%brsJ literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/c.tf b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/c.tf new file mode 100644 index 000000000..cc4bcfd9b --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/c.tf @@ -0,0 +1,17 @@ +resource "google_gke_backup_backup_plan" "c" { + name = "cmek-encrypted-backups" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + backup_config { + include_volume_data = true + include_secrets = false + selected_namespaces { + namespaces = ["default", "production"] + } + encryption_key { + gcp_kms_encryption_key = "projects/fluent-coder-468700-h4/locations/australia-southeast1/keyRings/backup-keyring/cryptoKeys/backup-key" + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/config.tf b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf new file mode 100644 index 000000000..664a6065d --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf @@ -0,0 +1,13 @@ +resource "google_gke_backup_backup_plan" "nc" { + name = "unencrypted-backups" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + backup_config { + include_volume_data = true + include_secrets = false + all_namespaces = true + # SECURITY RISK: No customer-managed encryption specified + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/plan.json b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..acfcc617dc8104c10021bdb5a945766dd6012cf4 GIT binary patch literal 14654 zcmeI3+ioK_42E@Gpf8c@I!@AVx5z8>uIN>RVBp$0ZIW@|L)xI&S8w}&qFG5}J02U^ ztkVnv$DSF9qR5{VMRET5`>${iF2guX!hINoS*XHexX{%!+~{ttr>FWHhr@89@9*@P z#pe^X_I~U89Eb1K^LWwoQGF(&I|#prJ5ibH{%L@Nt1t`?8v8-d$KjKn4K#lKgxwxv;rl*$UFp50&!Vlrc@Kg90j`Y_H*SbCkpY;dd59&40jB2$V#d$i_#0R5~ zqZIBV)p_L8`IxBZRQKoNau|Q}S?9957hfsRG4vj zquk>^( z*-gaHp}s*;j*`QOsJ^r^P`hhgp}C28@2hW;l<_gu(`(US#;fpk6m^=Ak#tx}lrd@{ z^+sdl+Pafg(k!Op07)%7k6Xvh0PjIP#B1B(*fAV(t5fEv9l;mBtMfq_80vBqBgZ8L*HC(y~T5^mFN9T z0^{(rX7{wV4;FVGB}d<(_?So3RO*3UgO!1O*!aZYb=R*4349mIa1 z41ZvD4btw_8_Tfq^uE-GRqknuZpe$#O5ZlZ2c~H1KTD zx7nR7mt`KnlS6457NlzY8nG4 z$dxBw8>=NpVAX7A6umzPN!%h2d=xVTy~$>qNVpLCF4fXx#;UihL0g;5H}w`0$$eUH z!3mzxS4{KFNX=1-MZi}RA2}|Y)@*WbYtO5FH+FL?8I`^W{(6PAgRX?5eDx(Zu$8yn zS_>7kZ^m>ivaVyvSeW}vv#aG*;!EoQo{)?AM6)Z`gJ}tCt)n(+Yq;2Tohc>1dhKuv zUG@@h$us4iJpJC)2eq?J)7Q)6jffH2SpQ4Mb*zYHZTSjyAWXh)WS97OZ?T?D5`WkGXJB+Ey2J>{HZXUTxnaj$J&+K12@ionn(b zV^nF?ApgOh+H(zE{>b(WFPlHg<&5{WST604(~jEKad!UfgUvG7#anjM_Qt+LU^OG} znfAueE!Vd$`V<-5ri)7G+m76)*)cB(t+lwq5=lJgDD=$bS*J!{^x z>rfnzJWo}Il%e#>EG5;>UqCBI;n|G(i)c(A+Q{ygkYcZdn z+3!#EzRr&K>y&sG-_b?j)SeJQz26A@|BLSZh@wrtd2X62)>QAticOroTn&)-@m6KM zruFoA!q)z>1^cd2L2MQ-7ij=GU%*HqV?a?{V6U z=|1&q;jZNR`Lhhu$f{b@b~9~XuWBQ?F5QD{w&7u{-fUadYNM2P?_;sA?&<1d_*K7;6kFQ=54!)GTHEQ7z18!iIoaEWP;u*~ d1@-`S-hbglqWRq3U*iomf1@L}<8Q+^;a`2acr*Y2 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/c.tf b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/c.tf new file mode 100644 index 000000000..3b9b3b412 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/c.tf @@ -0,0 +1,14 @@ +resource "google_gke_backup_backup_plan" "c" { + name = "secure-secrets-handling" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + backup_config { + include_volume_data = true + include_secrets = false # SECURE: Secrets NOT included in backups + selected_namespaces { + namespaces = ["production", "app"] + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/config.tf b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/nc.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/plan.json b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..e6c2d4f3c2b47d19499824d03eabde82b3097675 GIT binary patch literal 7546 zcmeHM+fLg+5S`~r{fRs`gwWE`d`F*(kmcqADTx#1LW?SXz3n-BJl(aEfP?4*l7&Lz zz0A(_%g8NT1)vkCJntoD6}_w?;O zcJ|Aici6K6-Q2#}3{=(_9~e2fwxKO?_7d|8`;NIG&hc69o7onl;$~7l6ZXgFR?3!LUf$D@2b{k=k{jk>UFmvl(R1vHKQOC~@`4c|5@iXC2PI$e{4;ePsn7pWb1r0;JJ?Q|&H@*49p%2p>>9dTfu9q6(~D9sISC%sgH>{@ zyTKDJw*v1y?2VcdA8X9sfCeSr=U=D6rqMH^4XYaE83jCbiZfDc&0v)%#Ts1DD(;g7 ztiu)bn=$qegH%gMrKre)E$>T;S7F^WtfQY&M;T|5 zF87M4rwlY0$E1J!Zr{P!-=*!dj9EtH2+~smMPox(_<)^p&JFk}<_o3XF~LiVsT<%p-d^u)My zP7y*cql84%=$Um77(<2$R!V=w_Fc;fffa$>QX^^Pc1une|DG3wKh&CgCy|ymsQX3g zk97@6?@e{I51|xgMC5VMY#MXS0L05t(0maPKrvL$GR%S0Fk`(*P9YUVwstrwEJF-4 zwyM~$i-!N(3XB#a3A2^sk6S`^qUMTVPp*|`JQq)!V&pEeye2$K@jL#0E&?@+Oxfz? zeT`L-kTaf;);1Y@Skc2;!x5QC(N;PyTj`{FCLT)1G2glFI|1v*&_B_HnNJyye#AOT z`ORaTbF9!~ek0v#er#)_wl->Oqqa8UO@z0jwlm*)gfpU@xOSrW+S?COOcJnKeE8 zMa-7;1@)y;ZjPzWc-!*~UX>}%WFedLX6PNb^fYDk^nSMQE}^P!i^{$#rN()0_o_ji zit0^(dWjWowU#)vzG;2YM#b?_ag4toQk@}(8 zCMREFzjqEF@0+Hb(|U(d@%WSu{iN5>GnFOwbs(E)mAC0;om}sOx(yxgp4O%OxOp#A z63NzX0Y8n=z`ifP`TipIa5^ClR(MBq=&jpT=nWA8y;3{;7RGZKW9vEZ_E_&R5{c`o ztd8x)DmO_N-t|<}&k+a84`+BEcxLD55cl!j#nWf|g5Q1Mz&V}jCdt-kACdpk# literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/labels/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/labels/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/c.tf b/inputs/gcp/backup_for_gke/backup_plan/labels/c.tf new file mode 100644 index 000000000..799db6824 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/labels/c.tf @@ -0,0 +1,14 @@ +resource "google_gke_backup_backup_plan" "c" { + name = "backup-plan-with-labels" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + labels = { + environment = "production" + team = "platform-engineering" + compliance = "required" + backup-frequency = "daily" + cost-center = "engineering" + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/config.tf b/inputs/gcp/backup_for_gke/backup_plan/labels/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/labels/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/labels/nc.tf new file mode 100644 index 000000000..b6c3d25b4 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/labels/nc.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_backup_plan" "nc" { + name = "backup-plan-no-labels" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + # Missing labels - non-compliant +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/plan.json b/inputs/gcp/backup_for_gke/backup_plan/labels/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..3ae766578c580d1c940799637b5c6cff98045c75 GIT binary patch literal 11928 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 D3VN8g literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/c.tf b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/c.tf new file mode 100644 index 000000000..eb4892631 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/c.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_backup_plan" "c" { + name = "secure-backup-plan-retention" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + retention_policy { + backup_delete_lock_days = 30 # Security: Prevents accidental/malicious deletion + backup_retain_days = 90 # Security: Meets compliance requirements + locked = true # Security: Prevents policy tampering + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/config.tf b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/nc.tf new file mode 100644 index 000000000..1f9bc3434 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/nc.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_backup_plan" "nc" { + name = "insecure-backup-plan-retention" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + location = "australia-southeast1" + project = var.gcp_project + + retention_policy { + backup_delete_lock_days = 0 # SECURITY RISK: No protection against deletion + backup_retain_days = 3 # SECURITY RISK: Too short for incident response + locked = false # SECURITY RISK: Policy can be changed + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/plan.json b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..0d6354b9c23d1b899f81efaa0fc5b064ffa16f71 GIT binary patch literal 11138 zcmeHN*-qO)6ur-t`V)C>fRMJdd`F*(kmY6pN^qhqw5a0O+nzJW7mu9)HcQK5Mc~9U zbLVbz*ZK4NmvwAxQ=8kFrM9%h&TWKW3p>Hv45Rz_>)Dp=;`t7L%P>C2Y+rZ%nx6Hs zvX`$s$C^3druNMyfU>~*eIo`(Hn17?o?(1y-!V48K0eBI6IsSGR)~>=G2A( zr>?!XkM_y-YzLpN9piV$F7YAWGptHMQHHt0K&L}3@Zj##z=g8_brtY*Jmy%r!21=j z9E9&2IS3S_fH}l_&Ja9OMQBF>MuO)lMibDUV)ZGYkmB+$$8ifY#BJf>lv73-{*C}? zn9o?+1t9s1yYH#}2>t8|nqwikoI`fvbP}*A=8^6rj4r^tIq=!SlUfvO$yU&)ZAc}> zykq>LIwFcv<}0{@+{wN2&qsr zD%F|R7) zZjK2x#Vv?5m0Y84=oITjR-wn(R5>KR*X7YBU0wv*cy>qNQ!IaCE!)ryqoj+r#Vw$$ zM=Wt+(?sUNhSIvcW5prm(r!_q^wK%vGszSr){C7UFOueZb)+|%PeSEp{xJG7SuZ_U>&nt6Rp5u`fV@Kxng}+&kL)&bs6Jqf;n|kRU?KNdn#i>t_ab?IX zGvr=B@ZYUVIj6k86<|ezRWN05vQMmM?c(US*2StYSh1?UQ&vGcM+{UA zWERec2b ztxE9g$;R8rMg4;|a%m$MubRctIlEm&myuqJvD(;>?L|9EKdQHE81J+H&nG)@ls{#6fd7={ z9Je~IyQjmdFwcM8%&gj_W__b$W z@O=k*cJ3Biwd*e$c^NyOd+Mf^MO!Ix#rjPaa3OdeN7X^F}RalJ%qh_y!;eF-UCv47`u4An|AZNGrVG44}H z=whUK!Sr($q3=?B6U-1Vdz5mG8C;LY*TwYUth3u$oOb5ND`;(=301qQAMKQ&wScX2 z=-I`UQCE+uF4{Bc!HW_4o#T$4&atK*##WX!Jqom*Lk2CeE*=jw2C7J^d`_um;ZkR` zm>) z7RQ{o*5MeDkVrOAG$B3_#hJeixe_2ug!r9m_G?`|N&Z z#*y`%6>6^aIU%K1e9qr*oBDHaZ(qm#y4kt9<&70~KP7K`3FzH2O;)kU_v#fg*6*6v z1}r-|&S;tS@tJ0eqQ;7vp{VsWJf0v^B*+>(LpkO}FA--~IbnT_>*d$RY@}b=@p~|1 zOqOiz|JLbTC6>|GR#~n7>*`jUD!#T~egADfBh=#|)Os_kNvznTcT z>Vtpb{I=fJe8g4r)IY(OSF)n&q~FmBX0EmA_3wOGJ0K?2bJTt;>1J$Jp*1b!-a?pmCAI-Gf2zT6x~&J-6P`WBsUVp%6(UC!RE?|O0|e{&p; z+?1Kyn7|B7!glu|-n<{8E*)r%I>6m~`HbIvu#gkftOsa4mM`dSm5Mn=@|~Cap8!g! g*G-5Bl+O2XR&Vs%nPZ6C%rsVEscIoN@>*WWUu4+ilK=n! literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/c.tf new file mode 100644 index 000000000..bdb91da58 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/c.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_backup_plan_iam_binding" "c" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.backupViewer" + + members = [ + "group:backup-admins@yourdomain.com", # SECURE: Specific group + "user:admin@yourdomain.com" # SECURE: Individual user + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/nc.tf new file mode 100644 index 000000000..1be59a970 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/nc.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_backup_plan_iam_binding" "nc" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.backupAdmin" + + members = [ + "domain:yourdomain.com" # SECURITY RISK: Entire domain has access! + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..fa8da6191fcbcd394d355a698a053574abad3534 GIT binary patch literal 8180 zcmeHM+in^$5S`~r{Ry745a=ZpPwgM{q3T1UXhm5rX<$LSkTk0D>ut}OS!ZpoOWG!= zSs_@ww#Q@7_{{P6*Uul)kfF>Zld1G%A+cP`0Hs_m@is+m7vHutrGw`Qz6-6-(AxFe z-lr|E(6e3iyhfi4a(nVsCXkZjeOIW#Ncu9z*mKm+?C`H>u=jo)DdT{iauEJEME>%ybM~0p` z-Y=nLU;ne_TxZaO%mnY*!sKyQlr~ZsF`iebjWPEgdS5{bXB?KCjIHae{IR z2~G4gE0}(6MQFPe-w{SgiWUpG#R#s&-`Ba-lsYsO>|hU)Ml+S?Eq5qDMz4(=!&T1vOsW`#tA9g{5s@na|KW=xy|ZZr}wG zq$Oxii|6tlt79IQ;K|wXJ^g?sn>%%(?5@{yUq72&XuWXvQMksnoB=r2UxW zV@!7s^3({j$~68AK|b80{$t{YVTMBvB4EgIVvVcBVsZv7)HPIr((se%P_i?SlJe2heb1GpAuFkMv zTK_gDW>LX>tIlXzuGM9Xwq;k1iH7#u&hLGHh&8u+3+r+}uiJbe-_@fmJM8mw`r0P` zT(Sh7+R5`RH}A4XHd1wtZ98+FSyUP4T<7$(*-F#jw@nqz-9C1BO@uuJt)DKZY4csr zYI4>*%?$=0t)%NwB}%PkLv1$ubM$OSZR+f$?eASo z_IcsYVVtu@i}LpL_|YQdwAHcVLfPg+Z!sn@c$G{p@ZA;uD<_*)|Ne(>%G=3^s+m0O7Zg=-1U^sTPn-v Vh4pre%6n3~3HI|7ck)tR$Zv8fzij{j literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/c.tf new file mode 100644 index 000000000..a8a043745 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/c.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_backup_plan_iam_binding" "c" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.backupViewer" + + members = [ + "serviceAccount:backup-sa@fluent-coder-468700-h4.iam.gserviceaccount.com", # SECURE: Same project SA + "serviceAccount:dr-backup@fluent-coder-468700-h4-dr.iam.gserviceaccount.com" # SECURE: Approved DR project + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/nc.tf new file mode 100644 index 000000000..b262be701 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/nc.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_backup_plan_iam_binding" "nc" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.backupAdmin" + + members = [ + "serviceAccount:random-sa@external-project-12345.iam.gserviceaccount.com", # SECURITY RISK: External SA! + "serviceAccount:unknown@suspicious-proj.iam.gserviceaccount.com" # SECURITY RISK: Unknown project! + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..7820e34378d7baa328d07433d69365c3d556efd1 GIT binary patch literal 9422 zcmeHN+fExX5S`~r{fRuY38WM%p2{Eeq3S~;v`TY>lI%v=gceo&dfRh68NAM|yMY2# zEff;3?eTanXU60G_49``WGK1JWFlReODZ=qK&y}|Jk8L1hR=~SrH$_ceCDoyhS4@} z` zf|0rO9Z!iI%Za>`Q#r(6B9~}4?p(7zT2l!^?Y#k+(}{Ls4g6z#>WgZ z3p`(d%bxqqo{rl=7c~2L&JjwFyCSubqmknK8oep@-o@-|P~nclmhqT6DNS7e6*%sr zoq<9VGgS-9pGkze%kUXth5mBHTyC*~jd*-sln<^txnIS&Q$5~*Yt>BZxbx#ErxAJ! z$a)4ooA{>Hm946Y{#;tnVi)5s(W0hj*i#F0y=0Y-0=<`@K}l?~$3tfW-jck|NmV60 zcPpyRcjUs&7^Albn&rL*+KVOcv>{q_f;KHe z_)kt2;AIZ0D%%BVcjZ0&O}(Is-BWthOcSySSEBX#m1t2p#+ej%@kIMh0?z93lsFHm z&zWi>w6qW@3fM#)>9iopP_Lv=RjaK)1|L9+-bV_`RewcF37+d1m2$}YKA1*4BUTYb zb-uO8g(6Maf|>!xpI{pU`R448_(*EB5$@s2Svq3?y=WaFcYDhwOCLHaq<;V%ks^Oz zEOD9W|5VtS!PZp+FB3gIe-S?)il2-mM0H}D;pafU!@7xZ#F8@g(huB|~c&g7q#L3m%?_oH34*QuvGt3B{6D18RiTPm$ zn!<9JA2Bzyd^+Z%KF>6~e|kJE>xB_o;~Y;ldaly^vjfZOIju6oWGq)7X0E8GD~<0N zuwjfp+B45xieg50cT8T*bTnV6n(J7+j2SFXlQDyRxf!hYi`1Q>e59@BCj)pDPtY9A zQz`2W^f#ViSD)3(b4jJ_(W%RT!)%)?`0P0J^KIjaDZ72Y9-mq%i5a<%AJ3VQ#|RR0 zc%lL;m*uKxtaa3>b*$&`F;4i(zEwHv#|h0-HTnz@BS(mr^jFJoX}OFf>zQ|Xj*SZI zxjHkf_k|-EABW4F`0v)1?e>5+7jFji&cdph+ioc|M-271{Ulblht%DX+(Ns=y>*?l zfvX_lSc{KU{{eKe`96YG z5Bho8j;cu6Fvo5Y|DAZL`wgSLAtY^nh!4M+mHKK=!`10$?xtt+EviY<;-=A5&)ek} zHe;V#1>Mb`@8vj-dX2XLibcE591$!14e9@RI*6F)-wS#9m>8Zusw3isi+uaOFT-~( zSW9BfSf#~mx%#^U`p%4HzRc*E?`WKuApcUFYU3T7Hg3xF)+|BmR6gPc?GU+J8}H$q z;n#_L#%Qf(O)+zfcRlRwA5tmT*@$hV&O2?bg@^r&eT+xcx>n?Tz3fh2%PaW}g4Lk_ literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/c.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/config.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/nc.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..7c34a2c49c050f92155bc6e4744f341e89352ed6 GIT binary patch literal 424 zcma)&!3x4K5JcxJ_!FL0+KLK(hbJ#mZ7V`sC5?hee_eeWwR#aGB-zbmc4zi}yK109 z2RT(r<+avXIa#AUuQlj`9c!$Fd&u?ycl>_yesf|?V8$=zQ6;RJl`9LKQeIAE4L=q# zEsm~-prhi>Kuho^+Nuo-wn15e!X3CN@n35Htzw)i^!8M!bPQbv_>9<7jnJKNMw)9$ z9HB7LjB`S^;%>Z_** DBO^&T literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam/members/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/members/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/members/c.tf new file mode 100644 index 000000000..98b666ad5 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/members/c.tf @@ -0,0 +1,8 @@ +resource "google_gke_backup_backup_plan_iam_member" "c" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.backupViewer" + member = "serviceAccount:backup-monitor@fluent-coder-468700-h4.iam.gserviceaccount.com" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/members/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/members/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/members/nc.tf new file mode 100644 index 000000000..2edb0f7c6 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/members/nc.tf @@ -0,0 +1,8 @@ +resource "google_gke_backup_backup_plan_iam_member" "nc" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.backupAdmin" + member = "allUsers" # CRITICAL SECURITY RISK: Public access! +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/members/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..ed1c288df5f265ad3bb5847e8bc07ee6d8d1a366 GIT binary patch literal 7874 zcmeHM+j0^?5bbBH{0W`~0$#B4Wd6Vh^}!Uih1?Ru?ouqEDJ#FOo-=1ByF&mMD@Kf4 zDFU-I(|e|;yXSPzkMG~CVG~PjVX+NtX_2jMj8;`|tJ;$s8R+M1u$gR^$EpYJdsnbI2q^=xJk7I$E z8J@3za_D}u=iIGe0GT5^=LpH;swi#hWJLJBLT`k%4>0=*Qn=!<^nphF>5gk|m1|BCrsABolA@`>RjfL-|{T1(|RizlWZBIjg%%J^45VV0d)F35P z)n7Z%#aqatl~aOHjiC2XTi$!Lk`TLee+YU>VMJi8(tO_{3i)#xK`X%X0s0@?7q{Dt zLX1J&2d+W(#z;$hy&H#i+ohrzW9Gv|oCMY(O&nv)DbUqXXMfb8jm_+R9tju$X^&w9 z4?U*#_Cvh=45vs8zb0e4Phaof@|R8a5y3NgJ|>7no=eqS_=xC|T6w1#OKg+%lZDCHF zF@e09>kB<(*ZBPy$*uTq`RqgFa|M5?*_F?f6?q?{i|8L)*GVtafq4H1Rs8rGZp!6!`07N8{c(@ zzzllxEUBi+L(ZGcYM&i685lvmqV>POdNVJ5_N}X(}js*0R?g}+ BgoywE literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/c.tf new file mode 100644 index 000000000..3cb319902 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/c.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_backup_plan_iam_binding" "c" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.backupViewer" + + members = [ + "serviceAccount:backup-sa@fluent-coder-468700-h4.iam.gserviceaccount.com", + "group:backup-viewers@yourdomain.com" + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/nc.tf new file mode 100644 index 000000000..a94ead370 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/nc.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_backup_plan_iam_binding" "nc" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.backupAdmin" + + members = [ + "projectOwner:fluent-coder-468700-h4", # SECURITY RISK: All project owners! + "projectEditor:fluent-coder-468700-h4" # SECURITY RISK: All project editors! + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..f9c0eced0b27f0d0894e71e145a354a9ff17e004 GIT binary patch literal 8816 zcmeHNO>f#j5S??S{t3?EvmdE)N)A1@hpLC7$f7t98Vr$b(neMOdfWGQn5;J#Vn~_~ z#X?}#yE{9(GxPTC*nj{0mWGUEE~z9kkX$0UkQ0ww1?=ppy4EGO&8jNKq=NS7O^>g`wx*^7~TK1dD0(VuL(Xuo{ znd7Krcjh&1L*E7^cnEL>|&me^}4ojwE00h5EU)VZ{O3ouWibr?xc5=$A+MW$gm(@)hYBBpf1kHKMA-5G_F~ zx1e+8w6c-t$$liSldfIp8)0l`u;Mm4w4rZk2}-DHhjy^SpCOC!LJ6u>4Eq%$v5EWI zM%OpgeHRoW0@2>YJ?(ELYN6Or)SwmU^R?g+L^MjHB{+wP^G%{Q{eBhGHv4y(Z;qT4 z%HM;HD3SkZ0>fyYMy<9IN(W8Tlkn#X#?e@q_x5->l+z?%7%XG@;@DSegs)>!Sc$d*yt z9;=nz=?*Z$J~hUk#Y~~GLfiLN`D(F`wF+~G$}z)CRoH@i)M&{h|8E}CGSy@VbrxFl zQ&~6{Bqn?Gy28z2bn|J`M~oO=0bSB)aNOd zlcNXnBvLhZtf%MIc&Rc@A0vgi+Q-idGm`Er>&??W3BrZ)nXJ7@!~7)+PSw`x%r{ g%n%V@D4owRHSZeMbN}Ip85%WsQOS8ttbRS0}EOpZB*sg+n(dIuGis`4Q)xP ztPm_-+vBlk=Jj~fM%K4E#-5{oW?xX($2h*0{U)};TWK>aN*UTD zXgRZi(V`w}; zIfH~IdddpY&#wq=m*G3Y2!o=<(ylRrZ}Inakscg%`g;_wo$Po8t!0_iX&2gYokpl# zV6AiL*~F7xSN5tV>Sxx16?7O1^|46ei`e>`?R5IiZ^oKm&I zOE;o?zH4W$#{{)~$Sl`2P+k?f(}(EM3Ci@0rPG2MFMsZ-M(^>`0i^lnO!Rs+nf95;zu8Me`y#JcZ;8N>@(hwH8WzCCZhvGme)1lsM5n>=agq)`45Y($Cte^%fg(e+T+l)*D) zfyaqXLBATG?#8EpEJS4@BvD8EEq7kN@taEA##^igtqF)}ZA_r7#{x7VIob-(v}M$M9*I!g+Em%kIh& zkgV@1Aauts5`{oFmhRwILAW-U1xOVK7L1vb5UYp zaV{lp!POZSTbxa5=^tIhk!YEPf?@e$&g8XYcYm-(#PQ zsAh9_&YtaP*E)l#Sl`8EpDGsZpPiH!))>MFdw2|qS#5QMICFe+-@9erPx8#p+?Q^g z$XC8Gc9J`xW5WFd1I%zJ;8nSiJc;Q-o`UQ>8*Xh|2DY7DelPm+qO?=t*pV^ o-Dq7yFWr<=N;#jwSoimV%IU@R+zW`$w5l>6Aun-b&+VE00v2t-BLDyZ literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_channel/description/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_channel/description/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/description/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_channel/description/c.tf b/inputs/gcp/backup_for_gke/restore_channel/description/c.tf new file mode 100644 index 000000000..fa25544e0 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/description/c.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_restore_channel" "c" { + name = "prod-restore-channel" + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" + description = "Production restore channel for GKE disaster recovery. Restores to same project with CMEK encryption. Approved by Security Team on 2024-01-15." # SECURE: Detailed description +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/description/config.tf b/inputs/gcp/backup_for_gke/restore_channel/description/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/description/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/description/nc.tf b/inputs/gcp/backup_for_gke/restore_channel/description/nc.tf new file mode 100644 index 000000000..1ebcdfed9 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/description/nc.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_restore_channel" "nc" { + name = "restore-channel" + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" + # SECURITY RISK: No description for audit trail! +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/description/plan.json b/inputs/gcp/backup_for_gke/restore_channel/description/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4fc4f1be47c07fd363f6eea29604fa59fb091a GIT binary patch literal 8928 zcmeHN-ER^>5T9og|A!0DLJPKj@Methp)qOHCk?q!zFG?h;h>e6{_E=Rx5Kb|+T%UGr|lD5nwmMiJuEtLzjCg^SAUzeIRaDRsX%=J$( z+TiYnsmpUf)|Zf1fSCesTh3$%EGgQXLJkJfkqKx|&_9-M=<9%v^%8C67wsIO_&6(K8#o*>?w9C|G50p0FM)+KR)`tK@hL{n`HIUS zWY+=b%8N?m0~IPimOifUU|2|XF@Q9X%z1^R>#dxG8}e&l8d33Y;b ztM_SRgxWRz2fbMp@AL}P6=lm_^Lg3zqcZ9OB5PyxV&S@1>1QRX)VG)Ex`cKuQ|gWu ztuj%qnOs%sDS8v99k1uSwOh;{6lbw{ayQ_3?mD~j*<7Kj!Ts>so*(lN|F+*YTjClm zJ=DW`sM0SzreA8UqE*#{k2QT{$e2%kY8iP>5g%lCSjz2TBTw6zDR+xM7{OaKWV)!J zjno+@ab(NI5R5JKoTSj9@8StccP+zP#;RqkTE?p3De>`RRliDO#P|tL?g=8>Yh1Id zmj2+rQ&Nn6p4FRJ^Lhp;e&W#xw+Bd``ETRM!&@{OCJ*y9&Xiv0yJGA)w_|ql(FaF7 znf08v3uTo*o^kiCqWUtf|9f%$e(Z|jZd#rM%98*yZbh;_n==%lCo8=^^Jtc-**~wZ zkv8+K3HGB4?2ydR`+Oxi=DxF@{Rm-fl;sv#p|G~>86!J_J7^yinKj()X~ZfSWtGBb z<2BEg)sJQ0?$>wh>M;wa<7}-)arWf9vly-DXdc;Tpzl7Z(bCkem{;=p-_qP#tN!`=5 zl6>rH$PHW%lkqTIZ* zv$L~vpZ)vix3z3&Q=8kwy0);yu5EySxsCBO!)OQZV>_@De80nc5yt0$_IdZuIkr>G zJYLSc#+*6ucI}&`z>?#6$4J4*dN#w_GmKB|JH~og$45CYwJSUoHN)k<3@~j#POTqk zYTJAJXrJuNj__*R1^&0}7BA90!>lfLlmWIM_UTw79bA1HxG)J=uL7M;#~d?rJih{! zz3`hOU&9W%z}d%hLI@vsMQo#hBfO#?yx#FI;U%#r8u7iY9bu>GQwyMUd}<+0lq0! zMX5Om5_TB&o8xngy^;$vJH*_`Inj{^&J2Q-u9LT;z@;cD@k~h}XH)WKpd-q4hBHX< zB7X(NQSR8G)=4BKsVJp6=-o^rx!wSChWMnMkAu!7poE$+z;~pcJegp{6i_^K%AK@; zJpO?lj6qG5f_|XB8}x$sD2-#RMDE6Y2}6!~Sr~U3#Opqw^DtMZ)($I>64{2EB?aOs z=Mr~{r`j2*>KR?W|;fKca(3PZJ-+D0a8;!S1}DYZ!fO3f-&54^Of1SMc!r zZ{@eg-IuXpo7k%JyG)7ESuxLvSqbwE+21DXnIl^(M=j*rcC#LjbI5l_H1Z}f0`{|D zY|Ygf;S=&aMB>aPl%s2QQKOl?OFA5HlP5KKQj;e!FWi2f>JjC(z3BdX(58N&O!PVG z7mvpn(dsA2!!y)kGDLPi@mcl)#Pm=dEWtSIjve?A)lgLVsZ-OEE(|b}^~+Tp>+nV? z_qv#H)QxUP8|!3ciiM--BNN0n)rwdLo|2g)$B3!O!}aj=($Ae~ayLz`$@*Utl~H?H zAAR}i_4e|oRU1%@Wt;4@Y6&;1e7{!DQRU0JYOXxNK6{9|`%u;KJoqU_URmh;jNtv) zd2_qqzP?(eE6#B!*I{;S{aHEhEkn>p4zVITYrD0@s<5`Ox29{WzIF=UlmF%O@hb7d z=beQ9wD*r;W1I9(8Kp?h*wJB6Q@0MhT2C2!dXH5)z3MgUtnDyO z*VRv9wd?A7x6bc6_t;my|8(nDj&+Vjd9JrYJo$PZM6DwYS-pS4${Kt1{8k4(*4=cc zCNni{+tKzC!O5-LwOxJCuVPI_F_Qw7J-Gw(# literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_channel/location/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_channel/location/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/location/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_channel/location/c.tf b/inputs/gcp/backup_for_gke/restore_channel/location/c.tf new file mode 100644 index 000000000..95138a194 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/location/c.tf @@ -0,0 +1,6 @@ +resource "google_gke_backup_restore_channel" "c" { + name = "compliant-restore-channel" + location = "australia-southeast1" # SECURE: Data residency compliant + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/location/config.tf b/inputs/gcp/backup_for_gke/restore_channel/location/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/location/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/location/nc.tf b/inputs/gcp/backup_for_gke/restore_channel/location/nc.tf new file mode 100644 index 000000000..4de2d97fa --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/location/nc.tf @@ -0,0 +1,6 @@ +resource "google_gke_backup_restore_channel" "nc" { + name = "non-compliant-restore-channel" + location = "us-central1" # SECURITY RISK: Outside approved region! + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/location/plan.json b/inputs/gcp/backup_for_gke/restore_channel/location/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..58e98d17fb2ac36b116c6f1467b12dc99a7d203c GIT binary patch literal 8078 zcmeHMZExB@4EEx8OTavxswEMxlA#dVz!5GM=qp`=R15?I-ddB@%H0%RS19J~CkD7+-_Sq5kL0 zSKYw?G)EXGgwf-!NNu7tVmxm#8)NSSVBdlYcWf9d!0}&)m*5B zUFv>w{7$h~N?|FNzzvc!K5~^zqE=dEZ*7%Qu#})va!71i-V%HSyH25l89tP+L2;Hl zcBm?gq$L%tGzY&gvq-L&0B4L}+WAy{E(Ry`j0DfXy-OmhkYKdognDp)HG81XQu5|A zX8+sNi@Tpe-owJa&CdqFHx1HL=(iExY5yzeE5SQw-MhCfWdU8$=ZI&XTDEn1Zqe3F z&t=&j;_sC1uC<+7y3``=-=t&ua|xULbIhiyr=amFd#z^~Mzh{N8375;NPDU{l|q~6 z6sZC~O{@wT_4URoMk+=W`WPc0BUW`}O5vmFrfz5=lx4v4h*15|#EQqF zYg2b+s29sw_utoDo}(#uuY*~?dWGb=Xkm=2vvwk6U#lusGj>WaY|n_y(L6s`{&Koa zrDlHERBETJgP*U|f@Q|2byJ+xm@|Ihw`{4T^wen~#yn4FJ@-f!j%DJ)^?}KO6d8(S0TsKuMPu5K)@Qn0-pV^x_ z*!nyB`yfsHe@*efuUUwl!xWimid@O=Z0O*5#@_7$6mcBNyKU@F`&hZcE<-Q_j)-i$#`Jp6A~2(nMcpp$h`aIuo!}0h5#FxlGyb;`ldo`#+{4_J vd;zqbbC-IXbq~Jm_L@}uj*So@#_`l{^+R#q?mz9G*SZ4XB>f<7<&FFWrLnKQ literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_channel/name/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_channel/name/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/name/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_channel/name/c.tf b/inputs/gcp/backup_for_gke/restore_channel/name/c.tf new file mode 100644 index 000000000..fb6bd79a5 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/name/c.tf @@ -0,0 +1,7 @@ +resource "google_gke_backup_restore_channel" "c" { + name = "prod-restore-channel-ausoutheast1" # SECURE: Follows naming convention + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" + description = "Production restore channel for Australia Southeast 1" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/name/config.tf b/inputs/gcp/backup_for_gke/restore_channel/name/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/name/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/name/nc.tf b/inputs/gcp/backup_for_gke/restore_channel/name/nc.tf new file mode 100644 index 000000000..90c24ef38 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_channel/name/nc.tf @@ -0,0 +1,6 @@ +resource "google_gke_backup_restore_channel" "nc" { + name = "test123" # SECURITY RISK: Non-descriptive name! + location = "australia-southeast1" + project = var.gcp_project + destination_project = "projects/fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/name/plan.json b/inputs/gcp/backup_for_gke/restore_channel/name/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..f99bba9140e5f8b57994c02199b4a850bec42d00 GIT binary patch literal 8424 zcmeHN+iu!G5S`~r{RhNzO(02|insnjr1q&*WI5cD#u$VlZB*sg+n%$-uxl{IC?TS) z6@ks}&SmGmv-$P&hcsm<6Pd|a5}8XZ_cFk*Ty8O%VYZ7;M_O`<=No+HZhnT<2Dcri zBWHl@EFtd!GXvg4t|bMQ9OGRf2P5gp6tt(9pU79t^+3mF375(Oqsq;2`76Vk2rDPj zcRWRMF7M>MTu2*#k=)>SQy%e0zNdgnu%irX`);3x)$>8>6DNhS!@6*M8Xq%2<``dq z%bt7Z%on$V1UUN`=L*HgT@l;J;fV3P!)%PbCxE^K7VcOf=2*wK7&A93E>p;^2hPd8 z@?#R9t}=W^faxz+%;fSl08V#EOQKyj|Z${9ZJ>cm03Nl zHS~lWGTG1SX)^=B4DqddqhH6)2d?p!f;Y2klXe82*0mHZIiapCCaBFZE>OGbm+E8m zun>EO*%W`|CWT~r!M@d(lMNY0ptCMRiy%d7R2lW*=|zn(CWKxTfhsk%4Qo->%GdtV z-jv;;rA-T>&*{EYpC)nDM~>Od>5XgE0?K@(nx!btYWrl=<$6ZH(yRNV`zHatacAxaa z$W=#qcB-u7aePr;D_C|rGvuFJWJI1ud`FNRGtX>x5keSSW!*b=)NQO-yBAk5V-7)) zeYwL{`PO-_yXwAsykA#6)OYOe4<4M3i+2l(b0FWH#qbnsomxFZ(U!KKfH)r97 zXe0lkKdpCYkHa^v+&NYKZU38eMpd48nf>*Cowb18tyjNIx4dpuspgF_vXAD9Q{29v z%3IvavAZ4N*M)q-dmEYL9M3M^+VUBzS&JlqD%I6^`}*i}QMC RsW<3aLHkqvqr8?^@*89Q?YaN} literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/c.tf b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/c.tf new file mode 100644 index 000000000..030e7fb20 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/c.tf @@ -0,0 +1,23 @@ +resource "google_gke_backup_restore_plan" "c" { + name = "selective-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + # REMOVE this line: all_namespaces = false + # Just use selected_namespaces - this implies NOT all_namespaces + selected_namespaces { + namespaces = ["production", "critical-apps"] + } + + transformation_rules { + description = "Security policy for restore" + field_actions { + op = "REMOVE" + path = "/spec/serviceAccountName" + } + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/config.tf b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/nc.tf new file mode 100644 index 000000000..642884be8 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/nc.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "overpermissive-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + all_namespaces = true # SECURITY RISK: Restoring everything! + # No transformation rules - keeping original service accounts + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/plan.json b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..91d611d93c80e215c42cd6186cac33eedc40cc48 GIT binary patch literal 17512 zcmeHP$!=mt6us+6`3H-2@Q|cCiFa9KnL+6&i&z$-&0xnEEC#2osDC}lId!5M$vM}&!y7N?3{QJ+}*07$9Y-~5ywyCx3&bs(Eu`4_sqV*K76Famo@%{x~)6hOf zZy&dO%!z%4ktg$!cNjCqyls1H1I#kP^HU=PeY>z*tbL32k^PCb3#{X<95=8To(h`Y z{M!(Hn&>&QPJpRtU)yW@*1oZ0{59`P5O40lKT*3C;E4SQe;=(A z&~FTg4)IP&N+snmNYxQI(?-8bd?WY9fc^+$Beev_1g)2tgE&7XW5A~jL=G?>`TBWhbYG+ZxaTT9rBfS;P!!r#AFD}2Kb|{cEOV#{?iIv1&h=Q zw0etY1B_>X*$v4|6aA{PM%q!IDY0(Nq%*W=lu=m}SqExeI(rIDmE)p&U7kOtQexRw_GV&qn_XL!r%_4kNPUSpydlqeE zT!VT+e$vK`Fh9TDZ!upL2TIcjbISgm+4)?8-r+g5g%U@5?^dmfjgMGt=P0d~;!|Be zwa=;43<1^hRnwl;8EFw^V@Yj?FO?Z#)CShHZKPysk5-Rb#8X@q@0YjIgHoS5psDmy z@d5Q!`b=FVBm-D6!N!@-;eW*w>Kwh-1QHh`4p~uBTHZE=X1TR!*c97 zkdA42Dse`s4zZj;LL&$&&LHz1EFr<5%B zKam?6K^dv%r!;4k(vRET_4c$n&#vrWb>5e0g?f-$MgUz{`S>}?`Q|oey)AGZ5`|J< zuxpLmm9{YFq0~`Ecb}OIVXjrr) zMUT5Y-bmxMdR9N?|NEAmFlS;6!H9)*A?8o?g?zeCd5Y(FicnK-d)$-Sa`(q2Pg$1h zy_5)Hn`}a3wuxZV*jrIKvy9Cm>0SBtUD}iq1*dZES@x$X$!kufe!lAnmDO{nHLaMkfyHWv>Nj2VWiHN&4ecDOp{moUvX(|b-1~`j2F{yS zt>Z3+V(+|mSt{<;dh%vF2zlIED(uO^S?y0 zao4C++;5Smm5Mtn@}=UwUlsQlQMAHd$Tecbk^P1L9=X)3x+w1C83m3@D*)BV-t+x@ z?{mF%tG@7-jd>0__IbBEsJRkvJ{^*oKuTUe*M zTSeKAyCaO|Q~i3pf7#D^j$QSXOYt)^Xk}p^yFS&`22~cyj@E}fZ&&IC<%C|@15>@A z?18aTvidyG^To_YdF261r)8u2<-UTV)2>`#D6VFsH-$|z2NS0(_d19XT!g#7N-VWT?-DX83xs`NndFfc^ zP_N#T7M|5T@cNk6zjvjTQVFgnL7VLrYn5E;92;6D-ecoC&nm|=FS^|^#x2QZcVAfp zq_$MOSJj%zyQVO&yYECQI8|Z>6*X|3w4GtR@ZIJvkb9ENE1Szt=hoxv8_<878$;s5 z`g;Nm)cbWKs2)7|ts$2qdQ{ytsyEB#JDv1!lrDc!%D9WQ`mQbEBSfF-eS%c)iigwv z_04WDOTu$s;g)ip&2fw4zYXxzr^s@s_ua#7TitXU#ha1N3FqL``8vjXtL`V)v75dl z>$b424LlD%nK9=!zhprV#$7(;IYsVJ5s@y;3xMGxt3W{8Gm;UaxRh z;{@+beEZIR!{-y^Ua#=$7^nDEj$``+GjJBaMSPD>`dtok)ak<>)J@LL^K&{Onzt*9 TWLC|{gQMe4=6n0xKC}M-nyH&1 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/cluster/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster/c.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster/c.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster/config.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster/nc.tf new file mode 100644 index 000000000..5cc2dea46 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster/nc.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "insecure-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/external-project/locations/us-central1/clusters/external-cluster" # SECURITY RISK: External cluster! + + restore_config { + all_namespaces = true # SECURITY RISK: Restore everything + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster/plan.json b/inputs/gcp/backup_for_gke/restore_plan/cluster/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..a5565c40c6dead833a5d24345e9a9596dbfb9d6f GIT binary patch literal 8286 zcmeHM$xa(V5Uq2h`~>G1W3s|mzFF z-L?1Y>Z%{#zuBG*ZDw;jx2`R%uuB`@X<=jhJH_ZR-W}VwLwvu$dl|;(nC@s1JzZK)8&|B&N8Nb3;97+HDmR^)Z{<(w?W$_|N5@%9}5k?oV;T$sUrHWX5G)iUB>FP9v)fe>l*icuoOg+- zHheULT--0(C8W@WN2NF8ic#LeGoxi0G@!Oi?1gp~0q;wHlY*q`V_hnH>oz82kselv z6D_+rOrgUB zFUI!()*s@Ndwv}7r@#nNVu0`HQIC#RsaYCTt{-F5u}k}d_(ffWAHsqv^;DXwZ)M@S z-rcl+#<1oh=ttxjz{2^iuX;H5l=$xwpOPWxQNX&y^C9dr3Q^;@MK8pCynvsGPma!R zIr=I0uwz%m!^ng2Pj3>>W}wff>%cX&^!@azIxv=Ipedv~u}@|ET$Qph-iYmvUsY{< z#ril`iCd~qm4AxFsU}lMwVi7^vr3W3CoH9(T|Pz&Pe|HO8g-#HF^rZ>ap&$;>w0Q8 zIUntDMyH?Ukv8q2^Dkd>89cfQ=R*P6xq{eS)$A_MKZFKPPVS_B_#BnEKuvDSI9NYx zo*GApS3LcM^0JeATS!As(!OI@$+2zIX;lvcMYC$@%{%+g?XIeP|3{2JR(vvFWkmCn zs4HuxsKktjIUqAY-ID!<~I^WOp~=XS!;m|MHLdpM2bF5 z*4kvP%kuQ{xKPd!&!qzBIz_dLvGNt4eopO@ud-Uib?IHQnjJzwvZrZ`;T&XmWF{!eqN0(`1>EJoW9aqN+yozY*bENfc-6Y&{q?Gpz zRL2{JDok3V)6B=c=fvA)(*dE!bFbXh0ZIK_gdUG7otu2gsyQQtNbgl@-5wbo+wXoH z6(6B2tMlxJ5aD89>|ebf3e)p?mG7&EXuaN>$Sw2qy$@-$sgqF8llAXy;*>^fJr29{ zB*Y`Pq5Fri%-#*Zxl3Y2YA?j+96i8o-CfqWVudUAK+_#XKJ_{kb@cW;glOm7@9!{r zeVP01A^mIC_nD2bny#)kd+yq~^?TTk&|Y&E5}X51bRHa{=Y43e(Ov4`yM?DC`w)H~ xhkiIekL)96tMa6N!ZqYlH=b17K7QtrI{Of+XXWGS>#A?994%&CH}>3~*-x$^_zwU8 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/c.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/c.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/config.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/nc.tf new file mode 100644 index 000000000..5fb740f41 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/nc.tf @@ -0,0 +1,17 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "full-cluster-restore" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + selected_namespaces { + namespaces = ["production"] + } + + cluster_resource_restore_scope { + all_group_kinds = true # SECURITY RISK: Restores ALL cluster resources including RBAC! + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/plan.json b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..7e0ed57e773de209ebe2b16bcc1fa8ff814f7920 GIT binary patch literal 9526 zcmeHN+fExv5UuBx_9u8=117u6im%8+o`TTGv9Te5jXZ`dTJh`IJ*SV0zIeurSrQRt zgz&AqtLt*Ax~ppb{rZpX+0+)cv>O}Q$|}3Jb9}4q62HzddV>FWqu2;m8S>=A$D`xdK4kZ6v%lOU&4jeKzTMbN@cpn4bh zbUv0?S>yLRa5)a2IdU2#7=h*lzjKD@Q7TfK1sWCJuP|Cc_7PTJfeIzoiWTPZ6Ez?% z_rd2FT$6M0;?mPjbNtURf3lvjvIng68UJTr?MV7JPxK-uvd=wiD2-QvlQ@$y%rII* zhfDCZk9VReMazCb)&Z7dD(F@R^)J-@$3>u0EiMGu3?0OY~ za-7xJc^6C_z(x!3MSqc(kirNSmE6P?Q9i(TqGc5%ptLLa!a;_B_iKBTg1DMsUCR65 z2@}%D7%Q|BHTxFi$vMg;$;TuCu|vBu7TiARkdn+H*){%%`g7Q1idRO0%Mg{SpsP># z?HcPjU$H}&8DL(CHR_H&O~iUclh-h+5u=JKiV*a?lzPfdX>sYjtIeCdYPyz{5iGUn z09;W&9uu@SN33?=1+$`(Q?9TxWBe4_nFW1%ETavgZ`aTwV-~q8t(5cb@hry3xCecL zwq%T3fIh!HyntRQ1Cg`BJCA+oFi^Y2DiPC_BUwI21F*$hW2%*b{5b% z$DZ5frP!%KmFFF$??V4^y~nwge0f|hEfTp>+>YavMjA_PQtB{0VN%W|W!tXl%#tD_ zy3Pn9#`)XS#0ZvSY$h7gc)ER68%MH!`zUV#j0Y3gT5&~poHN`JWLM&X=W7kGh_@m| zd1_KO0%6Fdy2nhShv#4g+LVK*RjHG0xPJ)^-X(--zRuRjCRb6KG9rHK7|K{pJ?Pxa z<;^5)7|!kfBB4BlA!T!FVQ>g#oLg;d`> zKcwpz=iLT-i2dB1ahkUVc@A%Wiut-pq^BEmUEMC7ZhAwHSsO?FjPWeC&o0Wl^KRKv z9<}@ILMJP8V$Uf1?1Gt4pI!9XMVV*y*@bE;KTmcMPwEO8*&KCN=CEJz>L>Ruc?Ij7 zT$ff0${Ti{YcR)P=G*5Qs^G`!*7Lar>wJC>&2bh-R7v1z?;V*GkGhwp751haUpdMh zPRSh6`aQk-Rv|CTGj#eu%-NXjq<*%U(Z9skdcX2|QmKjFuXgvVu3q6;JTaX{a`yOQ zJ<{xRKHhaw?SU1E_R0ZAwU1&y``he!dY@W|$U8wlPIW;iO`grW$Gml^ zbFR17AS7p5^XM*V_nxA5N-^9GK^|+K?>uUU9C0oQ@y-4$-|0EA#<>?TyF~ZD?YRzC zO=Hc}JDsstnD--d?R#G(t+dM5BAuqXJ-vus&GyQB7w!4Yi;?s!$go-4cZoL3&X zL)&PV-A}Pz)@bTrsT%FNr4F_~IpGp8!o1|U9G-!^6|yI$r*-%&5j$Z-MAv6?{7mxB zkz(Hsk>xF+99PFoIgReh@#gzzzuGVMAJNL+7ytkO literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/c.tf b/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/c.tf new file mode 100644 index 000000000..9bd7fa58c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/c.tf @@ -0,0 +1,15 @@ +resource "google_gke_backup_restore_plan" "c" { + name = "safe-conflict-policy" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + # REMOVE: all_namespaces = false + selected_namespaces { + namespaces = ["production"] + } + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" # SECURE: Don't overwrite + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/config.tf b/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/nc.tf new file mode 100644 index 000000000..659f21c99 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/nc.tf @@ -0,0 +1,15 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "dangerous-conflict-policy" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + # REMOVE: all_namespaces = false + selected_namespaces { + namespaces = ["production"] + } + cluster_resource_conflict_policy = "USE_BACKUP_VERSION" # SECURITY RISK: Overwrites! + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/plan.json b/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..a84c7c82e7b5e70654f799102affd8c367bea8da GIT binary patch literal 16802 zcmeHPTW?xN5T55s{S!PF-`X^l-`XmwqDpPlo2ptCB499$4G6HCsPbQL`+fT{-rWP3 zLqZ&ARu*8+-ezX!zB~N;&)?Rto{el`*VeX~wd~d|@NH@XJRPF-6t81DuoHZKhSw~# zPte=PtsZl1pJU|leB>?0OfYZTUfLCAnd14W5rV#TY>c(XXdl_1XzO4dZ{@fvyTMaI z)0=-AqE8b&N7fB6HSG)g(!R2%c7(sCUE+Jg?(j#r#~9THMnm-N20VS%2nSam1u9&J zS#JWI4#xx|r+9t?C_CYQwwwhF+L*J8=j@^Rh!tn+hdEmKe1+B)aBpMuE6hTSHDZQ- z{Erk6ln3Y|dJ7WAox3!|tB>B@d5@XB!8q^nE~{!q&VPMBpTnWOxyAm8+N}Ub>__QF?56N0Pm#l$_)bol1q_Jo403Ro?f#4TUULRP z)y23J_U1i5h$0<~&`PB2F5r_xlw*>&2?O#D_mz5Jd{0ASG6ZH<_@k^|U{88@rxq9l zjnoRXdWmOO7|;IF8{(NJ`c-+2w4*$eV_lm`W~kA~qtYnS4wSld_7s}xj*ISf_k5X5 zO|csBllB@04x}tlpN#=Cd8h*!(%771wfZJJt68d=hLXpX2ar6@>3WQN5M_G`c&M*j zTc>o%_t$k<)Q>HU(;C8u)+NV|JMpXiY|qg0%zn4$`2QEY|6t$Y$!~b}6P`S`AMr$3 ztY5Q=C%J8eb)_HA?0n8)ukoDHM2@6AaIIIx*heh3bCgy~ajveP>hF|#LqN59)wE}I zMrusyVC|bQngS16RdSIqY6ENPKJrqkuO1$?h^ORD{IR-~7MAkX1x+Ql@*mD&e+40B zj@D}mu8SUrv?wVlYwN3N%q@CymuP2Nn45Ue8dPag<*Sr_Z!-t&^Z>AS!+U?ObI1!3 zo2tfn-#UuAkaUn;5uF^*yTH}t0n&E>D!JZVW*_V6SIt?aw99m^H$I$PR^i)C>F9xL zX}K;k4tgAU*cLC-lO|8l@^0VX9YSkJ$EO;z5xhTYoyYTdBP7v-C_Zm)LyFH!kDeBw z_`Hj8j^x;V1$nHr-NPWo^b#1w6z?~Bzu(x`_N{#nZ}d(we@7=p1tnPX7iX z3d#s`2F(7PhZvbzKII>j5%LI{c}HgDJJA z2*sk61j3OUHPxyv{-+JsxMDXgzqFST}ik;cjkvFI+vh8@I*N)l!AiK&G``6;8Ux ztx#jcx`E~Ucww&tm(b($nh2eil7Cj8b+T3KNE@^AiWNCtL8bNf^*mHr!d#;gqkX_S zhx*}DQ{lO+nx!75^($VqQp&;gR;YiPsTFdL^F5(>%GWDxu1pi_+i0{T`Ck%CgnV@Cd`RTJmPEVZG$Rp5S)_PV5OP6OQr8_aoG!9^qF7PVxO| yczM*38A&nbtG26xkhxW_OpaNaJNwi=vHt+$Z4@m4 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/config.tf b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/plan.json b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..4041a310517ef7ceb7f46f1eea3bbd8607b97f05 GIT binary patch literal 878 zcmbW0TTjAJ5QOL1#6QtzE3{rveuq!KkP5V5fHvil5W`B0A*Fbg7)*3*JqLw`51$&zMYCAhRQK2d1TNp(ib< zvgUp$GpICHL+^%ot!H9m`oySl3vIdW*p$c9iky_pT9d#j)wOPQr-AxBsb-uL9eB*U z0ac)AMeZc%j8#uO+`SGiEJM|8;Mwtrb=+@-_BpJ#@U?3vudJq1vE#PmH3}RfCaS7J zuj)gGgt`TDh&n%KSVKw21<&Y9W(%gG-x@Bh_IUn%N|%9U4_6BEW}K{~g>4V4bw@5y z>2Gc%?8*P8X-`V9R?^Mby1M!PeWH=0y|-glZtogg^2X+DK&~6MAmcaXbgu`#`$Tj0 zV#qttBboNK0O$SK^VRL9tC;12%F~czw_M+wYj>Stx4oCH;eU-C^DHJIdcq%ct~0#@ D3+|Y@ literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/field_actions/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/field_actions/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/c.tf b/inputs/gcp/backup_for_gke/restore_plan/field_actions/c.tf new file mode 100644 index 000000000..b4569e6cb --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/field_actions/c.tf @@ -0,0 +1,38 @@ +resource "google_gke_backup_restore_plan" "c" { + name = "secure-field-transformation" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + selected_namespaces { + namespaces = ["production"] + } + + transformation_rules { + description = "Remove service accounts" + field_actions { + op = "REMOVE" + path = "/spec/serviceAccountName" # SECURE: Remove service accounts + } + } + + transformation_rules { + description = "Remove secrets" + field_actions { + op = "REMOVE" + path = "/spec/containers[]/env[]/valueFrom/secretKeyRef" # SECURE: Remove secret references + } + } + + transformation_rules { + description = "Remove privileged mode" + field_actions { + op = "REPLACE" + path = "/spec/containers[]/securityContext/privileged" + value = "false" # SECURE: Disable privileged mode + } + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/config.tf b/inputs/gcp/backup_for_gke/restore_plan/field_actions/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/field_actions/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/plan.json b/inputs/gcp/backup_for_gke/restore_plan/field_actions/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..e5679c0eb9a8f183308f5cc5d5b71be78fbf838a GIT binary patch literal 12746 zcmeI3-%lGy5XbkqQvV0!=Nd!WrWJ2d)xPvs6jgmFicSv3h6Ze88yXblUvK*T?0DF{ zGY5CXRzN*j=O1^wv-5jqXU8A^eII&Z9A;r2&ciS)LlLgRv3@PWsqRko^g!2s*bUG0 z`IW9^d_LD`pI1L;KYXp3`>UB(nll&NVR#eH1ZAQ72LTKw;V4{a?F&7hg}?ReNbC4h z=ADI0-8F2+t6x)%>1*UHj3Q3`@J)Cgz7OApJ-zzjM8A9CgI?f$p;<#wG}YKqq|>1$ zJXn1exo{q#UPe3}kGWwoGIgAtx1#_hPj4*gm1++3CQdt2n(CTp^k_9=8Ll=&N_iyyUIC7*Jwi29u4D^&SDpOK^W)z@1$Q3_ual=C>nToPAy|C3|$z-f| zyufMnNJZq;8{Iq8e8!vKFrDdZTvgZL9rldIx;HbM!K0z0=26T$V0Ah49Gj}djqgom zew$4#B5nAQV@Z504516@gBKRQ(B0&f-4~l5tNKVhxcSFs9uX*2zk?l4BPNr`UH588 zBw6}GJjHvt@6NeYmbQDgC!vh zhd<~Zp5Ogjl^UP1{+wC1T24=O{oGUMluU(H{i^xMDnvBEye&HC_@O<-Pk3k)4MjCx z4o>Et>F!zUbed(E?CYNrOVPoRcxo1EnZj#DTI2a$S_~&GuI8)N`-NV3B`V=9naPeU z153xM(ZijnkI4N}a$QE>fPN>ND&mObt&Jy^_dvyY)I+#-vZjM*lUe(#@MHKj{2u<) zr&%>|(a4xQE98{e}shjslBk*5P(~g69 z;NwTaFY^maapqJ!fOm_i>jQnCibqg6$awXWMj$uiv{Ul4Mqfu=8LuStdAN&h5VMdJ z84(t`6ZIDfneJ>uJ70!h!i(@j1O2S$cZy4=(v53D!?N)*@APh2N|iRFsLX5Zk4y-7 zWZ>o%n(DKSzS7!wZLFmb53x4#K!cKJ%=IzkAu!0$(Zf-EpNIzcqE5$puCeXx1n&hO zETc4xlDEKA~_>}l~zsGRx zY-(i|HJ%RKhkJ!hSu~XdxXgR9k31t}ze@Iw*LS~x)pgYYv~si6ft=TPXybFrN1gvY zWnZjL{2&^c9$C)9y5AEs+T|J>3i62&fso&pr^@QftuCAW2 zUX%X+)Duz;T*S)iTkUFQ;UB$wPTZ!Fz?mWQ{M6;P*ko4Ael$OUDCdJ-{mJ)S)ha+& zU1(o@e>zowZB;F{SzX}l*LR;~8%R$~v&r%8ETufIS;f(+5|^@|vbEX$e8*edQZK|l zQ?07J53U>ERTMwR`CF0_wJ6iv&gS3W@S!%zOLzLh!} z>{K}Ifjw$sk>ySro9U;yRGi@;adwR7_i-6@^(s}aO zsV-xEcSY3btX5!~Q`)?z$yUlWxS0l}6XtfEPqtoJ|C}zgoo+Ecr_$nd_F^3tbM+$D zb(j)Co9{-zzTA1^9H>^|?(U&!!mC4Bq|tj@UCd)f`?z1&3de`d2V_?3+Go)hj->hH`~LrO-^H3)lQbYOJ|#$ z&ns)2(A#?6CvV%PpT}@2$Npy4ly)Z8caL}V3olD;=I)Me_iL>FkpBu`k6=NEq5XrP zZFekM#|wPD@5XYX^Ob+<>Aw(ry1rGv?!G>G-wS`}dagX{nf~)|pldJuB?v(A?#yd_ mvwuDix$;^V5(GN2#ZIZq&xvjHyb$`QI~;fb literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/c.tf b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/c.tf new file mode 100644 index 000000000..bdc2d526e --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/c.tf @@ -0,0 +1,15 @@ +resource "google_gke_backup_restore_plan" "c" { + name = "safe-conflict-handling" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + + selected_namespaces { + namespaces = ["production"] + } + namespaced_resource_restore_mode = "FAIL_ON_CONFLICT" + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/config.tf b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/nc.tf new file mode 100644 index 000000000..84e29a028 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/nc.tf @@ -0,0 +1,15 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "dangerous-conflict-handling" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + #all_namespaces = false + selected_namespaces { + namespaces = ["production"] + } + namespaced_resource_restore_mode = "DELETE_AND_RESTORE" # SECURITY RISK: Deletes existing resources! + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/plan.json b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..8f3c6471cda5ec06d03cbe9823e10e2cbf77dc65 GIT binary patch literal 16802 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 literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/c.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/c.tf new file mode 100644 index 000000000..5ebdc0a09 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/c.tf @@ -0,0 +1,18 @@ +resource "google_gke_backup_restore_plan" "c" { + name = "secure-volume-bindings" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + selected_namespaces { + namespaces = ["production"] + } + + volume_data_restore_policy_bindings { + policy = "NO_VOLUME_DATA_RESTORATION" # SECURE: No volume data for GCE disks + volume_type = "GCE_PERSISTENT_DISK" + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/config.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/nc.tf new file mode 100644 index 000000000..099036100 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/nc.tf @@ -0,0 +1,18 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "reuse-volume-handles" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + selected_namespaces { + namespaces = ["production"] + } + + volume_data_restore_policy_bindings { + policy = "REUSE_VOLUME_HANDLE_FROM_BACKUP" # SECURITY RISK: Reusing volume handles! + volume_type = "GCE_PERSISTENT_DISK" + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/plan.json b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..355c9f59ba342ab999a49a5604b9470868a089bd GIT binary patch literal 17614 zcmeHPS#u*b5bkHH_!EA{Nz6^&U|C>`B}pwC9!RC8ym2lzu~T*uHbv#H1K+359ZBP3 z$D0F(s9Zi~Mr!q??pC+tfByc=<|Zc)E^v$5!l9e1C%X zd3ZiVYwtI^Psct(&(65#CHf2jw`*_g1W-n}zi!0f(Dv*MW1r#q!2ZCqJ&fZ|+3&esaxNg}sUc~zhy}F>NkG8!)r$dc+aP&do z!fAkd5%6?8hUhuM{R?2Z7k=}}PN1L*m_6KQ3&A5*gmxHURQP_2rxj@LqW4=sA;s!( zj&}S-4hYK?v=P6BiPKIg_3=JL>)yDnlrR$)KOU!SqIL#6nctHUE<<o|?Z`ePehDloSI#BM{}{aJh0nu4tE^YuGSY6#DmJr&gi^OQoPB-3ImYZGRc^~D zhd94S;3RF9TkMoKxs2VOMH^Y6pT^+4pgd{gNH4Fh!l;YEtJ6Sj8UUv3-;V8$HRv7g zlRwlr+IzQZb!xoFwh5em!{jtM&RtoHI^5-)vj><<^q2dY20hFy zojt=A*JsA?)C>CjyN|T{uxFaBsV#4XxRdtq;bQHGNsL`ew4Hmm5^ZxWK`&6E?a39^ zv}l{QnyaSCSexrm#@e2ZD3SKONcXOM=VXjoBJH@k+JP^6x{)?x>21WljIi@~`zOTK z8;H7JhG#z@V%|g~UfFlJ{|s^Rwr!2Qc!{}VhNQ&Y6>R)Nu9N>?F*jG9>544%56sTe ze==*(;?C!;KxuiqK( zu#Tg6(&45V=va~9Q};|>pJw)`>^O8MJ=W?!3 zo<&VK^}^RwsC|5mVRee4Wi<>*g*x<6hdhG%u2 z{k*=}yz2Mg*^atRD!Fv+1c~!#_Iyio>C6jy+?Q)Wd?KH~2*h{yq?)2QFx{~+t-7T3 zzy)eOxvuGc8f#V|>z3DssGV_*lt-Ym+B4c+WERvls#K3?gC;BANHkuo^t)DtWeATt`1u zoJX8>%9Pp7=5-R{oS(ySx);l@HsKJl7roO~W}cJH_q#PaLo++SI$6PMg6W4=`Na90 zg7lP3v$30>r15%*#%1+;{s~jIBMwjX)Isq!w>`HjP0Q`JTdigHu{qX{-P_PNG|S3L zX2sKR4+6d8a(SBDX6z*0W%fC{As$iOviSdHum-~{5YOA{Uo;jyD^7{?m1YLD5;#RX zLhIGS|ADOG{RMX5b@1KB)i*e|+QIia{`I4SPu}?*Emh;!9_%aNrGNh*lyvU_Z6TpE Zw$k3!{JGA(GUw)}_+zH)+CH|A>|gdjoy`CM literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/c.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/c.tf new file mode 100644 index 000000000..5660a5b94 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/c.tf @@ -0,0 +1,15 @@ +resource "google_gke_backup_restore_plan" "c" { + name = "controlled-volume-restore" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + # REMOVE: all_namespaces = false + selected_namespaces { + namespaces = ["production"] + } + volume_data_restore_policy = "RESTORE_VOLUME_DATA_FROM_BACKUP" + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/config.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/nc.tf new file mode 100644 index 000000000..c7d53b571 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/nc.tf @@ -0,0 +1,15 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "reuse-volume-restore" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + # REMOVE: all_namespaces = false + selected_namespaces { + namespaces = ["production"] + } + volume_data_restore_policy = "REUSE_VOLUME_HANDLE_FROM_BACKUP" # SECURITY RISK! + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/plan.json b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..c0dc866c97471c6807e280164c5376c0c4017db9 GIT binary patch literal 16922 zcmeHPTTdHD6h6Q9enyI zNZ~y6dKu_+I>u-@!Tn26c@%!Lvorj0tR6!reS8uH zP6HxUK~^tu?+oo(U$`NgX`^1<)+jrUXIiYInZ^tejW#Mo5jt?xrM;)r)HN=-H`V## zF-2@84Wqy_>1u;gUR{Q<*G3s7<;b93a@!Rht5~mk$$PFKWm40JoCZO%j%d_I9OV

iWtx?Wh)!GCqT&gIXohky~C}uhCzf2invKeF_B+>~LmBuW_F;rQH$r9oy>M zc#HXRw$js5e(KLpQ98AqA*fpZ)U;;3N8+N8meO|mCg6i}CuJy(y5O1!M@gorbbG6L zKBZOZet9Y9QCe*eGS%pmmvD$#Rx+nmbB>z8qM~0RtfVA0r~1>>Cbj$ueUlGjeqAPY zn`zmv_PzaPzuU9$tFk}v>#4o4pK-sk@9YW6p5WIHD1U~#m3@QjZ|x`4c@DcH+N|?* z&f}-xvKKxFvoS#}MLE0M(Ov6Az#=AC?$3gu`$)XXX5>$tjT{%nT7>a(t+#b|Oj zLe%@&)QGP4yPe~z4}0g#cAQzz!;GX&*)lzC+5~6j&HKYc;El#>inXoa9TKk|&LfVL zL=U6*#QE$~d}8`;oB@hYJiiXoICd{Xek^gCYn$WZ2?rlZE1~x{Z@PA(r(8VYxcWK3 zT(o_j@C*3D^m}tJ_(yoWzrYuM8p?_%OrO7a!c|zEZQly>|KkaBEtsy6()a-*n_MN+ zYxTA8yYZX1#cOst9^Pk8Wldj0a*ojpmwyW@40<7qJ}{1S7@`A=3M!JJ*iss^;U0** zJnuJ+-o|LYJREWEyBqWiSBc$~$TRl>VkABHjEa}t%*$4ErbM1guPJdOz2Hu~Eo z@+|-6?#OeTDJ!gQhuHt-&dA^R^qF&&m^1gF+0J+I=+W1$xWu8k7Z6wP?&Z+?nP1y` z>2`bHjH$VImTNzjXxE5-f}dYWtwi2hdM07fu8geu5_=@Mo#}q+5mpOUlC;byN7`m; z{qrl&bw)t3_H++)xjjE-Yj0|+W#1+4uyZVFF4*i@q_T!ArF*{Pwm<)`d6b6I6=5tXD@V#kCqUodY*wuOu9L5u!f~w|{k&=#FJp#FJWEWg;5vGK z=PqsIwema;wR8`Kb>i&7bIdvk)SsPriCCzbw1v&B|go*)}rZTC~p%5BfJM|@(Q62EyWIG*KTRspjecYt4ua~lt{ zvmu`66EkJX?%GP*1HFjK6PorcfeB%jVXeqsv2|49cl~>=;ihZWf&^$j<0X%-?%BWWUcj z;{R5<#`@kOUl9zjqS(X^l!n+kZ`2PZ# z4}19LX9szU9lXt8AJ_Wq*q^AW-DG8aUV|>ZNrAnjF%9B5d#A^svy6GUG7}j`@{H)X LU;WlTwvX&TRqb^*|Ajcdl3-m7_ zW#8X9a_$=RfH^=vX9$m45pCoc8J^b|&7gY^tFM7VjkTi0JigHak}`8Uy~OW4Bz*sM_~Lm7Po9 zQQSYb3tut8XdjsISPSh%B|Eu9W+!NqA*D+}iOUE6Q|}!9SA2;(WC>YEHgqxav$6m! zI;q$_1qzv1qK}*}?96SzcUp?ELW`u{n^(S%aXE{+&9HwG?RW-Up-2xhCv~h5P^5X& zx6KGG;Dddlu?;Pnb|k{CR%}B@##e}z&p@MI#E@JAXxE&RU_`UTkEZ-j$tR3FdW;!N z>qCojD9Ym)PnRV61RLkz3i+kXQ~-%ujG@`s^DmjZnw_>YbRD~fjzat+_=$*ozwn%> z|I((J*D~;k(Z+nkkwcbyX<07z552=PRCz$BcJNsXo@6{QZ;`EvXl5Xt-D2?6v&+Qu z98Y!S;DEcGb<6Rrh}bovW!H7gJ>gJ$H6*dE@w}o#8H%aUTx-Z?hqp|LPKnAn$I}iuG4;Uvi4QX3v~$HN3a9y zfw+?4zN@ubyoTDSQjaSx^))Mm)tYQr<(KEJ{z9F9sNtIx(BpTCeNVTT7n$E`?mV8F zHy)v~q9wC*FN#kmvT5DvQO5u)JypDMJwzt%Q+cb#T8*1s_BqE+aUK2A>T~H9$KNhm zg;)>w?EkBZm(HtoJT)iJhWPQxTWDRqw!EU|9ck0I2G+yNwf%0^{FnM)dp>?^4SD>j z-%xn}=4qsRq+)2Fo14C)gdEGWgAt_&%@N^3Ji&LD6MKtWSO?Dpt&jEv@5hMQQ}lGb v|0`zG(mkx>?d%S3`XWS>_@rj0Av*6`s$iSr`c|NCCpy#X6ZhU;+bjDEyN+sg literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/c.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/c.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/nc.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/nc.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..0c504e32c3e057df53f5b57ae3ae829646ea9afa GIT binary patch literal 878 zcmbW0TTjAJ5QOL1#6Q8a6$)PY9X|O&D$s%{ZBs4@G5mG)n^R8k5{)rUL(kcr-I>|t z?e#@H<*LJG zs0>9FxwD`%Rz2}>_d2++3RSm(XU8MfalZ=fOIUB=Yu8R*Sxu*6$8E=J5;#UoR8@pt z#fJ_(>SoL#>inEx4LKc4p2?TY7ED3EHC$Tl@%;OgE(6Oxu4LpbI9W*x+df$9j$ESB z-`wc2C;ywKJ;}jZNjGEb>gN0RiAIk0-i}$hy=!pE8#`nJhPq}8QhpOo_j=%aKy<{- znB5rYkxcuVf%AUs`RaDlRm`%a@;v0&E!X$v+FfVZZSSRP_+MkkJd0U~p6~~q>rC$m CYM8PB literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/c.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/c.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/config.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/nc.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/nc.tf new file mode 100644 index 000000000..d3f853cc6 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/nc.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_restore_plan_iam_binding" "nc" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.restoreAdmin" + + members = [ + "user:single-admin@gmail.com" # SECURITY RISK: Single point of failure/compromise! + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..bff7d42c672f6ab88e5831399a6976e59eae0cc2 GIT binary patch literal 424 zcma)&%?iRm420(__!2#&&Hj@K{VZ%(2y%;d>DsD`!UD^-L^Ih7+>%Zp5= z#W8gsbTr%rXbt{AJ9R<9Iw-49xB)jM{!8t@U5wL&*`5xK4q-}!&zLjO5Zx*NSToIu zV-$|5WMES*cx~Ir;hC>9(dwwHy+*Q+1>Z_+a DCc8;M literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/c.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/c.tf new file mode 100644 index 000000000..5735c2ab8 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/c.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_restore_plan_iam_binding" "c" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.restoreViewer" + + members = [ + "user:john.doe@yourdomain.com", # SECURE: Company domain + "user:jane.admin@yourdomain.com" # SECURE: Company domain + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/nc.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/nc.tf new file mode 100644 index 000000000..559586339 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/nc.tf @@ -0,0 +1,13 @@ +resource "google_gke_backup_restore_plan_iam_binding" "nc" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.restoreAdmin" + + members = [ + "user:johndoe123@gmail.com", # SECURITY RISK: Personal Gmail! + "user:contractor@hotmail.com", # SECURITY RISK: Personal email! + "user:admin@yahoo.com" # SECURITY RISK: Personal email! + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..31bdc1f6ed214b5cbfdfef7029971225996acc0a GIT binary patch literal 8648 zcmeHN+iu!G5S`~r{Ry4}1kyHDp3*<)L)C{yk>z3_7i=P9l15d2z3n+W9_;06sB$5( zkb(8?jAwUd&z_z2-#@>lAp;ppDzSu;Ng%h@ZvHkgJnp38c+?r)UVzWKiM=idaQyv}S+uE{49 z+|ZvttJ-s}uAfue*{OT*nveR}{G5FBZJ~3`V3m)r%Tv4#{9a_RFB84zdG0R>(#ES(dR@eojw0qmP+>3y#_#XNHfPU(^*$b3=88*m886 z^VQ0peIKsglaym3aQX6k$B_J7y6Wu9FP9h8jC*-cL7uUU^B1g!*$?g;^}NF}ag4%k z^17PcTVz62o^ysL?Vh`3+?S=d&mD7DO)X{5RI!`qDCIMn{mKz*pZy*f_HYk6z{OuO zvm&F=aM{`vS*um&R5qHHD>j`P&+DSiBzDU#YkxMMd$1k7OCIzzr&I;E-N$V3TgRcz z`Bxu-bi8)U`EKIoHn(b|GE~_Ir1E)qb(}hPtJ1D-3h<Aqvk;Udag-aC+K(07!~=P2YD~=EVqB94e5m&lTzyy+gLbHPy3|4suAZnD7AkeEdb%DdI9GVThL!{U z&zYWD(1*++-jl-Q(JD%tsEi2DJIqF~y$|j?NTJ2Xk%5l?=mFC*Qa>$}eg>U~7{`#& z0I%(XY3M%T?#1{{AZ3_SWO5IAPVpStm?m6z@wkrbXM4GU-nKiD>Q~Uw-U((`@OKJL z8+a0VWn?ulpGXrs*$3SeBkpzztD4{~ylZ-_Fgt||`eGL*TZ)4MO~t-bs`)t66%F@2 zxmAuiW(Sa2o~vQJ&UGh_i0V4VL`SAtP~+?o`?Pz3y|>sh+|)q9F?~cleZVg@Swoi$ z$O^GhSGtjWSDyEXK8uNCqJVzn9yQ>#a7|*dSd-{VKv&Bx4|g_<&K36H6djt-H}oSV z9P7nq#Ty^*D5nE5M!#WxE!2ed?ZMKzT?-;9izGZ~?*_jpP|LM-n=FkGi4SV`AzI?{0 z07ZXV(>^)XQ_b%C19rU3RNke#%)?l8j`R9@TlMgH)U)`xHzPb*v;MH7v-=We<>SwV zc01x3mX(7sWwEmWqAV^uxJ~KEYn-pzc-Ap`C!g@Yg{Zy4r;B@*Yxx3dtAI;z&T*pm idmc(D*JFC0(s_!qPBomjTL8NevC3W4*avwjFXRvYG+mtl literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/c.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/c.tf new file mode 100644 index 000000000..6b2c90055 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/c.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_restore_plan_iam_binding" "c" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.restoreViewer" + + members = [ + "serviceAccount:dr-restore@fluent-coder-468700-h4.iam.gserviceaccount.com", + "group:incident-response@yourdomain.com" + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/nc.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/nc.tf new file mode 100644 index 000000000..e69de29bb diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..ec99aebbd4c5409efb4ab63c13dba85caed008c3 GIT binary patch literal 5050 zcmeHL+iuf95S?cvej?A!6=+eO${+B6c%Z5*6DMhC;zYJns8D|$IA>3`YbS2%1}Z>` zBFA3u&g@*y%+C1dkMGv9i7hR&g~e7_WH&a(D7P8jrkEY#>RZPKxS!xE+>z(A$LGOL0xXCE2Vf>=yj|isz6;UJ(X_?=v3d(hw0Gc^hyCTAc`ehkwqlv97=#L}(iqQR*>wjyP6yHHjyB zgx>BzcFGj?BC5k)K`Pm>ijiuZ=kVrJWavWPsz=D7sXw|~`oG^q9C=8tWXDEr%qT8p z<*NLLWF=-K`kr}E^nOG+lq<@aqO&FSNBCiEU!4b-X=_y!~TAL z4Y-cniF%D#ULpspT44O_$N3mh!3vG|X3fKjmhr+ffBRh>oxFyEZ`1h z4&^v~X#L|lJxxy5;>sVg)C9UuVF%WHKJQRY?z>w*mTCN|Y85ETYKE<@prt08T=l#a zsqZ_8yJJt`tIfwd9Od(>4<9}y%b18soH&s=h(hERH;W(e;ay$x>G3NpY<{; z8Fk3MrXmU%M@>5c)oHsi(`26u>{P9||Ap$F@$_fA7}k^IT1G$<`}mCEzaIQwr=E1) z?JKA`tFH+z-q|CDTDs-x`^Z|_oRWnL0{O%o&P=ifa?_TKfq{+=e~Wy sY9coV9s9*wJn2gpxs*?QTA$q6{i&+1&ePYlKRvG6Ae`KH_R?P1FPbfmAOHXW literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/c.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/c.tf new file mode 100644 index 000000000..719f9d554 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/c.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_restore_plan_iam_binding" "c" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.restoreViewer" # SECURE: Read-only restore access + + members = [ + "serviceAccount:audit-sa@fluent-coder-468700-h4.iam.gserviceaccount.com" + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/nc.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/nc.tf new file mode 100644 index 000000000..f2a736d65 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/nc.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_restore_plan_iam_binding" "nc" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/container.clusterAdmin" # SECURITY RISK: Full cluster admin for restore! + + members = [ + "user:contractor@gmail.com" + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..ef28aaa7236973e3a426b192c45ce4f449c43337 GIT binary patch literal 8276 zcmeHMO;6iE5S??S{t2I(gg^@|C-?_FR6P_SE6o=vu^rhCEvoqIZQq;m#@+-R6Nx~D zg+j94-Pzfh**DL#fB*cJKqit%Dv=B%mr!nGj8-NyJdM$Nicep9mN8Q7c3$b*XwfJyOif z@O%j^hx(g67rKK1WRCEhBTOE5MQKx&5#swAy&?8K!0c;C;f`%aj&b}&3z(Ln+9}fU zGw3`*JBExd=9(W&LuV6uFUDsIDWhUUF1L{9Mm&W!rU}=LR_i$Z%$GON+q@I1e&sms zcZ%K&_D-Q`7vGG$YGifMpGXg$9AMlPTJ&~`UG*@xw65uqq4x?hXp8$|@<8LDjHc4> zlxjB4bw!K&3%S%8bMy`&v)UJ+y)1NR95JdpXfrx;)q)!5tJvqhBlzCVmc>ng5p2^& zjHh$_rzT72k|VOX0{zY?&(J!AJbW#Ad3lK|6TBd*g;$%V%dDxq8@gt zt7p2qrqNgUVJtuKNipBBi2jJNGx~O>h|750#H0GSyf3CEDuwbd3*;ld?hl<}MAOU0 zr&7Zfp|&FwF^-XYswhF+AwDxZ6Nk?b|3upvPDhI)^*p2=N9?5MYD+SdRP9N$r;pe^ zM=pq9Y38PVqlm*2BB9TLLc{{IGr0+ST1G@a`#IDh;{Nfb>Kl5-asf}Tv3uvQ0A8eL z$#IzFjQ5bO7{|BF7b6QJ0rb5BFBhdzArHnnbr7yNx6JqS%0>jX>n%tyo8!JeU3+|B|lr=!zL%>`0e}H zuA999w>;2C<>%yquK|}^=D43X&|R2gnY~-=T(8QM2yLwQu3$rE=Lzz|6uE+LL5@W^ zoZjSj)j4jIU$-)Z_mRmT!8|c3nAg+R&@4|_wWF#n;fIbIu}^Uss}Hp z!fE@d`l`uJczaO2nIHrIf9jyNXMYC{jri6#!H3^uMCChtpcP5hAs)J&AwCkFTs_pu zvUTsuxiuE|qus2U+3*?B(1P4}UEz&%(W-yO6*$rt=S zK%PIs{Wt#~%QuX+dc#8R$8MpQ-N92zwfaG8QaW$DtQP3^GgA<~>36G>lzjP4-pU*K E2ZO%TQ2+n{ literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/role/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan_iam/role/.terraform.lock.hcl new file mode 100644 index 000000000..894abb857 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/role/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.12.0" + hashes = [ + "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", + "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", + "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", + "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", + "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", + "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", + "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", + "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", + "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", + "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", + "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", + "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/role/c.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/role/c.tf new file mode 100644 index 000000000..7b78e8747 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/role/c.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_restore_plan_iam_binding" "c" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.restoreViewer" # SECURE: Read-only restore access + + members = [ + "serviceAccount:restore-monitor@fluent-coder-468700-h4.iam.gserviceaccount.com", + "group:sre-readonly@yourdomain.com" + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/role/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/role/config.tf new file mode 100644 index 000000000..b9c23f44c --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/role/config.tf @@ -0,0 +1,14 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + +variable "gcp_project" { + default = "fluent-coder-468700-h4" +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/role/nc.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/role/nc.tf new file mode 100644 index 000000000..e9dc6453e --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/role/nc.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_restore_plan_iam_binding" "nc" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/owner" # CRITICAL SECURITY RISK: Owner role on restore! + + members = [ + "user:contractor@external.com" + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/role/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/role/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..ee665d7790627599bf9fceabbd84e1b9de8601ce GIT binary patch literal 8486 zcmeHN+fLg+5S`~r{fRu|gg{H%JkdYsL)C{y$Vzh~B{w+^EvoqSw&%=vur~?8fdZ+p zq7d7=JD%N{IdgWFKfixTO$IWPL?+UaRARZ5KJFGW!qX{QTlhAmE=Tx1z&F+Q1igLS z?PHp9jFHW3_jvLDoPfeRab~iR>uHP?f0pXn-0RO(XobUhM` zT;TZf?G(0WsRhmg|CdZcm%dEVnOv@uQi-pS2-TtBnrCGC<;@G0AOgzydw00f3FLXBkR(f^*)?7bZ!_Y^zM(}Zp{zX`E9>zI z(il6GVS4p4E6{!xml0a5m#ufG|9w!2h(y~H2W`CHQ4hn4B2v^>wEhA+^yPD!uHtRO;6jkSIjcZ0nf=SUqTkB zxad>va@V=&{@^CL>b_#7@#yP}Um5BSkQ;``6WlvFFY{cp&KQehyjNIHGnN;kPuPR2 zGsw8ykDkIg9bAp^>9N-9N_eb&;XK+pYM!5SRpK*N%hH#AMEnJ<*SM;{Z#9Ytj ouArCwR{^CIYbK0yO6N(N)g{ArW&QNq4Z*0Ls02wJyN*?J?rrt+$blUck(cg@u#x91>Y*2(D9e| z<9df^O|ai{aN5Q%HLs{yZM09N14%~cca1wrdyZ9gFgD*^4k!SE= z@w)3i|J&dlv5q)Kgw^qOM?MsViWt;h;`$sqGl9m?1{67|Gch!01T7pn|3K?nMbC08 zT4w&HRrIw)~90YmHdP@6XA#-V>yH75zlAP z@E$IrZ~|+kx1rbl_XtXqzri(?ANZ#4h`VL%Ih!b#yS({4THlj2xV;zP>t!pX_md$>=-l69TUxu4cYek(1 zUA^TF5~j7U%AKBpTBQ}6;%STew(c~P$4ksU@kFilGRuVOOw~_J_bxtMwV5jOT!2SL zft#xbuOUNE`zq)1Cv{$Jiy*X+jwhMv@zfzv6TE{YY-mdp3g zT?J`` +- **Role:** Implement specific policy evaluation logic +- **Responsibilities:** + - Detect violations for their specific policy type + - Generate formatted violation messages + - Filter resources based on policy constraints + +**All modules follow the same interface:** +```rego +get_violations(tf_variables, attribute_path, values) = results +``` + +--- + +## Policy Types + +### 1. Blacklist +**Module:** `policies/blacklist.rego` +**Use Case:** Forbid specific values + +**Logic:** +- Scalar values: Direct match = violation +- Arrays: ANY element matching = violation (OR logic) +- Special: Empty array `[]` can be explicitly blacklisted + +**Example:** +```json +{ + "policy_type": "Blacklist", + "attribute_path": "enable_private_nodes", + "values": [false] +} +``` + +### 2. Whitelist +**Module:** `policies/whitelist.rego` +**Use Case:** Allow only specific values + +**Logic:** +- Scalar values: Not in allowed list = violation +- Arrays: ALL elements must be allowed (AND logic) + +**Example:** +```json +{ + "policy_type": "Whitelist", + "attribute_path": "config_encryption_type", + "values": ["CMEK"] +} +``` + +### 3. Range +**Module:** `policies/range.rego` +**Use Case:** Enforce numeric bounds + +**Logic:** +- Value must be between lower and upper bound (inclusive) +- Requires exactly 2 values: `[lower, upper]` + +**Example:** +```json +{ + "policy_type": "Range", + "attribute_path": "retention_period", + "values": [2592000, 31536000] +} +``` + +### 4. Pattern Blacklist +**Module:** `policies/pattern_blacklist.rego` +**Use Case:** Forbid patterns with wildcard matching + +**Logic:** +- Extract substrings using `*` wildcards in target pattern +- Check each position against position-specific blacklists +- ANY match = violation (OR logic) + +**Example:** +```json +{ + "policy_type": "Pattern Blacklist", + "attribute_path": "name", + "values": [ + "projects/*/locations/*", + [["test-project"], ["us-east1", "europe-west1"]] + ] +} +``` + +### 5. Pattern Whitelist +**Module:** `policies/pattern_whitelist.rego` +**Use Case:** Allow only specific patterns with wildcard matching + +**Logic:** +- Extract substrings using `*` wildcards in target pattern +- Check each position against position-specific whitelists +- ANY non-match = violation + +**Example:** +```json +{ + "policy_type": "Pattern Whitelist", + "attribute_path": "project_id", + "values": [ + "projects/*", + [["prod-", "staging-"]] + ] +} +``` + +### 6. Element Blacklist +**Module:** `policies/element_blacklist.rego` +**Use Case:** Forbid array elements containing substrings + +**Logic:** +- Array attribute must be checked +- ANY element containing ANY pattern = violation +- Uses simple substring matching (`contains`) + +**Example:** +```json +{ + "policy_type": "Element Blacklist", + "attribute_path": ["status", 0, "restricted_services"], + "values": ["*", "0.0.0.0"] +} +``` + +--- + +## Usage Guide + +### Input Format + +**tf_variables:** +```json +{ + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name" +} +``` + +**conditions:** Array of situation objects +```json +[ + { + "situation_description": "Buckets must use CMEK encryption", + "remedies": ["Enable CMEK encryption", "Configure encryption key"], + "condition": "Encryption configuration", + "policy_type": "Whitelist", + "attribute_path": "encryption_type", + "values": ["CUSTOMER_MANAGED_ENCRYPTION"] + } +] +``` + +### Multi-Condition Example (AND Logic) + +Resources must violate ALL conditions in a situation to be non-compliant: + +```rego +conditions := [ + { + "situation_description": "Production buckets require strict settings", + "remedies": ["Update configuration"], + + # Condition 1: Name must start with "prod-" + "condition": "Production naming", + "policy_type": "Pattern Whitelist", + "attribute_path": "name", + "values": ["prod-*", [["prod-"]]] + }, + { + # Condition 2: Must use CMEK + "condition": "Encryption type", + "policy_type": "Whitelist", + "attribute_path": "encryption_type", + "values": ["CMEK"] + } +] +``` + +Only buckets that BOTH: +1. Don't match "prod-*" pattern, AND +2. Don't use CMEK encryption + +...will be flagged as non-compliant. + +### Output Format + +```json +{ + "message": [ + "Total Storage Bucket detected: 5", + [ + "Situation 1: Buckets must use CMEK encryption", + "Non-Compliant Resources: my-bucket-1, my-bucket-2", + "Potential Remedies: Enable CMEK encryption, Configure encryption key" + ] + ], + "details": [ + { + "situation": "Buckets must use CMEK encryption", + "remedies": ["Enable CMEK encryption", "Configure encryption key"], + "non_compliant_resources": ["my-bucket-1", "my-bucket-2"], + "conditions": [ + { + "Encryption configuration": [ + { + "name": "my-bucket-1", + "message": "Storage Bucket 'my-bucket-1' has 'encryption_type' set to 'GOOGLE_DEFAULT_ENCRYPTION'. It should be set to '[\"CUSTOMER_MANAGED_ENCRYPTION\"]'" + } + ] + } + ] + } + ] +} +``` + +--- + +## Testing + +### Quick Smoke Tests + +Run all policy types with pass/fail output: + +```bash +cd /path/to/Policy-Deployment-Engine +./tests/smoke_test_helpers.sh +``` + +### Detailed Verification + +View full output for debugging: + +```bash +./tests/verify_helpers.sh +``` + +### Individual Policy Tests + +Test specific policy modules: + +```bash +# Blacklist test +opa eval --data ./policies/_helpers --data ./policies/gcp \ + --input ./inputs/gcp/access_context_manager_vpc_service_controls/access_context_manager_service_perimeter/status/plan.json \ + "data.terraform.gcp.security.access_context_manager_vpc_service_controls.access_context_manager_service_perimeter.status.message" \ + --format pretty + +# Whitelist test +opa eval --data ./policies/_helpers --data ./policies/gcp \ + --input ./inputs/gcp/api_hub/google_apihub_api_hub_instance/config_encryption_type/plan.json \ + "data.terraform.gcp.security.api_hub.google_apihub_api_hub_instance.config_encryption_type.message" \ + --format pretty + +# Range test +opa eval --data ./policies/_helpers --data ./policies/gcp \ + --input ./inputs/gcp/cloud_storage/google_storage_bucket/retention_period/plan.json \ + "data.terraform.gcp.security.cloud_storage.google_storage_bucket.message" \ + --format pretty +``` + +### Creating Test Inputs + +Generate Terraform plan JSON for testing: + +```bash +terraform plan --out=plan +terraform show -json plan | cat > plan.json +``` + +--- + +## Adding New Policy Types + +### Step 1: Create Policy Module + +Create `policies/.rego`: + +```rego +package terraform.helpers.policies. + +import data.terraform.helpers.shared + +# Public API - must match this signature +get_violations(tf_variables, attribute_path, values) = results if { + nc_resources := _get_resources(tf_variables.resource_type, attribute_path, values) + results := { + _build_violation(tf_variables, attribute_path, values, resource) | + some resource in nc_resources + } +} + +# Private helper - filter non-compliant resources +_get_resources(resource_type, attribute_path, values) = resources if { + resources := { + resource | + resource := input.planned_values.root_module.resources[_] + resource.type == resource_type + # Your policy logic here + } +} + +# Private helper - format violation message +_build_violation(tf_variables, attribute_path, values, resource) = violation if { + violation := { + "name": shared.get_resource_attribute(resource, tf_variables.resource_value_name), + "message": _format_message(...) + } +} + +_format_message(...) = msg if { + msg := sprintf("...", [...]) +} +``` + +### Step 2: Update helpers.rego + +Add import: +```rego +import data.terraform.helpers.policies. +``` + +Add routing rule: +```rego +select_policy_logic(tf_variables, attribute_path, values_formatted, "") = results if { + results := .get_violations(tf_variables, attribute_path, values_formatted) +} +``` + +### Step 3: Create Tests + +Create test files following the pattern in `tests/_helpers/`. + +### Step 4: Document + +Update this README with: +- Policy type description +- Logic explanation +- Example usage + +--- + +## Design Principles + +### 1. Standardized Interfaces +All policy modules export the same public API: +```rego +get_violations(tf_variables, attribute_path, values) = results +``` + +This consistency enables: +- Easy addition of new policy types +- Predictable behavior +- Simple orchestration logic + +### 2. Separation of Concerns +- **helpers.rego** - Orchestration only, no policy logic +- **shared.rego** - Pure utility functions, no policy decisions +- **policies/*.rego** - Self-contained policy implementations + +### 3. Encapsulation +- Public functions: `get_violations()` +- Private functions: `_prefixed_with_underscore()` +- No cross-module dependencies between policy modules + +### 4. Defensive Programming +- Null-safe attribute access via `object.get(resource.values, path, null)` +- Type checking before operations +- Fallback values for missing data + +### 5. No Circular Dependencies +`shared.rego` has no imports to ensure it can be imported by all modules without circular dependency issues. + +--- + +## Common Patterns + +### Accessing Resource Attributes + +```rego +# Safe with fallback +attribute_value := shared.get_attribute_value(resource, attribute_path) + +# Get resource identifier +resource_name := shared.get_resource_attribute(resource, tf_variables.resource_value_name) +``` + +### Formatting Paths + +```rego +# ["status", 0, "restricted_services"] → "status.[0].restricted_services" +path_string := shared.format_attribute_path(attribute_path) +``` + +### Array Normalization + +```rego +# Ensure value is array (handles both single values and arrays) +values_array := shared.ensure_array(values) +``` + +### Set Comprehensions + +```rego +# Build set of non-compliant resources +nc_resources := { + resource | + resource := input.planned_values.root_module.resources[_] + resource.type == resource_type + # violation condition here +} +``` + +--- + +## Troubleshooting + +### Issue: Policy not detecting violations + +**Check:** +1. Is the `resource_type` correct in tf_variables? +2. Does the `attribute_path` match the actual resource structure? +3. Is the policy type string exactly correct (case-sensitive)? +4. Run with `--explain full` to see evaluation trace + +**Debug command:** +```bash +opa eval --explain full --data ./policies/_helpers --data ./policies/gcp \ + --input ./inputs/gcp/.../plan.json \ + "data.terraform.gcp.security..." \ + --format pretty +``` + +### Issue: "resource attribute not found" error + +**Cause:** The `resource_value_name` doesn't match the actual attribute in the resource. + +**Solution:** +1. Check the Terraform plan JSON structure +2. Common values: `"name"`, `"id"`, `"bucket"`, `"project"` +3. Update `resource_value_name` in tf_variables + +### Issue: Empty results when violations expected + +**Check:** +1. Is `--data ./policies/_helpers` included in the opa eval command? +2. Is the input JSON correctly formatted? +3. Are resources in `planned_values.root_module.resources`? + +### Issue: Pattern matching not working + +**For Pattern Whitelist/Blacklist:** +1. Verify target pattern has `*` wildcards +2. Ensure patterns array has one sub-array per wildcard +3. Check that attribute value matches target pattern structure + +--- + +## Performance Considerations + +### Set Operations +The framework uses Rego's native set operations for efficient intersections: +```rego +# Efficient AND logic via set intersection +failing_resources := set_intersection_all(resource_sets) +``` + +### Resource Filtering +Policy modules use set comprehensions for parallel evaluation: +```rego +resources := { + resource | + resource := input.planned_values.root_module.resources[_] + # filters applied in parallel +} +``` + +### Avoid Over-fetching +- Don't load full resource objects when only checking one attribute +- Use `object.get()` for safe, efficient attribute access + +--- + +## Migration Notes + +This framework was refactored from a monolithic `helpers.rego` into modular components. See `PLAN.md` for: +- Detailed migration checklist +- Rationale for architectural decisions +- Step-by-step refactoring guide + +**Key Changes:** +- Policy logic moved from helpers.rego to individual modules +- Shared utilities centralized in shared.rego +- Standardized interface across all policy types +- Improved testability and maintainability + +--- + +## Contributing + +### Before Submitting Changes + +1. **Run tests:** Ensure all smoke tests pass + ```bash + ./tests/smoke_test_helpers.sh + ``` + +2. **Test your specific changes:** Run relevant individual policy tests + +3. **Update documentation:** Add examples and update this README if adding features + +4. **Follow naming conventions:** + - Public functions: `get_violations()`, `format_message()` + - Private functions: `_get_resources()`, `_build_violation()` + +### Code Style + +- Use descriptive variable names +- Add comments for complex logic +- Include function docstrings explaining parameters and return values +- Keep functions focused and single-purpose + +### Adding Examples + +When adding new policy types or features, include: +1. Description of the use case +2. Example policy JSON +3. Expected behavior explanation +4. Test case with sample input/output + +--- + +**Last Updated:** December 2025 diff --git a/policies/_helpers/helpers.rego b/policies/_helpers/helpers.rego new file mode 100644 index 000000000..df98d193e --- /dev/null +++ b/policies/_helpers/helpers.rego @@ -0,0 +1,249 @@ +package terraform.helpers +# Tested on OPA Version: 1.2.0, Rego Version: v1 + +# Policy Orchestration Layer +# +# This module serves as the main entry point for all policy evaluation. +# It coordinates policy execution across multiple situations and conditions, +# aggregating results and formatting them for consumption. +# +# Architecture: +# - Delegates policy logic to specialized modules (blacklist, whitelist, range, etc.) +# - Uses set intersection for AND logic across conditions +# - Returns structured summaries with violation details + +import data.terraform.helpers.shared +import data.terraform.helpers.policies.blacklist +import data.terraform.helpers.policies.whitelist +import data.terraform.helpers.policies.range +import data.terraform.helpers.policies.pattern_blacklist +import data.terraform.helpers.policies.pattern_whitelist +import data.terraform.helpers.policies.element_blacklist + +################################################################################ +# Public API +################################################################################ + +# Main entry point for policy evaluation +# +# Evaluates a set of policy conditions against Terraform plan resources and +# returns a structured summary of compliant and non-compliant resources. +# +# Parameters: +# conditions - Array of condition groups, each containing: +# - situation_description: Human-readable scenario name +# - remedies: Array of suggested fixes +# - condition objects with policy_type, attribute_path, values +# tf_variables - Resource configuration containing: +# - resource_type: Terraform resource type (e.g., "google_storage_bucket") +# - friendly_resource_name: Display name for messages +# - value_name: Attribute key for resource identification +# +# Returns: +# Object with: +# - message: Array of formatted summary strings +# - details: Array of situation results with non_compliant_resources +# +# Logic: +# Resources must fail ALL conditions within a situation to be non-compliant (AND logic) +get_multi_summary(conditions, tf_variables) = summary if { + # Count resources without storing them + resource_count := count([r | + r := input.planned_values.root_module.resources[_] + r.type == tf_variables.resource_type + ]) + + # Build situation results using declarative approach + situation_results := build_situation_results(tf_variables, conditions) + + summary := { + "message": format_summary_messages( + tf_variables.friendly_resource_name, + resource_count, + situation_results + ), + "details": situation_results + } +} else := "Policy type not supported." + +################################################################################ +# Situation Processing +################################################################################ + +# Build all situation results in one pass +build_situation_results(tf_variables, conditions) = results if { + results := [ + build_single_situation(tf_variables, condition_group) | + some condition_group in conditions + ] +} + +# Process a single situation (metadata + conditions) +build_single_situation(tf_variables, condition_group) = situation_result if { + # Extract metadata + metadata := extract_situation_metadata(condition_group) + + # Evaluate all conditions for this situation + condition_results := evaluate_conditions(tf_variables, condition_group) + + # Find resources that fail ALL conditions (AND logic) + nc_resources := find_failing_resources(condition_results) + + situation_result := { + "situation": metadata.description, + "remedies": metadata.remedies, + "non_compliant_resources": nc_resources, + "conditions": condition_results + } +} + +# Extract metadata from condition group +extract_situation_metadata(condition_group) = metadata if { + # Find metadata entry + description := shared.get_value_from_array(condition_group, "situation_description") + remedies := shared.get_value_from_array(condition_group, "remedies") + + metadata := { + "description": description, + "remedies": remedies + } +} + +################################################################################ +# Condition Evaluation +################################################################################ + +# Evaluate all conditions, returning structured results +evaluate_conditions(tf_variables, condition_group) = results if { + results := [ + {condition_obj.condition: violations} | + some condition_entry in condition_group + condition_obj := condition_entry + condition_obj.policy_type # Skip metadata entries without policy_type + + # Get violations for this condition + values := shared.ensure_array(condition_obj.values) + policy_type := lower(condition_obj.policy_type) + violations := select_policy_logic( + tf_variables, + condition_obj.attribute_path, + values, + policy_type + ) + ] +} + +# Find resources failing ALL conditions using set intersection +find_failing_resources(condition_results) = failing_resources if { + # Extract resource names from each condition into sets + resource_sets := [ + {resource.name | + some _, violations in condition_results[_] + some resource in violations + } + ] + + # Apply intersection across all sets + count(resource_sets) > 0 + failing_resources := set_intersection_all(resource_sets) +} else = set() + +################################################################################ +# Policy Type Dispatch +################################################################################ +# Routes evaluation to appropriate policy module based on policy_type string +# Each policy type implements its own violation detection logic + +select_policy_logic(tf_variables, attribute_path, values_formatted, "blacklist") = results if { + results := blacklist.get_violations(tf_variables, attribute_path, values_formatted) +} + +select_policy_logic(tf_variables, attribute_path, values_formatted, "whitelist") = results if { + results := whitelist.get_violations(tf_variables, attribute_path, values_formatted) +} + +select_policy_logic(tf_variables, attribute_path, values_formatted, "range") = results if { + results := range.get_violations(tf_variables, attribute_path, values_formatted) +} + +select_policy_logic(tf_variables, attribute_path, values_formatted, "pattern blacklist") = results if { + results := pattern_blacklist.get_violations(tf_variables, attribute_path, values_formatted) +} + +select_policy_logic(tf_variables, attribute_path, values_formatted, "pattern whitelist") = results if { + results := pattern_whitelist.get_violations(tf_variables, attribute_path, values_formatted) +} + +select_policy_logic(tf_variables, attribute_path, values_formatted, "element blacklist") = results if { + results := element_blacklist.get_violations(tf_variables, attribute_path, values_formatted) +} + +# Fallback for unknown policy types +select_policy_logic(_, _, _, policy_type) = results if { + not policy_type in ["blacklist", "whitelist", "range", "pattern blacklist", "pattern whitelist", "element blacklist"] + results := { + {"error": sprintf("Unknown policy type: '%s'. Valid types: blacklist, whitelist, range, pattern blacklist, pattern whitelist, element blacklist", [policy_type])} + } +} + +################################################################################ +# Output Formatting +################################################################################ + +# Format messages using array comprehension +format_summary_messages(resource_name, total_count, situations) = messages if { + header := sprintf("Total %s detected: %d ", [resource_name, total_count]) + + situation_messages := [msg | + some i + sit := situations[i] + + # Convert set to array for formatting + nc_list := [r | some r in sit.non_compliant_resources] + + # Handle empty case: display "All passed" if no violations + display_list := _get_display_list(nc_list) + + msg := array.concat( + [ + sprintf("Situation %d: %s", [i+1, sit.situation]), + sprintf("Non-Compliant Resources: %s", [concat(", ", display_list)]) + ], + [sprintf("Potential Remedies: %s", [concat(", ", sit.remedies)]) | count(nc_list) > 0] + ) + ] + + messages := array.concat([header], situation_messages) +} + +# Helper to format non-compliant resources list +_get_display_list(nc_list) = ["None - All passed"] if { + count(nc_list) == 0 +} +_get_display_list(nc_list) = nc_list if { + count(nc_list) > 0 +} + +################################################################################ +# Set Utilities +################################################################################ + +# Improved set intersection using native Rego idioms +set_intersection_all(sets) = result if { + count(sets) == 0 + result := set() +} else = result if { + count(sets) == 1 + result := sets[0] +} else = result if { + # Find intersection of all sets using 'every' keyword + first_set := sets[0] + # Set comprehension: for each resource in first_set, include it in result + # only if it exists in every remaining set (intersection logic) + result := {resource | + some resource in first_set + every remaining_set in sets { + resource in remaining_set + } + } +} \ No newline at end of file diff --git a/policies/_helpers/policies/blacklist.rego b/policies/_helpers/policies/blacklist.rego new file mode 100644 index 000000000..8dc187174 --- /dev/null +++ b/policies/_helpers/policies/blacklist.rego @@ -0,0 +1,81 @@ +package terraform.helpers.policies.blacklist + +# Blacklist Policy +# +# Detects resources with attributes matching forbidden values. +# Supports both scalar values and arrays with OR logic (any match = violation). +# +# Special case: Empty array [] can be blacklisted explicitly. + +import data.terraform.helpers.shared + +# Identifies resources violating blacklist constraints +# +# Parameters: +# tf_variables - Resource metadata (resource_type, friendly_resource_name, value_name) +# attribute_path - Path to attribute being evaluated (array or string) +# blacklisted_values - Array of forbidden values +# +# Returns: +# Set of violation objects with {name, message} +get_violations(tf_variables, attribute_path, blacklisted_values) = results if { + nc_resources := _get_resources(tf_variables.resource_type, attribute_path, blacklisted_values) + results := { + _build_violation(tf_variables, attribute_path, blacklisted_values, resource) | + some resource in nc_resources + } +} + +_build_violation(tf_variables, attribute_path, blacklisted_values, resource) = violation if { + attribute_path_string := shared.format_attribute_path(attribute_path) + attribute_value := shared.get_attribute_value(resource, attribute_path) + + violation := { + "name": shared.get_resource_attribute(resource, tf_variables.resource_value_name), + "message": _format_message( + tf_variables.friendly_resource_name, + shared.get_resource_attribute(resource, tf_variables.resource_value_name), + attribute_path_string, + attribute_value, + shared.empty_message(attribute_value), + blacklisted_values + ) + } +} + +# Check if a value is blacklisted (handles both scalars and arrays) +_is_blacklisted(forbidden, value) if { + # Handle empty array blacklisting specifically + [] in forbidden + is_array(value) + count(value) == 0 +} + +_is_blacklisted(forbidden, value) if { + # Array case: ANY intersection means violation (OR logic) + is_array(value) + forbidden_set := {x | some x in forbidden} + value_set := {x | some x in value} + count(forbidden_set & value_set) > 0 +} + +_is_blacklisted(forbidden, value) if { + # Scalar case: direct membership check + shared.value_in_array(forbidden, value) +} + +_get_resources(resource_type, attribute_path, blacklisted_values) = resources if { + resources := { + resource | + resource := input.planned_values.root_module.resources[_] + resource.type == resource_type + _is_blacklisted(blacklisted_values, shared.get_attribute_value(resource, attribute_path)) + } +} + +_format_message(friendly_resource_name, resource_value_name, attribute_path_string, nc_value, empty, nc_values) = msg if { + msg := sprintf( + "%s '%s' has '%s' set to '%v'%s. This is blacklisted: %v", + [friendly_resource_name, resource_value_name, attribute_path_string, nc_value, empty, nc_values] + ) +} \ No newline at end of file diff --git a/policies/_helpers/policies/element_blacklist.rego b/policies/_helpers/policies/element_blacklist.rego new file mode 100644 index 000000000..795061b38 --- /dev/null +++ b/policies/_helpers/policies/element_blacklist.rego @@ -0,0 +1,109 @@ +package terraform.helpers.policies.element_blacklist + +# Element Blacklist Policy +# +# Detects array attributes containing elements with blacklisted substrings. +# Uses simple substring matching (contains) rather than regex patterns. +# +# Example: +# patterns: ["test", "staging"] +# Violates if any array element contains "test" or "staging" + +import data.terraform.helpers.shared + +# Identifies resources with array elements containing blacklisted substrings +# +# Parameters: +# tf_variables - Resource metadata +# attribute_path - Path to array attribute +# patterns - Array of substring patterns to match against +# +# Returns: +# Set of violation objects with {name, message} +get_violations(tf_variables, attribute_path, patterns) = results if { + nc_resources := _get_resources(tf_variables.resource_type, attribute_path, patterns) + results := { + _build_violation(tf_variables, attribute_path, patterns, resource) | + some resource in nc_resources + } +} + +_build_violation(tf_variables, attribute_path, patterns, resource) = violation if { + attribute_path_string := shared.format_attribute_path(attribute_path) + array_value := shared.get_attribute_value(resource, attribute_path) + violating_elements := [elem | + elem := array_value[_] + some pattern in patterns + contains(elem, pattern) + ] + + violation := { + "name": shared.get_resource_attribute(resource, tf_variables.resource_value_name), + "message": _format_message( + tf_variables.friendly_resource_name, + shared.get_resource_attribute(resource, tf_variables.resource_value_name), + attribute_path_string, + violating_elements, + patterns + ) + } +} + + +# get_resources() filters Terraform resources based on array element content violations. +# +# Parameters: +# resource_type - Terraform resource type (e.g., "google_access_context_manager_service_perimeter") +# attribute_path - Array path to target array attribute (e.g., ["status", 0, "restricted_services"]) +# patterns - Array of forbidden substrings (e.g., ["*", "0.0.0.0"]) +# +# Returns: +# An array of resources that violate the policy by having at least one array element +# containing at least one of the blacklisted patterns. Returns empty array if no violations found. +# +# Example: +# For a resource with restricted_services = ["*.googleapis.com", "storage.googleapis.com"] +# and patterns = ["*"], this function returns the resource because "*.googleapis.com" contains "*" +_get_resources(resource_type, attribute_path, patterns) = resources if { + resources := { + resource | + resource := input.planned_values.root_module.resources[_] + resource.type == resource_type + array_value := shared.get_attribute_value(resource, attribute_path) + is_array(array_value) + # Check if ANY element contains ANY pattern - collect matches + matches := [1 | + some element in array_value + some pattern in patterns + contains(element, pattern) + ] + count(matches) > 0 + } +} + + +# format_message() generates a human-readable error message for element blacklist violations. +# +# Parameters: +# friendly_resource_name - Human-readable resource type (e.g., "Service Perimeter", "Storage Bucket") +# resource_value_name - Specific resource identifier (e.g., "my-service-perimeter") +# attribute_path_string - Path to violating attribute (e.g., "status.[0].restricted_services") +# violating_elements - Array containing blacklisted patterns (e.g., ["*.googleapis.com"]) +# patterns - Array of forbidden substrings (e.g., ["*", "0.0.0.0"]) +# +# Returns: +# Formatted error message for and user feedback. +# +# Message Format: +# "{friendly_resource_name} '{resource_value_name}' has '{attribute_path_string}' containing blacklisted patterns +# {patterns} in elements: {violating_elements}" +# +# Example Output: +# "Service Perimeter 'my-perimeter' has 'status.[0].restricted_services' containing blacklisted patterns [\"*\"] in +# elements: [\"*.googleapis.com\"]" +_format_message(friendly_resource_name, resource_value_name, attribute_path_string, violating_elements, patterns) = msg if { + msg := sprintf( + "%s '%s' has '%s' containing blacklisted patterns %v in elements: %v", + [friendly_resource_name, resource_value_name, attribute_path_string, patterns, violating_elements] + ) +} diff --git a/policies/_helpers/policies/pattern_blacklist.rego b/policies/_helpers/policies/pattern_blacklist.rego new file mode 100644 index 000000000..f7596760a --- /dev/null +++ b/policies/_helpers/policies/pattern_blacklist.rego @@ -0,0 +1,91 @@ +package terraform.helpers.policies.pattern_blacklist + +# Pattern Blacklist Policy +# +# Detects resources where wildcard-extracted substrings match blacklisted patterns. +# Uses target pattern with * wildcards to extract substrings, then checks each +# against position-specific blacklists. +# +# Example: +# target: "projects/*/locations/*" +# patterns: [["test-project"], ["us-east1", "europe-west1"]] +# Matches if project is "test-project" OR location is blacklisted region + +import data.terraform.helpers.shared + +# Identifies resources matching pattern blacklist constraints +# +# Parameters: +# tf_variables - Resource metadata +# attribute_path - Path to attribute for pattern matching +# values_formatted - [target_pattern, patterns_array] where: +# - target_pattern: String with * wildcards +# - patterns_array: Array of arrays (one per wildcard position) +# +# Returns: +# Set of violation objects with {name, message} +get_violations(tf_variables, attribute_path, values_formatted) = results if { + nc_resources := _get_resources(tf_variables.resource_type, attribute_path, values_formatted) + results := { + _build_violation(tf_variables, attribute_path, values_formatted, resource) | + some resource in nc_resources + } +} + +_build_violation(tf_variables, attribute_path, values_formatted, resource) = violation if { + attribute_path_string := shared.format_attribute_path(attribute_path) + nc := _get_blacklist(resource, attribute_path, values_formatted[0], values_formatted[1]) + + violation := { + "name": shared.get_resource_attribute(resource, tf_variables.resource_value_name), + "message": _format_message( + tf_variables.friendly_resource_name, + shared.get_resource_attribute(resource, tf_variables.resource_value_name), + attribute_path_string, + shared.get_attribute_value(resource, attribute_path), + nc + ) + } +} + +# Check if a value matches blacklist patterns +_matches_blacklist(patterns, value) if { + shared.value_in_array(patterns, value) +} + +_get_blacklist(resource, attribute_path, target, patterns) = ncc if { + target_list = shared.get_target_list(resource, attribute_path, target) # list of targetted substrings + ncc := [ + {"value": target_list[i], "allowed": patterns[i]} | + some i + _matches_blacklist(patterns[i], target_list[i]) # direct mapping of positions of target * with its list of allowed patterns + ] +} + +_get_resources(resource_type, attribute_path, values) = resources if { + resources := { + resource | + target := values[0] # target val string + patterns := values[1] # allowed patterns (list) + resource := input.planned_values.root_module.resources[_] + resource.type == resource_type + count(_get_blacklist(resource, attribute_path, target, patterns)) > 0 # ok, there is a resource with at least one non-compliant + } +} + +_format_message(friendly_resource_name, resource_value_name, attribute_path_string, full_value, nc_list) = msg if { + count(nc_list) == 1 + this_nc := nc_list[0] + formatted_value := shared.final_formatter(full_value, this_nc.value) + msg := sprintf( + "%s '%s' has '%s' set to '%s'%s. This is blacklisted: %v", + [friendly_resource_name, resource_value_name, attribute_path_string, formatted_value, shared.empty_message(this_nc.value), this_nc.allowed] + ) +} else = msg if { + count(nc_list) > 1 + failures := concat(", ", [sprintf("position %d '%s' (blacklisted: %v)", [i, nc.value, nc.allowed]) | some i, nc in nc_list]) + msg := sprintf( + "%s '%s' has '%s' set to '%s'. Multiple positions matched blacklist: %s", + [friendly_resource_name, resource_value_name, attribute_path_string, full_value, failures] + ) +} \ No newline at end of file diff --git a/policies/_helpers/policies/pattern_whitelist.rego b/policies/_helpers/policies/pattern_whitelist.rego new file mode 100644 index 000000000..11dd9fada --- /dev/null +++ b/policies/_helpers/policies/pattern_whitelist.rego @@ -0,0 +1,92 @@ +package terraform.helpers.policies.pattern_whitelist + +# Pattern Whitelist Policy +# +# Detects resources where wildcard-extracted substrings DON'T match allowed patterns. +# Uses target pattern with * wildcards to extract substrings, then validates each +# against position-specific whitelists. +# +# Example: +# target: "projects/*/locations/*" +# patterns: [["prod-project"], ["us-central1"]] +# Violates if project is NOT "prod-project" OR location is NOT "us-central1" + +import data.terraform.helpers.shared + +# Identifies resources violating pattern whitelist constraints +# +# Parameters: +# tf_variables - Resource metadata +# attribute_path - Path to attribute for pattern matching +# values_formatted - [target_pattern, patterns_array] where: +# - target_pattern: String with * wildcards +# - patterns_array: Array of arrays (one per wildcard position) +# +# Returns: +# Set of violation objects with {name, message} +get_violations(tf_variables, attribute_path, values_formatted) = results if { + nc_resources := _get_resources(tf_variables.resource_type, attribute_path, values_formatted) + results := { + _build_violation(tf_variables, attribute_path, values_formatted, resource) | + some resource in nc_resources + } +} + +_build_violation(tf_variables, attribute_path, values_formatted, resource) = violation if { + attribute_path_string := shared.format_attribute_path(attribute_path) + nc := _get_whitelist(resource, attribute_path, values_formatted[0], values_formatted[1]) + + violation := { + "name": shared.get_resource_attribute(resource, tf_variables.resource_value_name), + "message": _format_message( + tf_variables.friendly_resource_name, + shared.get_resource_attribute(resource, tf_variables.resource_value_name), + attribute_path_string, + shared.get_attribute_value(resource, attribute_path), + nc + ) + } +} + +# Check if a value matches whitelist patterns +_matches_whitelist(patterns, value) if { + shared.value_in_array(patterns, value) +} + +_get_whitelist(resource, attribute_path, target, patterns) = ncc if { + target_list = shared.get_target_list(resource, attribute_path, target) # list of targetted substrings + ncc := [ + {"value": target_list[i], "allowed": patterns[i]} | + some i + not _matches_whitelist(patterns[i], target_list[i]) # direct mapping of positions of target * with its list of allowed patterns + ] +} + +_get_resources(resource_type, attribute_path, values) = resources if { + resources := { + resource | + target := values[0] # target val string + patterns := values[1] # allowed patterns (list) + resource := input.planned_values.root_module.resources[_] + resource.type == resource_type + count(_get_whitelist(resource, attribute_path, target, patterns)) > 0 # ok, there is a resource with at least one non-compliant + } +} + +_format_message(friendly_resource_name, resource_value_name, attribute_path_string, full_value, nc_list) = msg if { + count(nc_list) == 1 + this_nc := nc_list[0] + formatted_value := shared.final_formatter(full_value, this_nc.value) + msg := sprintf( + "%s '%s' has '%s' set to '%s'%s. It should be set to one of: %v", + [friendly_resource_name, resource_value_name, attribute_path_string, formatted_value, shared.empty_message(this_nc.value), this_nc.allowed] + ) +} else = msg if { + count(nc_list) > 1 + failures := concat(", ", [sprintf("position %d '%s' (allowed: %v)", [i, nc.value, nc.allowed]) | some i, nc in nc_list]) + msg := sprintf( + "%s '%s' has '%s' set to '%s'. Multiple positions failed: %s", + [friendly_resource_name, resource_value_name, attribute_path_string, full_value, failures] + ) +} + diff --git a/policies/_helpers/policies/range.rego b/policies/_helpers/policies/range.rego new file mode 100644 index 000000000..93a8ceed3 --- /dev/null +++ b/policies/_helpers/policies/range.rego @@ -0,0 +1,88 @@ +package terraform.helpers.policies.range + +# Range Policy +# +# Detects resources with numeric attributes outside specified bounds. +# Both lower and upper bounds are required. +# +# Example: [10, 100] requires value between 10 and 100 (inclusive) + +import data.terraform.helpers.shared + +################################################################################ +# Range Validation Utilities +################################################################################ + +# Checks if a value is within the specified range (inclusive) +_test_value_range(value, lower_bound, upper_bound) if { + value >= lower_bound + value <= upper_bound +} + +################################################################################ +# Public API +################################################################################ + +# Identifies resources with numeric attributes outside specified range +# +# Parameters: +# tf_variables - Resource metadata +# attribute_path - Path to numeric attribute +# values_formatted - Two-element array [lower_bound, upper_bound] +# +# Returns: +# Set of violation objects with {name, message} +get_violations(tf_variables, attribute_path, values_formatted) = results if { + count(values_formatted) == 2 + lower_bound := values_formatted[0] + upper_bound := values_formatted[1] + + nc_resources := _get_resources(tf_variables.resource_type, attribute_path, lower_bound, upper_bound) + results := { + _build_violation(tf_variables, attribute_path, lower_bound, upper_bound, resource) | + some resource in nc_resources + } +} + +_build_violation(tf_variables, attribute_path, lower_bound, upper_bound, resource) = violation if { + attribute_path_string := shared.format_attribute_path(attribute_path) + attribute_value := shared.get_attribute_value(resource, attribute_path) + + violation := { + "name": shared.get_resource_attribute(resource, tf_variables.resource_value_name), + "message": _format_message( + tf_variables.friendly_resource_name, + shared.get_resource_attribute(resource, tf_variables.resource_value_name), + attribute_path_string, + attribute_value, + shared.empty_message(attribute_value), + lower_bound, + upper_bound + ) + } +} + +_get_resources(resource_type, attribute_path, lower_bound, upper_bound) = resources if { + resources := { + resource | + resource := input.planned_values.root_module.resources[_] + resource.type == resource_type + attribute_value := to_number(shared.get_attribute_value(resource, attribute_path)) + not _test_value_range(attribute_value, lower_bound, upper_bound) + } +} + +_format_message( + friendly_resource_name, + resource_value_name, + attribute_path_string, + nc_value, + empty, + lower_bound, + upper_bound +) = msg if { + msg := sprintf( + "%s '%s' has '%s' set to '%v'%s. It must be between %v and %v", + [friendly_resource_name, resource_value_name, attribute_path_string, nc_value, empty, lower_bound, upper_bound] + ) +} diff --git a/policies/_helpers/policies/whitelist.rego b/policies/_helpers/policies/whitelist.rego new file mode 100644 index 000000000..7e1442f5f --- /dev/null +++ b/policies/_helpers/policies/whitelist.rego @@ -0,0 +1,72 @@ +package terraform.helpers.policies.whitelist + +# Whitelist Policy +# +# Detects resources with attributes NOT matching allowed values. +# Supports both scalar values and arrays with AND logic (all must be allowed). + +import data.terraform.helpers.shared + +# Identifies resources violating whitelist constraints +# +# Parameters: +# tf_variables - Resource metadata (resource_type, friendly_resource_name, value_name) +# attribute_path - Path to attribute being evaluated (array or string) +# compliant_values - Array of allowed values +# +# Returns: +# Set of violation objects with {name, message} +get_violations(tf_variables, attribute_path, compliant_values) = results if { + nc_resources := _get_resources(tf_variables.resource_type, attribute_path, compliant_values) + results := { + _build_violation(tf_variables, attribute_path, compliant_values, resource) | + some resource in nc_resources + } +} + +_build_violation(tf_variables, attribute_path, compliant_values, resource) = violation if { + attribute_path_string := shared.format_attribute_path(attribute_path) + attribute_value := shared.get_attribute_value(resource, attribute_path) + + violation := { + "name": shared.get_resource_attribute(resource, tf_variables.resource_value_name), + "message": _format_message( + tf_variables.friendly_resource_name, + shared.get_resource_attribute(resource, tf_variables.resource_value_name), + attribute_path_string, + attribute_value, + shared.empty_message(attribute_value), + compliant_values + ) + } +} + +# Check if a value is whitelisted (handles both scalars and arrays) +_is_whitelisted(allowed, value) if { + # Array case: ALL elements must be allowed (AND logic) + is_array(value) + allowed_set := {x | some x in allowed} + value_set := {x | some x in value} + object.subset(allowed_set, value_set) +} + +_is_whitelisted(allowed, value) if { + # Scalar case: direct membership check + shared.value_in_array(allowed, value) +} + +_get_resources(resource_type, attribute_path, compliant_values) = resources if { + resources := { + resource | + resource := input.planned_values.root_module.resources[_] + resource.type == resource_type + not _is_whitelisted(compliant_values, shared.get_attribute_value(resource, attribute_path)) + } +} + +_format_message(friendly_resource_name, resource_value_name, attribute_path_string, nc_value, empty, compliant_values) = msg if { + msg := sprintf( + "%s '%s' has '%s' set to '%v'%s. It should be set to '%v'", + [friendly_resource_name, resource_value_name, attribute_path_string, nc_value, empty, compliant_values] + ) +} diff --git a/policies/_helpers/shared.rego b/policies/_helpers/shared.rego new file mode 100644 index 000000000..b62a7f4bd --- /dev/null +++ b/policies/_helpers/shared.rego @@ -0,0 +1,165 @@ +package terraform.helpers.shared + +# Shared utility functions used by all policy modules +# No imports to avoid circular dependencies + +################################################################################ +# Resource Attribute Extraction +################################################################################ + +# Retrieves a resource's attribute value with defensive fallback logic +# +# This function handles variations in Terraform resource structure by attempting +# multiple lookup paths. Different resource types and states (planned vs existing) +# may store attributes in different locations within the resource object. +# +# Lookup sequence: +# 1. resource.values[attribute_key] - Primary path for planned resource values +# 2. resource[attribute_key] - Fallback for direct attribute access +# 3. null - Returns null and prints diagnostic error if both paths fail +# +# Parameters: +# tf_resource_object - A Terraform resource object from the plan +# attribute_key - The attribute name to extract (e.g., "name", "id", "bucket") +# +# Returns: +# Value of the specified attribute, or null if attribute doesn't exist +# +# Example: get_resource_attribute(s3_resource, "bucket") → "my-app-logs" +get_resource_attribute(tf_resource_object, attribute_key) = attribute_value if { + tf_resource_object.values[attribute_key] + attribute_value := tf_resource_object.values[attribute_key] +} else = attribute_value if { + attribute_value := tf_resource_object[attribute_key] +} else = null if { + print(sprintf("Resource attribute '%s' for resource type '%s' was not found! Your 'resource_value_name' in vars is wrong. Try 'resource_value_name': 'name'.", [attribute_key, tf_resource_object.type])) +} + +################################################################################ +# Attribute Path Formatting +################################################################################ +# This code is used by policies to convert error messages from: +# ["status", 0, "restricted_services"] → "status.[0].restricted_services"all this code +# Converts values from an int to a string but leaves strings as is + + +# Converts values from an int to a string but leaves strings as is +convert_value(x) = string if { + type_name(x) == "number" + string := sprintf("[%v]", [x]) +} + +convert_value(x) = x if { + type_name(x) == "string" +} + +# Converts each entry in attribute path into a string +get_attribute_path(attribute_path) = result if { + is_array(attribute_path) + result := [ val | + x := attribute_path[_] + val := convert_value(x) + ] +} + +# Returns a formatted string of any given attribute path +# Example: ["status", 0, "restricted_services"] → "status.[0].restricted_services" +format_attribute_path(attribute_path) = string_path if { + is_array(attribute_path) + string_path := concat(".", get_attribute_path(attribute_path)) +} + +format_attribute_path(attribute_path) = string_path if { + is_string(attribute_path) + string_path := replace(attribute_path, "_", " ") +} + +################################################################################ +# Data Normalization +################################################################################ + +# Normalizes input values into an array format +# Accepts either a single value or an array and ensures array output +# Used to handle flexible policy definition formats +ensure_array(values) = values if { + is_array(values) +} +ensure_array(values) = [values] if { + not is_array(values) +} + +# Get attribute value from a resource with null fallback +# Simplifies the common pattern of accessing nested resource attributes +# +# Enhanced: Array-of-Objects Field Extraction (Added 2025-12-04) +# When the attribute path ends with a string field name and leads to an array of objects, +# this function automatically extracts that field from each object in the array. +get_attribute_value(resource, attribute_path) := extracted_values if { + # Check if this might be an array-of-objects extraction pattern + count(attribute_path) > 1 + last_element := attribute_path[count(attribute_path) - 1] + is_string(last_element) + + # Get the path to the array (everything except the last element) + array_path := array.slice(attribute_path, 0, count(attribute_path) - 1) + array_value := object.get(resource.values, array_path, null) + + # If it's an array of objects, extract the field from each + is_array(array_value) + count(array_value) > 0 + is_object(array_value[0]) + + # Extract the field from each object in the array + extracted_values := [obj[last_element] | obj := array_value[_]; obj[last_element] != null] +} else := object.get(resource.values, attribute_path, null) + +# Searches an array of objects for a specific key and returns its value +# Used to extract metadata from condition groups +get_value_from_array(arr, key) = value if { + some i + obj := arr[i] + obj[key] != null + value := obj[key] +} + +################################################################################ +# Empty Value Handling +################################################################################ + +# Returns warning string for empty values, empty string otherwise +# Handles empty strings and null values gracefully +empty_message(value) = " (EMPTY!)" if { + value == "" +} + +empty_message(value) = "" if { + value != "" +} + +################################################################################ +# Array Membership Checking +################################################################################ + +# Generic helper: Check if a scalar value exists in an array +# Used by policy modules for simple membership testing +value_in_array(arr, value) if { + not is_array(value) + arr[_] == value +} + +################################################################################ +# Regex Pattern Utilities (for pattern policies) +################################################################################ + +# Gets the target * pattern - extracts substrings matching wildcard positions +get_target_list(resource, attribute_path, target) = target_list if { + p := regex.replace(target, "\\*", "([^/]+)") + target_value := object.get(resource.values, attribute_path, null) + matches := regex.find_all_string_submatch_n(p, target_value, 1)[0] # all matches, including main string + target_list := array.slice(matches, 1, count(matches)) # leaves every single * match except main string +} else := "Wrong pattern" + +# Formats pattern with quotes for display +final_formatter(target, sub_pattern) = final_format if { + final_format := regex.replace(target, sub_pattern, sprintf("'%s'", [sub_pattern])) +} \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_channel/description/policy.rego b/policies/gcp/backup_for_gke/backup_channel/description/policy.rego new file mode 100644 index 000000000..ad3bd0551 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_channel/description/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_channel.description + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_channel.vars +import data.terraform.helpers.policies.blacklist + +# Description should not be empty or null +violations := blacklist.get_violations( + vars.variables, + ["description"], + ["", null] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_channel/destination_project/policy.rego b/policies/gcp/backup_for_gke/backup_channel/destination_project/policy.rego new file mode 100644 index 000000000..5df4f4c0d --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_channel/destination_project/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_channel.destination_project + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_channel.vars +import data.terraform.helpers.policies.pattern_whitelist + +# Ensure backup channel uses approved project pattern +violations := pattern_whitelist.get_violations( + vars.variables, + ["destination_project"], + ["projects/*/locations/australia-southeast1", [[], []]] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego b/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego new file mode 100644 index 000000000..1abf1ff6b --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_channel.labels + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_channel.vars +import data.terraform.helpers.policies.whitelist + +# Required labels must be present +violations := whitelist.get_violations( + vars.variables, + ["labels", "environment"], + ["prod", "staging", "dev"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_channel/location/policy.rego b/policies/gcp/backup_for_gke/backup_channel/location/policy.rego new file mode 100644 index 000000000..e7dec28ff --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_channel/location/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_channel.location + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_channel.vars +import data.terraform.helpers.policies.whitelist + +# Australian data residency requirement +violations := whitelist.get_violations( + vars.variables, + ["location"], + ["australia-southeast1", "australia-southeast2"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_channel/name/policy.rego b/policies/gcp/backup_for_gke/backup_channel/name/policy.rego new file mode 100644 index 000000000..c1c121bdd --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_channel/name/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_channel.name + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_channel.vars +import data.terraform.helpers.policies.pattern_whitelist + +# Name must follow naming convention +violations := pattern_whitelist.get_violations( + vars.variables, + ["name"], + ["gke-backup-channel-*", [[]]] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_channel/vars.rego b/policies/gcp/backup_for_gke/backup_channel/vars.rego new file mode 100644 index 000000000..aae1f96b0 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_channel/vars.rego @@ -0,0 +1,8 @@ +package terraform.gcp.security.backup_for_gke.backup_channel.vars + +import rego.v1 +variables := { + "friendly_resource_name": "GKE Backup Channel", + "resource_type": "google_gke_backup_backup_channel", + "resource_value_name": "name" +} \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/all_namespaces/policy.rego b/policies/gcp/backup_for_gke/backup_plan/all_namespaces/policy.rego new file mode 100644 index 000000000..fdb74e8c0 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/all_namespaces/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.all_namespaces + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.blacklist + +# Blacklist all_namespaces=true (violates least privilege) +violations := blacklist.get_violations( + vars.variables, + ["backup_config", 0, "all_namespaces"], + [true] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego b/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego new file mode 100644 index 000000000..410ed3612 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.backup_config + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.blacklist + +# Backup config must not be empty +violations := blacklist.get_violations( + vars.variables, + ["backup_config"], + [[], null] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/policy.rego b/policies/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/policy.rego new file mode 100644 index 000000000..751b41a17 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.backup_delete_lock_days + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.range + +# Ransomware protection: Minimum 14 days, maximum 90 days +violations := range.get_violations( + vars.variables, + ["retention_policy", 0, "backup_delete_lock_days"], + [14, 90] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/backup_schedule/policy.rego b/policies/gcp/backup_for_gke/backup_plan/backup_schedule/policy.rego new file mode 100644 index 000000000..84caafd67 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/backup_schedule/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.backup_schedule + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.whitelist + +# Backup schedule must be defined +violations := whitelist.get_violations( + vars.variables, + ["backup_schedule", 0, "cron_schedule"], + ["0 2 * * *", "0 3 * * *", "0 4 * * *"] # Daily backups at 2, 3, or 4 AM +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/deactivated/policy.rego b/policies/gcp/backup_for_gke/backup_plan/deactivated/policy.rego new file mode 100644 index 000000000..6098ce8b8 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/deactivated/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.deactivated + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.blacklist + +# Backup plans should not be deactivated +violations := blacklist.get_violations( + vars.variables, + ["deactivated"], + [true] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/description/policy.rego b/policies/gcp/backup_for_gke/backup_plan/description/policy.rego new file mode 100644 index 000000000..2e203420b --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/description/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.description + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.blacklist + +# Description should not be empty or null +violations := blacklist.get_violations( + vars.variables, + ["description"], + ["", null] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego b/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego new file mode 100644 index 000000000..816a6d8b8 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.encryption_key + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.pattern_whitelist + +# CMEK must be in australia-southeast1 region +violations := pattern_whitelist.get_violations( + vars.variables, + ["backup_config", 0, "encryption_key", "kms_key_name"], + ["projects/*/locations/*/keyRings/*/cryptoKeys/*", [[], ["australia-southeast1"], [], []]] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/include_secrets/policy.rego b/policies/gcp/backup_for_gke/backup_plan/include_secrets/policy.rego new file mode 100644 index 000000000..0e2b4c70f --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/include_secrets/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.include_secrets + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.blacklist + +# Secrets should not be included in backups +violations := blacklist.get_violations( + vars.variables, + ["backup_config", 0, "include_secrets"], + [true] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego b/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego new file mode 100644 index 000000000..5943862a2 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.labels + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.whitelist + +# Required labels must be present +violations := whitelist.get_violations( + vars.variables, + ["labels", "environment"], + ["prod", "staging", "dev"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/name/policy.rego b/policies/gcp/backup_for_gke/backup_plan/name/policy.rego new file mode 100644 index 000000000..d29e04a6d --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/name/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.name + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.pattern_whitelist + +# Name must follow naming convention +violations := pattern_whitelist.get_violations( + vars.variables, + ["name"], + ["gke-backup-plan-*", [[]]] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/permissive_mode/policy.rego b/policies/gcp/backup_for_gke/backup_plan/permissive_mode/policy.rego new file mode 100644 index 000000000..ab9452e83 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/permissive_mode/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.permissive_mode + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.blacklist + +# Permissive mode should not be enabled +violations := blacklist.get_violations( + vars.variables, + ["backup_config", 0, "permissive_mode"], + [true] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/retention_policy/policy.rego b/policies/gcp/backup_for_gke/backup_plan/retention_policy/policy.rego new file mode 100644 index 000000000..de9e64292 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/retention_policy/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.retention_policy + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars +import data.terraform.helpers.policies.range + +# Retention period in days (7 to 90 days) +violations := range.get_violations( + vars.variables, + ["retention_policy", 0, "backup_retain_days"], + [7, 90] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/vars.rego b/policies/gcp/backup_for_gke/backup_plan/vars.rego new file mode 100644 index 000000000..e3d1929ba --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/vars.rego @@ -0,0 +1,8 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.vars + +import rego.v1 +variables := { + "resource_type": "google_gke_backup_backup_plan", + "friendly_resource_name": "GKE Backup Plan", + "resource_value_name": "name" +} \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/custom_roles/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/custom_roles/policy.rego new file mode 100644 index 000000000..528a913bc --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam/custom_roles/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam.custom_roles + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars +import data.terraform.helpers.policies.blacklist + +# Prevent use of custom roles (harder to audit) +violations := blacklist.get_violations( + vars.variables, + ["role"], + ["organizations/*/roles/*", "projects/*/roles/*"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/domain_access/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/domain_access/policy.rego new file mode 100644 index 000000000..ce8632d78 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam/domain_access/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam.domain_access + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars +import data.terraform.helpers.policies.element_blacklist + +# Block personal email domains +violations := element_blacklist.get_violations( + vars.variables, + ["members"], + ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/policy.rego new file mode 100644 index 000000000..7bfdb36df --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam.external_service_accounts + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars +import data.terraform.helpers.policies.element_blacklist + +# Prevent external service accounts +violations := element_blacklist.get_violations( + vars.variables, + ["members"], + ["serviceAccount:*@*.iam.gserviceaccount.com"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/federated_identities/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/federated_identities/policy.rego new file mode 100644 index 000000000..a16d9807c --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam/federated_identities/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam.federated_identities + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars +import data.terraform.helpers.policies.blacklist + +# Control federated identities +violations := blacklist.get_violations( + vars.variables, + ["members"], + ["principal://iam.googleapis.com/*", "principalSet://iam.googleapis.com/*"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/members/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/members/policy.rego new file mode 100644 index 000000000..7e9983fc8 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam/members/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam.members + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars +import data.terraform.helpers.policies.element_blacklist + +# Blacklist personal email domains and public access +violations := element_blacklist.get_violations( + vars.variables, + ["members"], + ["@gmail.com", "@hotmail.com", "@yahoo.com", "allUsers", "allAuthenticatedUsers"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/project_roles/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/project_roles/policy.rego new file mode 100644 index 000000000..58d499f84 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam/project_roles/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam.project_roles + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars +import data.terraform.helpers.policies.blacklist + +# Prevent project-wide roles for backup plans +violations := blacklist.get_violations( + vars.variables, + ["role"], + ["roles/gkebackup.admin", "roles/gkebackup.backupAdmin"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/role/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/role/policy.rego new file mode 100644 index 000000000..60257606a --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam/role/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam.role + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars +import data.terraform.helpers.policies.blacklist + +# Prevent overly permissive roles +violations := blacklist.get_violations( + vars.variables, + ["role"], + ["roles/owner", "roles/editor"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/vars.rego b/policies/gcp/backup_for_gke/backup_plan_iam/vars.rego new file mode 100644 index 000000000..d729bd133 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam/vars.rego @@ -0,0 +1,8 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam.vars + +import rego.v1 +variables := { + "friendly_resource_name": "GKE Backup Plan IAM", + "resource_type": "google_gke_backup_backup_plan_iam_binding", + "resource_value_name": "name" +} \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_channel/description/policy.rego b/policies/gcp/backup_for_gke/restore_channel/description/policy.rego new file mode 100644 index 000000000..af50c7756 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_channel/description/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_channel.description + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_channel.vars +import data.terraform.helpers.policies.blacklist + +# Description should not be empty or null +violations := blacklist.get_violations( + vars.variables, + ["description"], + ["", null] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_channel/destination_project/policy.rego b/policies/gcp/backup_for_gke/restore_channel/destination_project/policy.rego new file mode 100644 index 000000000..67dd7c409 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_channel/destination_project/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_channel.destination_project + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_channel.vars +import data.terraform.helpers.policies.pattern_whitelist + +# Ensure restore channel uses approved project pattern +violations := pattern_whitelist.get_violations( + vars.variables, + ["destination_project"], + ["projects/*/locations/australia-southeast1", [[], []]] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_channel/labels/policy.rego b/policies/gcp/backup_for_gke/restore_channel/labels/policy.rego new file mode 100644 index 000000000..744529e71 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_channel/labels/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_channel.labels + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_channel.vars +import data.terraform.helpers.policies.whitelist + +# Required labels must be present +violations := whitelist.get_violations( + vars.variables, + ["labels", "environment"], + ["prod", "staging", "dev"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_channel/location/policy.rego b/policies/gcp/backup_for_gke/restore_channel/location/policy.rego new file mode 100644 index 000000000..19e6a9dd1 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_channel/location/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_channel.location + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_channel.vars +import data.terraform.helpers.policies.whitelist + +# Australian data residency requirement +violations := whitelist.get_violations( + vars.variables, + ["location"], + ["australia-southeast1", "australia-southeast2"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_channel/name/policy.rego b/policies/gcp/backup_for_gke/restore_channel/name/policy.rego new file mode 100644 index 000000000..dddd44a29 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_channel/name/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_channel.name + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_channel.vars +import data.terraform.helpers.policies.pattern_whitelist + +# Name must follow naming convention +violations := pattern_whitelist.get_violations( + vars.variables, + ["name"], + ["gke-restore-channel-*", [[]]] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_channel/vars.rego b/policies/gcp/backup_for_gke/restore_channel/vars.rego new file mode 100644 index 000000000..db3b08bba --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_channel/vars.rego @@ -0,0 +1,8 @@ +package terraform.gcp.security.backup_for_gke.restore_channel.vars + +import rego.v1 +variables := { + "friendly_resource_name": "GKE Restore Channel", + "resource_type": "google_gke_backup_restore_channel", + "resource_value_name": "name" +} \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/all_namespaces/policy.rego b/policies/gcp/backup_for_gke/restore_plan/all_namespaces/policy.rego new file mode 100644 index 000000000..0725098dc --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/all_namespaces/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.all_namespaces + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.blacklist + +# Blacklist all_namespaces=true (violates least privilege) +violations := blacklist.get_violations( + vars.variables, + ["restore_config", 0, "all_namespaces"], + [true] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego b/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego new file mode 100644 index 000000000..b136d802d --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.cluster + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.pattern_whitelist + +# Ensure restore targets approved clusters only +violations := pattern_whitelist.get_violations( + vars.variables, + ["restore_config", 0, "cluster"], + ["projects/*/locations/australia-southeast*/clusters/*", [[], [], []]] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/cluster_resource_scope/policy.rego b/policies/gcp/backup_for_gke/restore_plan/cluster_resource_scope/policy.rego new file mode 100644 index 000000000..b5e4a04b3 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/cluster_resource_scope/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.cluster_resource_scope + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.blacklist + +# Prevent restoration of all cluster resources +violations := blacklist.get_violations( + vars.variables, + ["restore_config", 0, "cluster_resource_restore_scope", 0, "all_group_kinds"], + [true] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/conflict_policy/policy.rego b/policies/gcp/backup_for_gke/restore_plan/conflict_policy/policy.rego new file mode 100644 index 000000000..97d3a3f85 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/conflict_policy/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.conflict_policy + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.whitelist + +# Only allow safe conflict resolution +violations := whitelist.get_violations( + vars.variables, + ["restore_config", 0, "cluster_resource_conflict_policy"], + ["USE_EXISTING_VERSION"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/descripttion/policy.rego b/policies/gcp/backup_for_gke/restore_plan/descripttion/policy.rego new file mode 100644 index 000000000..e9e003832 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/descripttion/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.description + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.blacklist + +# Description should not be empty or null +violations := blacklist.get_violations( + vars.variables, + ["description"], + ["", null] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego b/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego new file mode 100644 index 000000000..a102bf72f --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.excluded_namespaces + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.element_blacklist + +# Prevent exclusion of critical namespaces +violations := element_blacklist.get_violations( + vars.variables, + ["restore_config", 0, "excluded_namespaces", "namespaces"], + ["kube-system", "kube-public", "kube-node-lease", "gke-system"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/field_actions/policy.rego b/policies/gcp/backup_for_gke/restore_plan/field_actions/policy.rego new file mode 100644 index 000000000..4fc258f29 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/field_actions/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.field_actions + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.whitelist + +# Only allow safe field actions +violations := whitelist.get_violations( + vars.variables, + ["restore_config", 0, "transformation_rules", 0, "field_actions", 0, "op"], + ["REMOVE", "REPLACE", "ADD"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/transformation_rules/policy.rego b/policies/gcp/backup_for_gke/restore_plan/transformation_rules/policy.rego new file mode 100644 index 000000000..451b75572 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/transformation_rules/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.transformation_rules + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.whitelist + +# Must have transformation rules defined +violations := whitelist.get_violations( + vars.variables, + ["restore_config", 0, "transformation_rules", 0, "field_actions"], + [["REMOVE"], ["REPLACE"]] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/vars.rego b/policies/gcp/backup_for_gke/restore_plan/vars.rego new file mode 100644 index 000000000..b098e7b30 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/vars.rego @@ -0,0 +1,8 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.vars + +import rego.v1 +variables := { + "friendly_resource_name": "GKE Restore Plan", + "resource_type": "google_gke_backup_restore_plan", + "resource_value_name": "name" +} \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego b/policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego new file mode 100644 index 000000000..25a92ead8 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.volume_bindings + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.whitelist + +# Volume restore policy must be defined +violations := whitelist.get_violations( + vars.variables, + ["restore_config", 0, "volume_data_restore_policy"], + ["RESTORE_VOLUME_DATA_FROM_BACKUP", "NO_VOLUME_DATA_RESTORATION", "REUSE_VOLUME_HANDLE_FROM_BACKUP"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/volume_data_restore/policy.rego b/policies/gcp/backup_for_gke/restore_plan/volume_data_restore/policy.rego new file mode 100644 index 000000000..ce344d595 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/volume_data_restore/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.volume_data_restore + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars +import data.terraform.helpers.policies.whitelist + +# Only allow safe volume restoration policies +violations := whitelist.get_violations( + vars.variables, + ["restore_config", 0, "volume_data_restore_policy"], + ["RESTORE_VOLUME_DATA_FROM_BACKUP", "NO_VOLUME_DATA_RESTORATION"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/domain_access/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/domain_access/policy.rego new file mode 100644 index 000000000..9628653b5 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam/domain_access/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam.domain_access + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars +import data.terraform.helpers.policies.element_blacklist + +# Prevent external domain access +violations := element_blacklist.get_violations( + vars.variables, + ["members"], + ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/member_count/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/member_count/policy.rego new file mode 100644 index 000000000..3aff68734 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam/member_count/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam.member_count + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars +import data.terraform.helpers.policies.range + +# Limit number of members (between 1 and 10) +violations := range.get_violations( + vars.variables, + ["members_count"], + [1, 10] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/personal_emails/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/personal_emails/policy.rego new file mode 100644 index 000000000..205733531 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam/personal_emails/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam.personal_emails + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars +import data.terraform.helpers.policies.element_blacklist + +# Blacklist personal email domains +violations := element_blacklist.get_violations( + vars.variables, + ["members"], + ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/project_roles/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/project_roles/policy.rego new file mode 100644 index 000000000..8a627a1d6 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam/project_roles/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam.project_roles + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars +import data.terraform.helpers.policies.blacklist + +# Prevent project-wide roles for restore plans +violations := blacklist.get_violations( + vars.variables, + ["role"], + ["roles/gkebackup.admin", "roles/gkebackup.restoreAdmin"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/public_access/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/public_access/policy.rego new file mode 100644 index 000000000..1a36e2205 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam/public_access/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam.public_access + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars +import data.terraform.helpers.policies.element_blacklist + +# Prevent public access +violations := element_blacklist.get_violations( + vars.variables, + ["members"], + ["allUsers", "allAuthenticatedUsers"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/restore_permissions/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/restore_permissions/policy.rego new file mode 100644 index 000000000..bfd847732 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam/restore_permissions/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam.restore_permissions + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars +import data.terraform.helpers.policies.whitelist + +# Only allow specific restore permissions +violations := whitelist.get_violations( + vars.variables, + ["role"], + ["roles/gkebackup.viewer", "roles/gkebackup.restoreAgent"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/role/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/role/policy.rego new file mode 100644 index 000000000..48c5a0586 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam/role/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam.role + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars +import data.terraform.helpers.policies.blacklist + +# Blacklist overly permissive roles +violations := blacklist.get_violations( + vars.variables, + ["role"], + ["roles/owner", "roles/editor", "roles/gkebackup.admin"] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/service_accounts/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/service_accounts/policy.rego new file mode 100644 index 000000000..1af18cf54 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam/service_accounts/policy.rego @@ -0,0 +1,17 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam.service_accounts + +import rego.v1 +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars +import data.terraform.helpers.policies.pattern_whitelist + +# Only allow project service accounts +violations := pattern_whitelist.get_violations( + vars.variables, + ["members"], + ["serviceAccount:*@fluent-coder-468700-h4.iam.gserviceaccount.com", [[]]] +) + +message := [m | + some violation in violations + m := violation.message +] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/vars.rego b/policies/gcp/backup_for_gke/restore_plan_iam/vars.rego new file mode 100644 index 000000000..216b3feed --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam/vars.rego @@ -0,0 +1,8 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam.vars + +import rego.v1 +variables := { + "friendly_resource_name": "GKE Restore Plan IAM", + "resource_type": "google_gke_backup_restore_plan_iam_binding", + "resource_value_name": "name" +} \ No newline at end of file diff --git a/templates/gcp/c.tf b/templates/gcp/c.tf new file mode 100644 index 000000000..9343bf01c --- /dev/null +++ b/templates/gcp/c.tf @@ -0,0 +1,6 @@ +# Describe your resource type here +# Keep "c" as the name to indicate that this resource and its attributes are compliant + +resource "RESOURCE TYPE" "c" { + +} diff --git a/templates/gcp/config.tf b/templates/gcp/config.tf new file mode 100644 index 000000000..9f4356520 --- /dev/null +++ b/templates/gcp/config.tf @@ -0,0 +1,11 @@ +##### DO NOT EDIT ###### + +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} \ No newline at end of file diff --git a/templates/gcp/nc.tf b/templates/gcp/nc.tf new file mode 100644 index 000000000..76e41151f --- /dev/null +++ b/templates/gcp/nc.tf @@ -0,0 +1,6 @@ +# Describe your resource type here +# Keep "nc" as the name to indicate that this resource and its attributes are non-compliant + +resource "RESOURCE TYPE" "nc" { + +} \ No newline at end of file diff --git a/templates/gcp/policy.rego b/templates/gcp/policy.rego new file mode 100644 index 000000000..86198ff34 --- /dev/null +++ b/templates/gcp/policy.rego @@ -0,0 +1,121 @@ +package terraform.gcp.security... # Edit here +import data.terraform.gcp.helpers +import data.terraform.gcp.security...vars + +# STEP 1: STUDY YOUR RESOURCE AND ITS ATTRIBUTES, THEN FILL IN THE VARS FILE + +# STEP 2: CREATE SCENARIOS (can be simple (one condition) or complex (multiple linked conditions) ) +conditions := [ + [ + {"situation_description" : "A self documenting message about the conditions within", + "remedies":[ "Something that fixes the issues in this situation","You can have multiple items in the array"]}, + { + "condition": "A message about what the condition does", + "attribute_path" : [], # An array of strings and indicies eg. ["rsa",0,"key"] + "values" : [], # Values to compare against + "policy_type" : "" # Policy type eg. 'whitelist', 'blacklist', 'range', 'pattern whitelist', 'pattern blacklist' + } + ] +] + """ + Examples + Remove this in actual policies + + Whitelist like previous policies + [ + {"situation_description" : "Resource is not using Linux", + "remedies":[ "Change the OS to linux"]}, + { + "condition": "Test if an OS is not Linux", + "attribute_path" : ["parent"], + "values" : ["Linux"], + "policy_type" : "whitelist" + } + ] + + Blacklist - Disallow the use of specific values + + [ + {"situation_description" : "Resource is using Linux", + "remedies":[ "Change the OS from linux"]}, + { + "condition": "Test if an OS is Linux", + "attribute_path" : ["parent"], + "values" : ["Linux"], + "policy_type" : "blacklist" + } + ] + + Range - Use with numeric data to set a minimum, maximum or range + + Minimum + [ + {"situation_description" : "Check if key is over 1000 bits", + "remedies":[ "Enforce a key over 1000 bits"]}, + { + "condition": "Test if key size is over 1000 bits", + "attribute_path" : ["rsa",0,"key"], + "values" : [1000,null], + "policy_type" : "range" + } + ] + + Maximum + [ + {"situation_description" : "Check if key is under 1000 bits", + "remedies":[ "Enforce a key under 1000 bits"]}, + { + "condition": "Test if key size is under 1000 bits", + "attribute_path" : ["rsa",0,"key"], + "values" : [null,1000], + "policy_type" : "range" + } + ] + + Range + [ + {"situation_description" : "Check if key is between 1000 and 2000 bits", + "remedies":[ "Ensure key is 1000 to 2000 bits"]}, + { + "condition": "Test if key size is within 1000 to 2000 bits", + "attribute_path" : ["rsa",0,"key"], + "values" : [1000,2000], + "policy_type" : "range" + } + ] + + Patterns + + Whitelist + [ + {"situation_description" : "Check description fits a defined pattern", + "remedies":[ "Fix description to fit pattern"]}, + { + "condition": "Wrong description pattern", + "attribute_path" : ["description"], + "values" : ["project/*/gcp/*", [["a","c","d"],["b","d"]]], # Value to be compared + "policy_type" : "pattern whitelist" # First value must be one of a,c,d. Second value must be one of b,d. + } + ] + + Blacklist + [ + {"situation_description" : "Check description fits a defined pattern", + "remedies":[ "Fix description to fit pattern"]}, + { + "condition": "Wrong description pattern", + "attribute_path" : ["description"], + "values" : ["project/*", [["root"]], # Value to be compared + "policy_type" : "pattern blacklist" # Can be any value but root + } + ] + """ + +# Displays a general message about policy compliance +# Use 'opa eval ... "data.terraform.gcp.security....message" +message := helpers.get_multi_summary(conditions, vars.variables).message + +# Displays a detailed summary of each resources compliance to every condition and situation +# Useful for debugging +# Use 'opa eval ... "data.terraform.gcp.security....details" +details := helpers.get_multi_summary(conditions, vars.variables).details \ No newline at end of file diff --git a/templates/gcp/vars.rego b/templates/gcp/vars.rego new file mode 100644 index 000000000..e52c6c328 --- /dev/null +++ b/templates/gcp/vars.rego @@ -0,0 +1,8 @@ +package terraform.gcp.security...vars + + +variables := { + "friendly_resource_name": "", # eg., "GCS Bucket", + "resource_type": "", # eg., "google_storage_bucket" + "resource_value_name" : "" # eg., "name" +} diff --git a/tests/_helpers/README.md b/tests/_helpers/README.md new file mode 100644 index 000000000..d8907db86 --- /dev/null +++ b/tests/_helpers/README.md @@ -0,0 +1,175 @@ +# Helper Policy Tests + +Unit tests for policy helper functions in `policies/_helpers/`. + +## Quick Start + +```bash +# Run all helper tests +./tests/_helpers/unit_test_helpers.sh + +# Quick integration check +./tests/_helpers/smoke_test_helpers.sh + +# Debug policy output +./tests/_helpers/policy_debug.sh + +# Review violation messages +./tests/_helpers/check_ux.sh +``` + +## Test Files + +| File | Tests | Coverage | +|------|-------|----------| +| `shared_test.rego` | 12 | Shared utilities (get_resource_attribute, format paths, etc.) | +| `blacklist_test.rego` | 10 | Blacklist policy (forbidden values) | +| `whitelist_test.rego` | 10 | Whitelist policy (required values) | +| `range_test.rego` | 8 | Range policy (numeric bounds, simplified) | +| `pattern_blacklist_test.rego` | 8 | Pattern blacklist (glob matching forbidden) | +| `pattern_whitelist_test.rego` | 8 | Pattern whitelist (glob matching required) | +| `element_blacklist_test.rego` | 8 | Element blacklist (array elements with substrings) | + +**Total:** 64 tests covering all 7 helper policies + +## Test Structure + +Each test file follows an 8-test pattern: +- **Unit tests (6):** Test individual helper functions with boundary cases +- **Integration test (1):** Realistic mocks with multiple resources +- **Reality check (1):** Uses real Terraform fixtures + +## Test Scripts + +### unit_test_helpers.sh +Runs all 7 test suites with fixtures. Use for comprehensive validation. + +### smoke_test_helpers.sh +Fast integration tests (5 policies at policy level). Use for quick feedback during development. + +### policy_debug.sh +Shows full policy output with `--format pretty`. Use when debugging failures. + +### check_ux.sh +Displays complete violation objects. Use to review user-facing error messages before merging. + +## Fixtures + +Real Terraform plans wrapped in unique keys to avoid OPA namespace conflicts. + +### Why Wrapper Structure? + +OPA loads all JSON files recursively and merges them into a single `data` namespace. When multiple files have identical top-level keys (like `format_version`, `terraform_version`), OPA throws merge conflicts. + +**Solution:** Wrap each Terraform plan in a unique outer key matching the directory name + `_plan` suffix. + +```json +{ + "gcp_storage_bucket_plan": { + "format_version": "1.2", + "terraform_version": "1.12.2", + "planned_values": { ... }, + "resource_changes": [ ... ] + } +} +``` + +### Available Fixtures + +| Fixture | Resource | Used By | Source | +|---------|----------|---------|--------| +| `gcp_storage_bucket_plan` | `google_storage_bucket` | blacklist, whitelist, range tests | `inputs/gcp/cloud_storage/google_storage_bucket/retention_period/` | +| `gcp_project_plan` | `google_project` | pattern blacklist/whitelist tests | `inputs/gcp/cloud_platform_service/google_project/project_id/` | +| `gcp_access_level_plan` | `google_access_context_manager_access_level` | shared tests (deep nesting) | `inputs/gcp/access_context_manager_vpc_service_controls/access_context_manager_access_level/device_policy/` | + +**Note:** `gcp_access_level_plan` has 5-level deep nesting, ideal for testing nested attribute extraction. + +### Using Fixtures + +```rego +test_with_fixture if { + plan := data.gcp_storage_bucket_plan # Wrapper key becomes data path + resource := plan.planned_values.root_module.resources[0] + # ... test logic +} +``` + +### Regenerating Fixtures + +When helper functions change or test cases need updates: + +```bash +# 1. Navigate to Terraform configuration +cd inputs/gcp/// + +# 2. Generate plan (if not already exists) +terraform init +terraform plan -out=plan.tfplan + +# 3. Export to JSON and wrap in unique namespace +terraform show -json plan.tfplan > plan.json +jq '{_plan: .}' plan.json > ../../../../tests/_helpers/fixtures//plan.json + +# 4. Cleanup +rm plan.json plan.tfplan +``` + +**Examples:** + +```bash +# Storage Bucket +cd inputs/gcp/cloud_storage/google_storage_bucket/retention_period +terraform show -json plan.tfplan > plan.json +jq '{gcp_storage_bucket_plan: .}' plan.json > ../../../../tests/_helpers/fixtures/gcp_storage_bucket/plan.json +rm plan.json + +# Project +cd inputs/gcp/cloud_platform_service/google_project/project_id +terraform show -json plan.tfplan > plan.json +jq '{gcp_project_plan: .}' plan.json > ../../../../tests/_helpers/fixtures/gcp_project/plan.json +rm plan.json + +# Access Level +cd inputs/gcp/access_context_manager_vpc_service_controls/access_context_manager_access_level/device_policy +terraform show -json plan.tfplan > plan.json +jq '{gcp_access_level_plan: .}' plan.json > ../../../../tests/_helpers/fixtures/gcp_access_level/plan.json +rm plan.json +``` + +### Creating New Fixtures + +Follow this pattern for new fixtures: + +```bash +# 1. Create fixture directory (name becomes data path prefix) +mkdir tests/_helpers/fixtures/gcp_compute_instance + +# 2. Navigate to relevant Terraform configuration +cd inputs/gcp//google_compute_instance/ + +# 3. Generate Terraform plan +terraform init +terraform plan -out=plan.tfplan +terraform show -json plan.tfplan > plan.json + +# 4. Wrap with unique key matching directory name + _plan +jq '{gcp_compute_instance_plan: .}' plan.json > ../../../../tests/_helpers/fixtures/gcp_compute_instance/plan.json + +# 5. Cleanup +rm plan.json plan.tfplan + +# 6. Access in tests as data.gcp_compute_instance_plan +``` + +**Key requirements:** +- Directory name must match wrapper key prefix (e.g., `gcp_compute_instance/` → `gcp_compute_instance_plan`) +- Always use `jq` to wrap the plan (prevents namespace conflicts) +- Source Terraform configs from `inputs/gcp/` directory + +## Adding New Tests + +1. Create `_test.rego` in `tests/_helpers/` +2. Follow 8-test pattern (6 unit + 1 integration + 1 reality check) +3. Use fixtures for reality checks: `data._plan` +4. Update `unit_test_helpers.sh` to include new test file +5. Run tests to verify: `./tests/_helpers/unit_test_helpers.sh` diff --git a/tests/_helpers/blacklist_test.rego b/tests/_helpers/blacklist_test.rego new file mode 100644 index 000000000..a0d9954a7 --- /dev/null +++ b/tests/_helpers/blacklist_test.rego @@ -0,0 +1,315 @@ +package terraform.helpers.policies.blacklist_test + +# Blacklist Policy Test Suite +# +# Tests the blacklist policy module which detects resources with forbidden values. +# Covers scalar values, array OR logic, empty array special case, and message formatting. + +import data.terraform.helpers.policies.blacklist +import data.terraform.helpers.shared +import data.terraform.helpers.shared_test +import rego.v1 + +# ============================================================================== +# UNIT TESTS (6): Test _is_blacklisted helper function +# ============================================================================== + +# Test 1: Scalar value in blacklist (boundary: match) +test_is_blacklisted_scalar_match if { + blacklist._is_blacklisted(["forbidden", "banned"], "forbidden") +} + +# Test 2: Scalar value not in blacklist (boundary: no match) +test_is_blacklisted_scalar_no_match if { + not blacklist._is_blacklisted(["forbidden", "banned"], "allowed") +} + +# Test 3: Array with ANY blacklisted value (OR logic proof) +test_is_blacklisted_array_any_match if { + blacklist._is_blacklisted(["bad", "evil"], ["good", "bad", "ugly"]) +} + +# Test 4: Array with NO blacklisted values (OR logic negative) +test_is_blacklisted_array_no_match if { + not blacklist._is_blacklisted(["bad", "evil"], ["good", "ugly"]) +} + +# Test 5: Empty array blacklisting (critical edge case) +test_is_blacklisted_empty_array if { + blacklist._is_blacklisted([[]], []) +} + +# ============================================================================== +# MOCK DATA PROVENANCE +# ============================================================================== +# Minimal mocks in tests 6-10 are synthetic, designed to test specific logic paths. +# They represent simplified versions of real Terraform resources with controlled +# attributes to validate exact behavior (e.g., single violation, edge cases). +# +# Reality check (test 8) uses: tests/_helpers/fixtures/gcp_storage_bucket/plan.json +# Source: inputs/gcp/cloud_storage/google_storage_bucket/retention_period/ +# Purpose: Tests against actual Terraform plan structure with 2 buckets: +# - c123: retention_period=604800 (7 days), location=US, force_destroy=true +# - nc123: retention_period=2692000 (31 days), location=US, force_destroy=true +# ============================================================================== + +# Test 6: get_violations with minimal mock (happy path + structure validation) +test_get_violations_minimal if { + # Minimal mock with blacklisted location + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_storage_bucket", + "values": { + "name": "test-bucket", + "location": "US", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + violations := blacklist.get_violations( + tf_variables, + ["location"], + ["US"], + ) with input as mock_input + + count(violations) == 1 + some v in violations + v.name == "test-bucket" + shared_test._assert_valid_violation(v) + contains(v.message, "test-bucket") # Resource name + contains(v.message, "US") # Violating value + contains(v.message, "blacklisted") # Verdict +} + +# ============================================================================== +# INTEGRATION TEST (1): Realistic structure with edge cases +# ============================================================================== + +# Test 7: get_violations with realistic Terraform structures +test_get_violations_realistic if { + # Realistic mock including edge cases + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + # Normal resource with blacklisted value + { + "type": "google_storage_bucket", + "values": { + "name": "violating-bucket", + "location": "US", + "storage_class": "STANDARD", + }, + }, + # Resource with allowed value + { + "type": "google_storage_bucket", + "values": { + "name": "compliant-bucket", + "location": "EU", + "storage_class": "STANDARD", + }, + }, + # Resource with null location (edge case) + { + "type": "google_storage_bucket", + "values": { + "name": "null-bucket", + "location": null, + "storage_class": "STANDARD", + }, + }, + # Different resource type (should be ignored) + { + "type": "google_project", + "values": { + "name": "test-project", + "location": "US", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + violations := blacklist.get_violations( + tf_variables, + ["location"], + ["US"], + ) with input as mock_input + + # Should only flag the violating bucket + count(violations) == 1 + violation_names := {v.name | some v in violations} + violation_names == {"violating-bucket"} + + some v in violations + contains(v.message, "Storage Bucket") + contains(v.message, "location") + contains(v.message, "'US'") +} + +# ============================================================================== +# REALITY CHECK (1): Test with real Terraform plan structure +# ============================================================================== + +# Test 8: get_violations with real Terraform plan +test_real_plan_violations if { + # Use real fixture - gcp_storage_bucket from fixtures + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Test with real data - blacklist a location that might exist + violations := blacklist.get_violations( + tf_variables, + ["location"], + ["US", "EU"], + ) with input as data.gcp_storage_bucket_plan + + is_set(violations) + every v in violations { + shared_test._assert_valid_violation(v) + contains(v.message, "Storage Bucket") + contains(v.message, "location") + } +} + +# ============================================================================== +# ADDITIONAL TESTS (2): Real-world usage patterns +# ============================================================================== + +# Test 9: Boolean blacklisting (real-world use case - force_destroy) +test_get_violations_boolean_blacklist if { + # Mock matching real policy: force_destroy: true is blacklisted + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_storage_bucket", + "values": { + "name": "unsafe-bucket", + "force_destroy": true, + "location": "US", + }, + }, + { + "type": "google_storage_bucket", + "values": { + "name": "safe-bucket", + "force_destroy": false, + "location": "US", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Blacklist force_destroy: true (actual policy usage pattern) + violations := blacklist.get_violations( + tf_variables, + ["force_destroy"], + [true], + ) with input as mock_input + + # Should only flag unsafe-bucket + count(violations) == 1 + some v in violations + v.name == "unsafe-bucket" + contains(v.message, "force_destroy") + contains(v.message, "true") +} + +# Test 10: Array attribute with OR logic (tests helper's array intersection) +test_get_violations_array_attribute if { + # Mock with array attributes (e.g., labels, tags) + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_storage_bucket", + "values": { + "name": "violating-bucket", + "labels": { + "env": "dev", + "team": "security", + }, + "uniform_bucket_level_access": [ + { + "enabled": false, + "locked": false, + }, + ], + }, + }, + { + "type": "google_storage_bucket", + "values": { + "name": "compliant-bucket", + "labels": { + "env": "prod", + "team": "security", + }, + "uniform_bucket_level_access": [ + { + "enabled": true, + "locked": true, + }, + ], + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Blacklist specific nested array attribute values (OR logic) + # If uniform_bucket_level_access array contains enabled: false, it violates + violations := blacklist.get_violations( + tf_variables, + ["uniform_bucket_level_access", 0, "enabled"], + [false], + ) with input as mock_input + + # Should flag bucket with enabled: false + count(violations) == 1 + some v in violations + v.name == "violating-bucket" + contains(v.message, "uniform_bucket_level_access") + contains(v.message, "false") +} diff --git a/tests/_helpers/check_ux.sh b/tests/_helpers/check_ux.sh new file mode 100644 index 000000000..775037ee2 --- /dev/null +++ b/tests/_helpers/check_ux.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# UX Message Review Tool +# Displays actual violation messages to verify they are clear and actionable + +# Navigate to repository root +cd "$(git rev-parse --show-toplevel)" || exit 1 + +echo "🔍 UX Message Review" +echo "======================================" +echo "" + +inspect_policy() { + local name="$1" + local input="$2" + local query="$3" + + + echo "Policy: $name" + echo "======================================" + echo "" + + # Get message and details fields + message=$(opa eval \ + --data ./policies/_helpers \ + --data ./policies/gcp \ + --input "$input" \ + "${query}.message" \ + --format pretty 2>&1) + + details=$(opa eval \ + --data ./policies/_helpers \ + --data ./policies/gcp \ + --input "$input" \ + "${query}.details" \ + --format pretty 2>&1) + + if [ $? -eq 0 ]; then + echo "MESSAGE:" + echo "$message" + echo "" + echo "DETAILS:" + echo "$details" + else + echo "❌ Error evaluating policy:" + echo "$message" + fi + + echo "" + echo "" +} + +# Test all 6 policy types with their violations + +inspect_policy "Blacklist & Element Blacklist (Access Context Manager)" \ + "./inputs/gcp/access_context_manager_vpc_service_controls/access_context_manager_service_perimeter/status/plan.json" \ + "data.terraform.gcp.security.access_context_manager_vpc_service_controls.access_context_manager_service_perimeter.status" + +inspect_policy "Whitelist (API Hub Encryption)" \ + "./inputs/gcp/api_hub/google_apihub_api_hub_instance/config_encryption_type/plan.json" \ + "data.terraform.gcp.security.api_hub.google_apihub_api_hub_instance.config_encryption_type" + +inspect_policy "Range (Storage Bucket Retention Period)" \ + "./inputs/gcp/cloud_storage/google_storage_bucket/retention_period/plan.json" \ + "data.terraform.gcp.security.cloud_storage.google_storage_bucket.retention_period" + +inspect_policy "Pattern Blacklist (Storage Default Object ACL)" \ + "./inputs/gcp/cloud_storage/google_storage_default_object_acl/public_access_prevention/plan.json" \ + "data.terraform.gcp.security.cloud_storage.google_storage_default_object_acl.public_access_prevention" + +inspect_policy "Pattern Whitelist (Project ID)" \ + "./inputs/gcp/cloud_platform_service/google_project/project_id/plan.json" \ + "data.terraform.gcp.security.cloud_platform_service.google_project.project_id" + +echo "======================================" +echo "✅ Inspection complete" +echo "" +echo "Use this to verify:" +echo " - Violation messages are clear and actionable" +echo " - Resource names are displayed correctly" +echo " - Attribute paths are formatted properly" +echo " - Blacklist/whitelist values are shown" +echo " - Empty values show (EMPTY!) warning" diff --git a/tests/_helpers/element_blacklist_test.rego b/tests/_helpers/element_blacklist_test.rego new file mode 100644 index 000000000..b72255067 --- /dev/null +++ b/tests/_helpers/element_blacklist_test.rego @@ -0,0 +1,412 @@ +package terraform.helpers.policies.element_blacklist_test + +# Element Blacklist Policy Test Suite +# +# Tests the element blacklist policy module which detects array elements containing +# forbidden substring patterns (e.g., wildcards "*" or template variables "${var.*}"). + +import data.terraform.helpers.policies.element_blacklist +import data.terraform.helpers.shared +import data.terraform.helpers.shared_test +import rego.v1 + +# ============================================================================== +# UNIT TESTS (6): Test _get_resources and get_violations with simple mocks +# ============================================================================== + +# Test 1: Single pattern match (wildcard detection) +test_get_resources_single_pattern if { + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_access_context_manager_service_perimeter", + "name": "wildcard-perimeter", + "values": { + "title": "wildcard-perimeter", + "status": [{ + "restricted_services": [ + "*.googleapis.com", + "storage.googleapis.com", + ], + }], + }, + }, + { + "type": "google_access_context_manager_service_perimeter", + "name": "compliant-perimeter", + "values": { + "title": "compliant-perimeter", + "status": [{ + "restricted_services": [ + "storage.googleapis.com", + "bigquery.googleapis.com", + ], + }], + }, + }, + ], + }, + }, + } + + resources := element_blacklist._get_resources( + "google_access_context_manager_service_perimeter", + ["status", 0, "restricted_services"], + ["*"], + ) with input as mock_input + + # Only wildcard-perimeter should match + count(resources) == 1 + some r in resources + r.name == "wildcard-perimeter" +} + +# Test 2: Multiple patterns with OR logic +test_get_resources_multi_pattern_or_logic if { + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_access_context_manager_service_perimeter", + "name": "wildcard-perimeter", + "values": { + "title": "wildcard-perimeter", + "status": [{ + "restricted_services": ["*.googleapis.com"], + }], + }, + }, + { + "type": "google_access_context_manager_service_perimeter", + "name": "variable-perimeter", + "values": { + "title": "variable-perimeter", + "status": [{ + "restricted_services": ["${var.service}.googleapis.com"], + }], + }, + }, + { + "type": "google_access_context_manager_service_perimeter", + "name": "compliant-perimeter", + "values": { + "title": "compliant-perimeter", + "status": [{ + "restricted_services": ["storage.googleapis.com"], + }], + }, + }, + ], + }, + }, + } + + resources := element_blacklist._get_resources( + "google_access_context_manager_service_perimeter", + ["status", 0, "restricted_services"], + ["*", "${"], + ) with input as mock_input + + # Both wildcard and variable perimeters should match (OR logic) + count(resources) == 2 + resource_names := {r.name | some r in resources} + resource_names == {"wildcard-perimeter", "variable-perimeter"} +} + +# Test 3: Non-matching pattern returns empty set +test_get_resources_no_match if { + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_access_context_manager_service_perimeter", + "name": "compliant-perimeter", + "values": { + "title": "compliant-perimeter", + "status": [{ + "restricted_services": ["storage.googleapis.com"], + }], + }, + }, + ], + }, + }, + } + + resources := element_blacklist._get_resources( + "google_access_context_manager_service_perimeter", + ["status", 0, "restricted_services"], + ["forbidden-pattern"], + ) with input as mock_input + + count(resources) == 0 +} + +# Test 4: Resource type filter (only matches specified type) +test_get_resources_resource_type_filter if { + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_access_context_manager_service_perimeter", + "name": "wildcard-perimeter", + "values": { + "title": "wildcard-perimeter", + "status": [{ + "restricted_services": ["*.googleapis.com"], + }], + }, + }, + { + "type": "google_access_context_manager_access_policy", + "name": "different-type", + "values": { + "title": "my-policy", + "services": ["*.googleapis.com"], + }, + }, + ], + }, + }, + } + + resources := element_blacklist._get_resources( + "google_access_context_manager_service_perimeter", + ["status", 0, "restricted_services"], + ["*"], + ) with input as mock_input + + # Only service_perimeter type should match + count(resources) == 1 + some r in resources + r.type == "google_access_context_manager_service_perimeter" +} + +# Test 5: Missing attribute path returns empty set +test_get_resources_missing_attribute if { + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_access_context_manager_service_perimeter", + "name": "perimeter", + "values": { + "title": "perimeter", + }, + }, + ], + }, + }, + } + + resources := element_blacklist._get_resources( + "google_access_context_manager_service_perimeter", + ["nonexistent", 0, "field"], + ["*"], + ) with input as mock_input + + count(resources) == 0 +} + +# Test 6: get_violations minimal mock (structure validation) +test_get_violations_minimal if { + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_access_context_manager_service_perimeter", + "name": "wildcard-perimeter", + "values": { + "title": "wildcard-perimeter", + "status": [{ + "restricted_services": ["*.googleapis.com"], + }], + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_access_context_manager_service_perimeter", + "friendly_resource_name": "Service Perimeter", + "resource_value_name": "title", + } + + violations := element_blacklist.get_violations( + tf_variables, + ["status", 0, "restricted_services"], + ["*"], + ) with input as mock_input + + count(violations) == 1 + some v in violations + v.name == "wildcard-perimeter" + shared_test._assert_valid_violation(v) + contains(v.message, "wildcard-perimeter") # Resource name + contains(v.message, "*.googleapis.com") # Violating element + contains(v.message, "[\"*\"]") # Pattern matched +} + +# ============================================================================== +# INTEGRATION TEST (1): Realistic structure with edge cases +# ============================================================================== + +# Test 7: get_violations with realistic multi-resource scenario +test_get_violations_realistic if { + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + # Wildcard violation + { + "type": "google_access_context_manager_service_perimeter", + "name": "wildcard-perimeter", + "values": { + "title": "wildcard-perimeter", + "status": [{ + "restricted_services": [ + "*.googleapis.com", + "storage.googleapis.com", + ], + }], + }, + }, + # Variable template violation + { + "type": "google_access_context_manager_service_perimeter", + "name": "variable-perimeter", + "values": { + "title": "variable-perimeter", + "status": [{ + "restricted_services": [ + "${var.service}.googleapis.com", + "compute.googleapis.com", + ], + }], + }, + }, + # Multiple violations in one resource + { + "type": "google_access_context_manager_service_perimeter", + "name": "multi-violation-perimeter", + "values": { + "title": "multi-violation-perimeter", + "status": [{ + "restricted_services": [ + "*.googleapis.com", + "${var.service}.googleapis.com", + "pubsub.googleapis.com", + ], + }], + }, + }, + # Compliant resource + { + "type": "google_access_context_manager_service_perimeter", + "name": "compliant-perimeter", + "values": { + "title": "compliant-perimeter", + "status": [{ + "restricted_services": [ + "storage.googleapis.com", + "bigquery.googleapis.com", + ], + }], + }, + }, + # Different resource type (should be ignored) + { + "type": "google_access_context_manager_access_policy", + "name": "different-type", + "values": { + "title": "my-policy", + "parent": "organizations/123456789", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_access_context_manager_service_perimeter", + "friendly_resource_name": "Service Perimeter", + "resource_value_name": "title", + } + + violations := element_blacklist.get_violations( + tf_variables, + ["status", 0, "restricted_services"], + ["*", "${"], + ) with input as mock_input + + # Should detect all three violating perimeters + count(violations) == 3 + violation_names := {v.name | some v in violations} + violation_names == {"wildcard-perimeter", "variable-perimeter", "multi-violation-perimeter"} + + every v in violations { + shared_test._assert_valid_violation(v) + contains(v.message, "Service Perimeter") + contains(v.message, "status.[0].restricted_services") + } + + # Verify multi-violation includes both patterns + some v in violations + v.name == "multi-violation-perimeter" + contains(v.message, "*") + contains(v.message, "${") +} + +# ============================================================================== +# REALITY CHECK (1): Test with real Terraform plan structure +# ============================================================================== + +# ============================================================================== +# REALITY CHECK (1): Test with real Terraform plan structure +# ============================================================================== +# ============================================================================ +# FIXTURE PROVENANCE +# ============================================================================ +# Source: inputs/gcp/access_context_manager_vpc_service_controls/ +# access_context_manager_access_level/device_policy/ +# Fixture: tests/_helpers/fixtures/gcp_access_level/plan.json +# Why this fixture: Contains actual array data (regions: ["CH", "IT", "US"]) +# for testing element blacklist on string arrays +# Alternative: gcp_storage_bucket has empty arrays (cors: [], lifecycle_rule: []) +# ============================================================================ + +# Test 8: get_violations with real Terraform plan (access level fixture) +test_real_plan_violations if { + # Use real fixture with actual array data from access level regions + tf_variables := { + "resource_type": "google_access_context_manager_access_level", + "friendly_resource_name": "Access Level", + "resource_value_name": "title", + } + + # Test regions array for any restricted regions + # Fixture has regions: ["CH", "IT", "US"] in nc resource + violations := element_blacklist.get_violations( + tf_variables, + ["basic", 0, "conditions", 0, "regions"], + ["US", "CN", "RU"], # Blacklist certain countries + ) with input as data.gcp_access_level_plan + + is_set(violations) + every v in violations { + shared_test._assert_valid_violation(v) + contains(v.message, "Access Level") + contains(v.message, "basic") + contains(v.message, "regions") + } +} diff --git a/tests/_helpers/fixtures/gcp_access_level/plan.json b/tests/_helpers/fixtures/gcp_access_level/plan.json new file mode 100644 index 000000000..4058c9911 --- /dev/null +++ b/tests/_helpers/fixtures/gcp_access_level/plan.json @@ -0,0 +1,507 @@ +{ + "gcp_access_level_plan": { + "format_version": "1.2", + "terraform_version": "1.12.2", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "google_access_context_manager_access_level.c", + "mode": "managed", + "type": "google_access_context_manager_access_level", + "name": "c", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 0, + "values": { + "basic": [ + { + "combining_function": "AND", + "conditions": [ + { + "device_policy": [ + { + "allowed_device_management_levels": null, + "allowed_encryption_statuses": null, + "os_constraints": [], + "require_admin_approval": null, + "require_corp_owned": null, + "require_screen_lock": true + } + ], + "ip_subnetworks": null, + "members": null, + "negate": null, + "regions": null, + "required_access_levels": null, + "vpc_network_sources": [] + } + ] + } + ], + "custom": [], + "description": null, + "timeouts": null, + "title": "chromeos_no_lock" + }, + "sensitive_values": { + "basic": [ + { + "conditions": [ + { + "device_policy": [ + { + "os_constraints": [] + } + ], + "vpc_network_sources": [] + } + ] + } + ], + "custom": [] + } + }, + { + "address": "google_access_context_manager_access_level.nc", + "mode": "managed", + "type": "google_access_context_manager_access_level", + "name": "nc", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 0, + "values": { + "basic": [ + { + "combining_function": "AND", + "conditions": [ + { + "device_policy": [ + { + "allowed_device_management_levels": null, + "allowed_encryption_statuses": null, + "os_constraints": [ + { + "minimum_version": null, + "os_type": "DESKTOP_CHROME_OS", + "require_verified_chrome_os": null + } + ], + "require_admin_approval": null, + "require_corp_owned": null, + "require_screen_lock": true + } + ], + "ip_subnetworks": null, + "members": null, + "negate": null, + "regions": [ + "CH", + "IT", + "US" + ], + "required_access_levels": null, + "vpc_network_sources": [] + } + ] + } + ], + "custom": [], + "description": null, + "timeouts": null, + "title": "chromeos_no_lock" + }, + "sensitive_values": { + "basic": [ + { + "conditions": [ + { + "device_policy": [ + { + "os_constraints": [ + {} + ] + } + ], + "regions": [ + false, + false, + false + ], + "vpc_network_sources": [] + } + ] + } + ], + "custom": [] + } + }, + { + "address": "google_access_context_manager_access_policy.access-policy", + "mode": "managed", + "type": "google_access_context_manager_access_policy", + "name": "access-policy", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 0, + "values": { + "parent": "organizations/123456789", + "scopes": null, + "timeouts": null, + "title": "my policy" + }, + "sensitive_values": {} + } + ] + } + }, + "resource_changes": [ + { + "address": "google_access_context_manager_access_level.c", + "mode": "managed", + "type": "google_access_context_manager_access_level", + "name": "c", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "basic": [ + { + "combining_function": "AND", + "conditions": [ + { + "device_policy": [ + { + "allowed_device_management_levels": null, + "allowed_encryption_statuses": null, + "os_constraints": [], + "require_admin_approval": null, + "require_corp_owned": null, + "require_screen_lock": true + } + ], + "ip_subnetworks": null, + "members": null, + "negate": null, + "regions": null, + "required_access_levels": null, + "vpc_network_sources": [] + } + ] + } + ], + "custom": [], + "description": null, + "timeouts": null, + "title": "chromeos_no_lock" + }, + "after_unknown": { + "basic": [ + { + "conditions": [ + { + "device_policy": [ + { + "os_constraints": [] + } + ], + "vpc_network_sources": [] + } + ] + } + ], + "custom": [], + "id": true, + "name": true, + "parent": true + }, + "before_sensitive": false, + "after_sensitive": { + "basic": [ + { + "conditions": [ + { + "device_policy": [ + { + "os_constraints": [] + } + ], + "vpc_network_sources": [] + } + ] + } + ], + "custom": [] + } + } + }, + { + "address": "google_access_context_manager_access_level.nc", + "mode": "managed", + "type": "google_access_context_manager_access_level", + "name": "nc", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "basic": [ + { + "combining_function": "AND", + "conditions": [ + { + "device_policy": [ + { + "allowed_device_management_levels": null, + "allowed_encryption_statuses": null, + "os_constraints": [ + { + "minimum_version": null, + "os_type": "DESKTOP_CHROME_OS", + "require_verified_chrome_os": null + } + ], + "require_admin_approval": null, + "require_corp_owned": null, + "require_screen_lock": true + } + ], + "ip_subnetworks": null, + "members": null, + "negate": null, + "regions": [ + "CH", + "IT", + "US" + ], + "required_access_levels": null, + "vpc_network_sources": [] + } + ] + } + ], + "custom": [], + "description": null, + "timeouts": null, + "title": "chromeos_no_lock" + }, + "after_unknown": { + "basic": [ + { + "conditions": [ + { + "device_policy": [ + { + "os_constraints": [ + {} + ] + } + ], + "regions": [ + false, + false, + false + ], + "vpc_network_sources": [] + } + ] + } + ], + "custom": [], + "id": true, + "name": true, + "parent": true + }, + "before_sensitive": false, + "after_sensitive": { + "basic": [ + { + "conditions": [ + { + "device_policy": [ + { + "os_constraints": [ + {} + ] + } + ], + "regions": [ + false, + false, + false + ], + "vpc_network_sources": [] + } + ] + } + ], + "custom": [] + } + } + }, + { + "address": "google_access_context_manager_access_policy.access-policy", + "mode": "managed", + "type": "google_access_context_manager_access_policy", + "name": "access-policy", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "parent": "organizations/123456789", + "scopes": null, + "timeouts": null, + "title": "my policy" + }, + "after_unknown": { + "create_time": true, + "id": true, + "name": true, + "update_time": true + }, + "before_sensitive": false, + "after_sensitive": {} + } + } + ], + "configuration": { + "provider_config": { + "google": { + "name": "google", + "full_name": "registry.terraform.io/hashicorp/google" + } + }, + "root_module": { + "resources": [ + { + "address": "google_access_context_manager_access_level.c", + "mode": "managed", + "type": "google_access_context_manager_access_level", + "name": "c", + "provider_config_key": "google", + "expressions": { + "basic": [ + { + "conditions": [ + { + "device_policy": [ + { + "require_screen_lock": { + "constant_value": true + } + } + ] + } + ] + } + ], + "name": { + "references": [ + "google_access_context_manager_access_policy.access-policy.name", + "google_access_context_manager_access_policy.access-policy" + ] + }, + "parent": { + "references": [ + "google_access_context_manager_access_policy.access-policy.name", + "google_access_context_manager_access_policy.access-policy" + ] + }, + "title": { + "constant_value": "chromeos_no_lock" + } + }, + "schema_version": 0 + }, + { + "address": "google_access_context_manager_access_level.nc", + "mode": "managed", + "type": "google_access_context_manager_access_level", + "name": "nc", + "provider_config_key": "google", + "expressions": { + "basic": [ + { + "conditions": [ + { + "device_policy": [ + { + "os_constraints": [ + { + "os_type": { + "constant_value": "DESKTOP_CHROME_OS" + } + } + ], + "require_screen_lock": { + "constant_value": true + } + } + ], + "regions": { + "constant_value": [ + "CH", + "IT", + "US" + ] + } + } + ] + } + ], + "name": { + "references": [ + "google_access_context_manager_access_policy.access-policy.name", + "google_access_context_manager_access_policy.access-policy" + ] + }, + "parent": { + "references": [ + "google_access_context_manager_access_policy.access-policy.name", + "google_access_context_manager_access_policy.access-policy" + ] + }, + "title": { + "constant_value": "chromeos_no_lock" + } + }, + "schema_version": 0 + }, + { + "address": "google_access_context_manager_access_policy.access-policy", + "mode": "managed", + "type": "google_access_context_manager_access_policy", + "name": "access-policy", + "provider_config_key": "google", + "expressions": { + "parent": { + "constant_value": "organizations/123456789" + }, + "title": { + "constant_value": "my policy" + } + }, + "schema_version": 0 + } + ] + } + }, + "relevant_attributes": [ + { + "resource": "google_access_context_manager_access_policy.access-policy", + "attribute": [ + "name" + ] + } + ], + "timestamp": "2025-12-02T04:18:21Z", + "applyable": true, + "complete": true, + "errored": false + } +} diff --git a/tests/_helpers/fixtures/gcp_project/plan.json b/tests/_helpers/fixtures/gcp_project/plan.json new file mode 100644 index 000000000..5e05dfefd --- /dev/null +++ b/tests/_helpers/fixtures/gcp_project/plan.json @@ -0,0 +1,606 @@ +{ + "gcp_project_plan": { + "format_version": "1.2", + "terraform_version": "1.12.2", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "google_project.c123", + "mode": "managed", + "type": "google_project", + "name": "c123", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 1, + "values": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "c123", + "org_id": "123456789", + "project_id": "proj-app-dev", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "sensitive_values": { + "effective_labels": {}, + "terraform_labels": {} + } + }, + { + "address": "google_project.c223", + "mode": "managed", + "type": "google_project", + "name": "c223", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 1, + "values": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "c223", + "org_id": "123456789", + "project_id": "proj-sec-prod", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "sensitive_values": { + "effective_labels": {}, + "terraform_labels": {} + } + }, + { + "address": "google_project.c323", + "mode": "managed", + "type": "google_project", + "name": "c323", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 1, + "values": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "c323", + "org_id": "123456789", + "project_id": "proj-app-prod", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "sensitive_values": { + "effective_labels": {}, + "terraform_labels": {} + } + }, + { + "address": "google_project.nc123", + "mode": "managed", + "type": "google_project", + "name": "nc123", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 1, + "values": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "nc123", + "org_id": "123456789", + "project_id": "project-app-dev", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "sensitive_values": { + "effective_labels": {}, + "terraform_labels": {} + } + }, + { + "address": "google_project.nc223", + "mode": "managed", + "type": "google_project", + "name": "nc223", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 1, + "values": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "nc223", + "org_id": "123456789", + "project_id": "proj-ops-staging", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "sensitive_values": { + "effective_labels": {}, + "terraform_labels": {} + } + }, + { + "address": "google_project.nc323", + "mode": "managed", + "type": "google_project", + "name": "nc323", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 1, + "values": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "nc323", + "org_id": "123456789", + "project_id": "myproject-prod-01", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "sensitive_values": { + "effective_labels": {}, + "terraform_labels": {} + } + } + ] + } + }, + "resource_changes": [ + { + "address": "google_project.c123", + "mode": "managed", + "type": "google_project", + "name": "c123", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "c123", + "org_id": "123456789", + "project_id": "proj-app-dev", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "after_unknown": { + "effective_labels": {}, + "id": true, + "number": true, + "terraform_labels": {} + }, + "before_sensitive": false, + "after_sensitive": { + "effective_labels": {}, + "terraform_labels": {} + } + } + }, + { + "address": "google_project.c223", + "mode": "managed", + "type": "google_project", + "name": "c223", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "c223", + "org_id": "123456789", + "project_id": "proj-sec-prod", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "after_unknown": { + "effective_labels": {}, + "id": true, + "number": true, + "terraform_labels": {} + }, + "before_sensitive": false, + "after_sensitive": { + "effective_labels": {}, + "terraform_labels": {} + } + } + }, + { + "address": "google_project.c323", + "mode": "managed", + "type": "google_project", + "name": "c323", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "c323", + "org_id": "123456789", + "project_id": "proj-app-prod", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "after_unknown": { + "effective_labels": {}, + "id": true, + "number": true, + "terraform_labels": {} + }, + "before_sensitive": false, + "after_sensitive": { + "effective_labels": {}, + "terraform_labels": {} + } + } + }, + { + "address": "google_project.nc123", + "mode": "managed", + "type": "google_project", + "name": "nc123", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "nc123", + "org_id": "123456789", + "project_id": "project-app-dev", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "after_unknown": { + "effective_labels": {}, + "id": true, + "number": true, + "terraform_labels": {} + }, + "before_sensitive": false, + "after_sensitive": { + "effective_labels": {}, + "terraform_labels": {} + } + } + }, + { + "address": "google_project.nc223", + "mode": "managed", + "type": "google_project", + "name": "nc223", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "nc223", + "org_id": "123456789", + "project_id": "proj-ops-staging", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "after_unknown": { + "effective_labels": {}, + "id": true, + "number": true, + "terraform_labels": {} + }, + "before_sensitive": false, + "after_sensitive": { + "effective_labels": {}, + "terraform_labels": {} + } + } + }, + { + "address": "google_project.nc323", + "mode": "managed", + "type": "google_project", + "name": "nc323", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "auto_create_network": false, + "billing_account": null, + "deletion_policy": "PREVENT", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "folder_id": null, + "labels": null, + "name": "nc323", + "org_id": "123456789", + "project_id": "myproject-prod-01", + "tags": null, + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "after_unknown": { + "effective_labels": {}, + "id": true, + "number": true, + "terraform_labels": {} + }, + "before_sensitive": false, + "after_sensitive": { + "effective_labels": {}, + "terraform_labels": {} + } + } + } + ], + "configuration": { + "provider_config": { + "google": { + "name": "google", + "full_name": "registry.terraform.io/hashicorp/google" + } + }, + "root_module": { + "resources": [ + { + "address": "google_project.c123", + "mode": "managed", + "type": "google_project", + "name": "c123", + "provider_config_key": "google", + "expressions": { + "auto_create_network": { + "constant_value": false + }, + "deletion_policy": { + "constant_value": "PREVENT" + }, + "name": { + "constant_value": "c123" + }, + "org_id": { + "constant_value": "123456789" + }, + "project_id": { + "constant_value": "proj-app-dev" + } + }, + "schema_version": 1 + }, + { + "address": "google_project.c223", + "mode": "managed", + "type": "google_project", + "name": "c223", + "provider_config_key": "google", + "expressions": { + "auto_create_network": { + "constant_value": false + }, + "deletion_policy": { + "constant_value": "PREVENT" + }, + "name": { + "constant_value": "c223" + }, + "org_id": { + "constant_value": "123456789" + }, + "project_id": { + "constant_value": "proj-sec-prod" + } + }, + "schema_version": 1 + }, + { + "address": "google_project.c323", + "mode": "managed", + "type": "google_project", + "name": "c323", + "provider_config_key": "google", + "expressions": { + "auto_create_network": { + "constant_value": false + }, + "name": { + "constant_value": "c323" + }, + "org_id": { + "constant_value": "123456789" + }, + "project_id": { + "constant_value": "proj-app-prod" + } + }, + "schema_version": 1 + }, + { + "address": "google_project.nc123", + "mode": "managed", + "type": "google_project", + "name": "nc123", + "provider_config_key": "google", + "expressions": { + "auto_create_network": { + "constant_value": false + }, + "deletion_policy": { + "constant_value": "PREVENT" + }, + "name": { + "constant_value": "nc123" + }, + "org_id": { + "constant_value": "123456789" + }, + "project_id": { + "constant_value": "project-app-dev" + } + }, + "schema_version": 1 + }, + { + "address": "google_project.nc223", + "mode": "managed", + "type": "google_project", + "name": "nc223", + "provider_config_key": "google", + "expressions": { + "auto_create_network": { + "constant_value": false + }, + "deletion_policy": { + "constant_value": "PREVENT" + }, + "name": { + "constant_value": "nc223" + }, + "org_id": { + "constant_value": "123456789" + }, + "project_id": { + "constant_value": "proj-ops-staging" + } + }, + "schema_version": 1 + }, + { + "address": "google_project.nc323", + "mode": "managed", + "type": "google_project", + "name": "nc323", + "provider_config_key": "google", + "expressions": { + "auto_create_network": { + "constant_value": false + }, + "name": { + "constant_value": "nc323" + }, + "org_id": { + "constant_value": "123456789" + }, + "project_id": { + "constant_value": "myproject-prod-01" + } + }, + "schema_version": 1 + } + ] + } + }, + "timestamp": "2025-11-27T04:15:45Z", + "applyable": true, + "complete": true, + "errored": false + } +} diff --git a/tests/_helpers/fixtures/gcp_storage_bucket/plan.json b/tests/_helpers/fixtures/gcp_storage_bucket/plan.json new file mode 100644 index 000000000..cdacbc34b --- /dev/null +++ b/tests/_helpers/fixtures/gcp_storage_bucket/plan.json @@ -0,0 +1,368 @@ +{ + "gcp_storage_bucket_plan": { + "format_version": "1.2", + "terraform_version": "1.12.2", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "google_storage_bucket.c123", + "mode": "managed", + "type": "google_storage_bucket", + "name": "c123", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 3, + "values": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "default_event_based_hold": null, + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "enable_object_retention": null, + "encryption": [], + "force_destroy": true, + "hierarchical_namespace": [], + "labels": null, + "lifecycle_rule": [], + "location": "US", + "logging": [], + "name": "c123", + "requester_pays": null, + "retention_policy": [ + { + "is_locked": false, + "retention_period": 604800 + } + ], + "storage_class": "STANDARD", + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "sensitive_values": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "effective_labels": {}, + "encryption": [], + "hierarchical_namespace": [], + "lifecycle_rule": [], + "logging": [], + "retention_policy": [ + {} + ], + "soft_delete_policy": [], + "terraform_labels": {}, + "versioning": [], + "website": [] + } + }, + { + "address": "google_storage_bucket.nc123", + "mode": "managed", + "type": "google_storage_bucket", + "name": "nc123", + "provider_name": "registry.terraform.io/hashicorp/google", + "schema_version": 3, + "values": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "default_event_based_hold": null, + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "enable_object_retention": null, + "encryption": [], + "force_destroy": true, + "hierarchical_namespace": [], + "labels": null, + "lifecycle_rule": [], + "location": "US", + "logging": [], + "name": "nc123", + "requester_pays": null, + "retention_policy": [ + { + "is_locked": false, + "retention_period": 2692000 + } + ], + "storage_class": "STANDARD", + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "sensitive_values": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "effective_labels": {}, + "encryption": [], + "hierarchical_namespace": [], + "lifecycle_rule": [], + "logging": [], + "retention_policy": [ + {} + ], + "soft_delete_policy": [], + "terraform_labels": {}, + "versioning": [], + "website": [] + } + } + ] + } + }, + "resource_changes": [ + { + "address": "google_storage_bucket.c123", + "mode": "managed", + "type": "google_storage_bucket", + "name": "c123", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "default_event_based_hold": null, + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "enable_object_retention": null, + "encryption": [], + "force_destroy": true, + "hierarchical_namespace": [], + "labels": null, + "lifecycle_rule": [], + "location": "US", + "logging": [], + "name": "c123", + "requester_pays": null, + "retention_policy": [ + { + "is_locked": false, + "retention_period": 604800 + } + ], + "storage_class": "STANDARD", + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "after_unknown": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "effective_labels": {}, + "encryption": [], + "hierarchical_namespace": [], + "id": true, + "lifecycle_rule": [], + "logging": [], + "project": true, + "project_number": true, + "public_access_prevention": true, + "retention_policy": [ + {} + ], + "rpo": true, + "self_link": true, + "soft_delete_policy": true, + "terraform_labels": {}, + "time_created": true, + "uniform_bucket_level_access": true, + "updated": true, + "url": true, + "versioning": true, + "website": true + }, + "before_sensitive": false, + "after_sensitive": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "effective_labels": {}, + "encryption": [], + "hierarchical_namespace": [], + "lifecycle_rule": [], + "logging": [], + "retention_policy": [ + {} + ], + "soft_delete_policy": [], + "terraform_labels": {}, + "versioning": [], + "website": [] + } + } + }, + { + "address": "google_storage_bucket.nc123", + "mode": "managed", + "type": "google_storage_bucket", + "name": "nc123", + "provider_name": "registry.terraform.io/hashicorp/google", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "default_event_based_hold": null, + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "enable_object_retention": null, + "encryption": [], + "force_destroy": true, + "hierarchical_namespace": [], + "labels": null, + "lifecycle_rule": [], + "location": "US", + "logging": [], + "name": "nc123", + "requester_pays": null, + "retention_policy": [ + { + "is_locked": false, + "retention_period": 2692000 + } + ], + "storage_class": "STANDARD", + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null + }, + "after_unknown": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "effective_labels": {}, + "encryption": [], + "hierarchical_namespace": [], + "id": true, + "lifecycle_rule": [], + "logging": [], + "project": true, + "project_number": true, + "public_access_prevention": true, + "retention_policy": [ + {} + ], + "rpo": true, + "self_link": true, + "soft_delete_policy": true, + "terraform_labels": {}, + "time_created": true, + "uniform_bucket_level_access": true, + "updated": true, + "url": true, + "versioning": true, + "website": true + }, + "before_sensitive": false, + "after_sensitive": { + "autoclass": [], + "cors": [], + "custom_placement_config": [], + "effective_labels": {}, + "encryption": [], + "hierarchical_namespace": [], + "lifecycle_rule": [], + "logging": [], + "retention_policy": [ + {} + ], + "soft_delete_policy": [], + "terraform_labels": {}, + "versioning": [], + "website": [] + } + } + } + ], + "configuration": { + "provider_config": { + "google": { + "name": "google", + "full_name": "registry.terraform.io/hashicorp/google" + } + }, + "root_module": { + "resources": [ + { + "address": "google_storage_bucket.c123", + "mode": "managed", + "type": "google_storage_bucket", + "name": "c123", + "provider_config_key": "google", + "expressions": { + "force_destroy": { + "constant_value": true + }, + "location": { + "constant_value": "US" + }, + "name": { + "constant_value": "c123" + }, + "retention_policy": [ + { + "retention_period": { + "constant_value": 604800 + } + } + ] + }, + "schema_version": 3 + }, + { + "address": "google_storage_bucket.nc123", + "mode": "managed", + "type": "google_storage_bucket", + "name": "nc123", + "provider_config_key": "google", + "expressions": { + "force_destroy": { + "constant_value": true + }, + "location": { + "constant_value": "US" + }, + "name": { + "constant_value": "nc123" + }, + "retention_policy": [ + { + "retention_period": { + "constant_value": 2692000 + } + } + ] + }, + "schema_version": 3 + } + ] + } + }, + "timestamp": "2025-11-27T02:50:59Z", + "applyable": true, + "complete": true, + "errored": false + } +} diff --git a/tests/_helpers/pattern_blacklist_test.rego b/tests/_helpers/pattern_blacklist_test.rego new file mode 100644 index 000000000..98b1b5c71 --- /dev/null +++ b/tests/_helpers/pattern_blacklist_test.rego @@ -0,0 +1,430 @@ +package terraform.helpers.policies.pattern_blacklist_test + +# Pattern Blacklist Policy Test Suite +# +# Tests the pattern blacklist policy module which detects resources where +# wildcard-extracted substrings match forbidden patterns. +# Uses target patterns with * wildcards to extract values, then checks against +# position-specific blacklists. + +import data.terraform.helpers.policies.pattern_blacklist +import data.terraform.helpers.shared +import data.terraform.helpers.shared_test +import rego.v1 + +# ============================================================================== +# UNIT TESTS (6): Test pattern matching logic +# ============================================================================== + +# Test 1: Exact match in blacklist (boundary: match) +test_matches_blacklist_exact_match if { + pattern_blacklist._matches_blacklist(["forbidden", "banned"], "forbidden") +} + +# Test 2: No match in blacklist (boundary: no match) +test_matches_blacklist_no_match if { + not pattern_blacklist._matches_blacklist(["forbidden", "banned"], "allowed") +} + +# Test 3: Single wildcard pattern match +test_get_blacklist_single_wildcard_match if { + # Mock resource with hierarchical pattern + mock_resource := { + "type": "google_project", + "values": { + "name": "test-project", + "parent": "projects/test-project/locations/us-east1", + }, + } + + # Target pattern with 2 wildcards + target := "projects/*/locations/*" + # Blacklist patterns: first position ["test-project"], second position ["us-east1"] + patterns := [["test-project"], ["us-east1"]] + + blacklist := pattern_blacklist._get_blacklist(mock_resource, ["parent"], target, patterns) + + # Should find 2 matches (both positions blacklisted) + count(blacklist) == 2 + + # Verify both positions are flagged + values := {b.value | some b in blacklist} + values == {"test-project", "us-east1"} +} + +# Test 4: Single wildcard pattern no match +test_get_blacklist_single_wildcard_no_match if { + # Mock resource with different values + mock_resource := { + "type": "google_project", + "values": { + "name": "prod-project", + "parent": "projects/prod-project/locations/us-central1", + }, + } + + target := "projects/*/locations/*" + patterns := [["test-project"], ["us-east1"]] + + blacklist := pattern_blacklist._get_blacklist(mock_resource, ["parent"], target, patterns) + + # Should find no matches + count(blacklist) == 0 +} + +# Test 5: Multiple patterns with OR logic within position +test_get_blacklist_multiple_patterns_or_logic if { + # Mock with value matching one of multiple patterns at a position + mock_resource := { + "type": "google_project", + "values": { + "name": "dev-project", + "parent": "projects/dev-project/locations/us-east1", + }, + } + + target := "projects/*/locations/*" + # First position: ["test-project", "dev-project"] (OR logic - full extracted strings) + # Second position: ["us-east1"] + patterns := [["test-project", "dev-project"], ["us-east1"]] + + blacklist := pattern_blacklist._get_blacklist(mock_resource, ["parent"], target, patterns) + + # Should match both positions (dev-project matches first, us-east1 matches second) + count(blacklist) == 2 + values := {b.value | some b in blacklist} + values == {"dev-project", "us-east1"} +} + +# ============================================================================== +# MOCK DATA PROVENANCE +# ============================================================================== +# Minimal mocks in tests 6-7 are synthetic, designed to test specific logic paths. +# They represent simplified hierarchical patterns (organizations/*/folders/*). +# +# Reality check (test 8) uses: tests/_helpers/fixtures/gcp_project/plan.json +# Source: inputs/gcp/cloud_platform_service/google_project/project_id/ +# Purpose: Tests pattern extraction on actual project_id values: +# - c123: project_id="proj-app-dev" (pattern: proj-*-*) +# - c223: project_id="proj-sec-prod" (pattern: proj-*-*) +# ============================================================================== + +# Test 6: get_violations with minimal mock +test_get_violations_minimal if { + # Minimal mock with blacklisted pattern + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_project", + "values": { + "name": "test-project", + "parent": "organizations/123456/folders/test-folder", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Blacklist pattern: organizations/*/folders/* where folder is "test-folder" + violations := pattern_blacklist.get_violations( + tf_variables, + ["parent"], + ["organizations/*/folders/*", [[], ["test-folder"]]], + ) with input as mock_input + + # Property: Returns a set with no duplicate resource names + shared_test._assert_unique_violations(violations) + count(violations) == 1 + + some v in violations + v.name == "test-project" + shared_test._assert_valid_violation(v) + contains(v.message, "test-project") # Resource name + contains(v.message, "'test-folder'") # Violating value + contains(v.message, "blacklisted") # Verdict +} + +# ============================================================================== +# INTEGRATION TEST (1): Complex wildcard patterns +# ============================================================================== + +# Test 7: get_violations with realistic complex patterns +test_get_violations_realistic if { + # Realistic mock with multiple wildcards and edge cases + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + # Resource with blacklisted pattern at one position + { + "type": "google_project", + "values": { + "name": "violating-project", + "parent": "organizations/12345/folders/dev-folder", + }, + }, + # Resource with multiple blacklisted positions (CRITICAL TEST CASE) + { + "type": "google_project", + "values": { + "name": "multi-fail-project", + "parent": "organizations/bad-org/folders/dev-folder", + }, + }, + # Resource with compliant pattern + { + "type": "google_project", + "values": { + "name": "compliant-project", + "parent": "organizations/12345/folders/prod-folder", + }, + }, + # Resource with null parent (edge case) + { + "type": "google_project", + "values": { + "name": "null-project", + "parent": null, + }, + }, + # Different resource type (should be ignored) + { + "type": "google_storage_bucket", + "values": { + "name": "test-bucket", + "parent": "organizations/12345/folders/dev-folder", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Pattern with 2 wildcards: organizations/*/folders/* + # Blacklist: org "bad-org" and folder "dev-folder" + violations := pattern_blacklist.get_violations( + tf_variables, + ["parent"], + ["organizations/*/folders/*", [["bad-org"], ["dev-folder"]]], + ) with input as mock_input + + # Property: Returns a set with no duplicate resource names + shared_test._assert_unique_violations(violations) + + # Should flag 2 projects: violating-project (single position) and multi-fail-project (both positions) + count(violations) == 2 + violation_name_set := {v.name | some v in violations} + violation_name_set == {"violating-project", "multi-fail-project"} + + every violation in violations { + is_string(violation.name) + is_string(violation.message) + violation.name != "" + violation.message != "" + contains(violation.message, "Project") + contains(violation.message, "parent") + contains(violation.message, "blacklisted") + } + + # Verify single-failure message + some single_violation in violations + single_violation.name == "violating-project" + contains(single_violation.message, "'dev-folder'") + + # Verify multi-failure message mentions multiple positions + some multi_violation in violations + multi_violation.name == "multi-fail-project" + # Message should indicate multiple blacklist matches + contains(multi_violation.message, "Multiple positions matched blacklist") +} + +# ============================================================================== +# REALITY CHECK (1): Test with real Terraform plan structure +# ============================================================================== + +# Test 8: get_violations with real Terraform plan +test_get_violations_with_real_terraform_plan if { + # Use real fixture - gcp_project from fixtures + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Test with real data - blacklist a pattern that might exist + # If project has parent with hierarchical structure + violations := pattern_blacklist.get_violations( + tf_variables, + ["parent"], + ["organizations/*/folders/*", [[], ["test", "dev", "staging"]]], + ) with input as data.gcp_project_plan + + # Property: Returns a set with no duplicate resource names + shared_test._assert_unique_violations(violations) + + every v in violations { + shared_test._assert_valid_violation(v) + contains(v.message, "Project") + contains(v.message, "blacklisted") + } +} + +# ============================================================================== +# CRITICAL TESTS (2): Multiple failures and functional purity +# ============================================================================== + +# Test 9: Multiple position failures per resource (THE BUG THAT WAS MISSED) +test_get_violations_multiple_failures_per_resource if { + # This test validates the fix for eval_conflict_error + # When a resource matches multiple blacklist positions, _build_violation must + # return exactly ONE violation object (not multiple) + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + # Resource matching ALL 3 blacklisted positions + { + "type": "google_project", + "values": { + "name": "bad-project", + "project_id": "test-dev-staging", + }, + }, + # Resource matching 2 blacklisted positions + { + "type": "google_project", + "values": { + "name": "partial-bad", + "project_id": "test-dev-prod", + }, + }, + # Compliant resource + { + "type": "google_project", + "values": { + "name": "good-project", + "project_id": "proj-app-prod", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Pattern: *-*-* with blacklist on all positions + violations := pattern_blacklist.get_violations( + tf_variables, + ["project_id"], + ["*-*-*", [["test"], ["dev"], ["staging"]]], + ) with input as mock_input + + # Property: Returns a set with no duplicate resource names + shared_test._assert_unique_violations(violations) + + # CRITICAL: Must return exactly 1 violation per resource (not 3 for bad-project) + count(violations) == 2 + + some v1 in violations + v1.name == "bad-project" + is_string(v1.message) + # Message must mention multiple blacklist matches + contains(v1.message, "Multiple positions matched blacklist") + + some v2 in violations + v2.name == "partial-bad" + is_string(v2.message) +} + +# Test 10: Functional purity - _build_violation returns single output +test_build_violation_functional_purity if { + # This test ensures _build_violation never produces multiple outputs + # for the same inputs (Rego functional semantics requirement) + mock_resource := { + "type": "google_project", + "values": { + "name": "test-project", + "project_id": "bad-bad-bad", + }, + } + + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Call _build_violation with resource that matches all 3 blacklist positions + # This would have caused eval_conflict_error before the fix + violation := pattern_blacklist._build_violation( + tf_variables, + ["project_id"], + ["*-*-*", [["bad"], ["bad"], ["bad"]]], + mock_resource, + ) + + # Must return exactly ONE violation object + is_object(violation) + violation.name == "test-project" + is_string(violation.message) + violation.message != "" + + # Verify deterministic behavior - calling twice yields same result + violation2 := pattern_blacklist._build_violation( + tf_variables, + ["project_id"], + ["*-*-*", [["bad"], ["bad"], ["bad"]]], + mock_resource, + ) + violation == violation2 +} + +# Test 11: Utilize fixture attribute - project_id pattern from project +test_project_id_fixture if { + # Test using actual project_id patterns from gcp_project_plan + # Blacklist production projects matching pattern "proj-*-prod" + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Pattern "proj-*-prod" extracts middle segment + # Blacklist middle segments: "sec" and "app" + # Should match: proj-sec-prod (c223), proj-app-prod (c323) + violations := pattern_blacklist.get_violations( + tf_variables, + ["project_id"], + ["proj-*-prod", [["sec", "app"]]], + ) with input as data.gcp_project_plan + + # c223 has project_id "proj-sec-prod" and c323 has "proj-app-prod" + count(violations) == 2 + violation_names := {v.name | some v in violations} + violation_names == {"c223", "c323"} + + every v in violations { + contains(v.message, "project_id") + contains(v.message, "prod") + } +} diff --git a/tests/_helpers/pattern_whitelist_test.rego b/tests/_helpers/pattern_whitelist_test.rego new file mode 100644 index 000000000..9a4c952a2 --- /dev/null +++ b/tests/_helpers/pattern_whitelist_test.rego @@ -0,0 +1,428 @@ +package terraform.helpers.policies.pattern_whitelist_test + +# Pattern Whitelist Policy Test Suite +# +# Tests the pattern whitelist policy module which detects resources where +# wildcard-extracted substrings DON'T match allowed patterns. +# Uses target patterns with * wildcards to extract values, then validates each +# against position-specific whitelists (inverted logic from blacklist). + +import data.terraform.helpers.policies.pattern_whitelist +import data.terraform.helpers.shared +import data.terraform.helpers.shared_test +import rego.v1 + +# ============================================================================== +# UNIT TESTS (6): Test pattern matching logic +# ============================================================================== + +# Test 1: Exact match in whitelist (boundary: match - should pass) +test_matches_whitelist_exact_match if { + pattern_whitelist._matches_whitelist(["allowed", "permitted"], "allowed") +} + +# Test 2: No match in whitelist (boundary: no match - should fail) +test_matches_whitelist_no_match if { + not pattern_whitelist._matches_whitelist(["allowed", "permitted"], "forbidden") +} + +# Test 3: Single wildcard pattern - all positions whitelisted (no violation) +test_get_whitelist_single_wildcard_all_match if { + # Mock resource with values matching whitelist + mock_resource := { + "type": "google_project", + "values": { + "name": "prod-project", + "parent": "projects/prod-project/locations/us-central1", + }, + } + + # Target pattern with 2 wildcards + target := "projects/*/locations/*" + # Whitelist patterns: first position ["prod-project"], second position ["us-central1"] + patterns := [["prod-project"], ["us-central1"]] + + whitelist := pattern_whitelist._get_whitelist(mock_resource, ["parent"], target, patterns) + + # Should find 0 violations (all positions whitelisted) + count(whitelist) == 0 +} + +# Test 4: Single wildcard pattern - one position not whitelisted (violation) +test_get_whitelist_single_wildcard_violation if { + # Mock resource with non-whitelisted value + mock_resource := { + "type": "google_project", + "values": { + "name": "test-project", + "parent": "projects/test-project/locations/us-east1", + }, + } + + target := "projects/*/locations/*" + patterns := [["prod-project"], ["us-central1"]] + + whitelist := pattern_whitelist._get_whitelist(mock_resource, ["parent"], target, patterns) + + # Should find 2 violations (both positions not whitelisted) + count(whitelist) == 2 + values := {w.value | some w in whitelist} + values == {"test-project", "us-east1"} +} + +# Test 5: Multiple patterns with OR logic within position +test_get_whitelist_multiple_patterns_or_logic if { + # Mock with value matching one of multiple allowed patterns at a position + mock_resource := { + "type": "google_project", + "values": { + "name": "staging-project", + "parent": "projects/staging-project/locations/us-central1", + }, + } + + target := "projects/*/locations/*" + # First position: ["prod-project", "staging-project"] (OR logic) + # Second position: ["us-central1"] + patterns := [["prod-project", "staging-project"], ["us-central1"]] + + whitelist := pattern_whitelist._get_whitelist(mock_resource, ["parent"], target, patterns) + + # Should match both positions (staging-project matches first, us-central1 matches second) + # No violations + count(whitelist) == 0 +} + +# ============================================================================== +# MOCK DATA PROVENANCE +# ============================================================================== +# Minimal mocks in tests 6-7 are synthetic, designed to test specific logic paths. +# They represent simplified hierarchical patterns (folders/*/projects/*). +# +# Reality check (test 8) uses: tests/_helpers/fixtures/gcp_project/plan.json +# Source: inputs/gcp/cloud_platform_service/google_project/project_id/ +# Purpose: Tests pattern validation on actual project_id values (see pattern_blacklist_test.rego) +# ============================================================================== + +# Test 6: get_violations with minimal mock +test_get_violations_minimal if { + # Minimal mock with non-whitelisted pattern + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_project", + "values": { + "name": "dev-project", + "parent": "folders/dev-folder/projects/test-app", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Whitelist pattern: folders/*/projects/* where project is "prod-app" only + # First wildcard (folder) allows any value, second (project) restricted + violations := pattern_whitelist.get_violations( + tf_variables, + ["parent"], + ["folders/*/projects/*", [["dev-folder", "prod-folder"], ["prod-app"]]], + ) with input as mock_input + + # Property: Returns a set with no duplicate resource names + shared_test._assert_unique_violations(violations) + count(violations) == 1 + + # Verify violation structure (violates because project is "test-app" not "prod-app") + some v in violations + v.name == "dev-project" + shared_test._assert_valid_violation(v) + contains(v.message, "dev-project") # Resource name + contains(v.message, "'test-app'") # Violating value + contains(v.message, "should be set to one of") # Verdict +} + +# ============================================================================== +# INTEGRATION TEST (1): Complex whitelist patterns +# ============================================================================== + +# Test 7: get_violations with realistic complex patterns +test_get_violations_realistic if { + # Realistic mock with multiple wildcards and edge cases + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + # Resource with non-whitelisted pattern (single position fails) + { + "type": "google_project", + "values": { + "name": "violating-project", + "parent": "organizations/12345/folders/dev-folder", + }, + }, + # Resource with multiple position failures (CRITICAL TEST CASE) + { + "type": "google_project", + "values": { + "name": "multi-fail-project", + "parent": "organizations/99999/folders/test-folder", + }, + }, + # Resource with whitelisted pattern + { + "type": "google_project", + "values": { + "name": "compliant-project", + "parent": "organizations/12345/folders/prod-folder", + }, + }, + # Resource with null parent (edge case) + { + "type": "google_project", + "values": { + "name": "null-project", + "parent": null, + }, + }, + # Different resource type (should be ignored) + { + "type": "google_storage_bucket", + "values": { + "name": "test-bucket", + "parent": "organizations/12345/folders/dev-folder", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Pattern with 2 wildcards: organizations/*/folders/* + # Whitelist both positions to ensure only one violation per resource + # First position (org): allow "12345", second position (folder): ["prod-folder", "staging-folder"] + violations := pattern_whitelist.get_violations( + tf_variables, + ["parent"], + ["organizations/*/folders/*", [["12345"], ["prod-folder", "staging-folder"]]], + ) with input as mock_input + + # Property: Returns a set with no duplicate resource names + shared_test._assert_unique_violations(violations) + + # Should flag 2 projects: violating-project (single position) and multi-fail-project (both positions) + count(violations) == 2 + violation_name_set := {v.name | some v in violations} + violation_name_set == {"violating-project", "multi-fail-project"} + + every violation in violations { + shared_test._assert_valid_violation(violation) + contains(violation.message, "Project") + contains(violation.message, "parent") + } + + # Verify single-failure message + some single_violation in violations + single_violation.name == "violating-project" + contains(single_violation.message, "should be set to one of") + contains(single_violation.message, "'dev-folder'") + + # Verify multi-failure message mentions multiple positions + some multi_violation in violations + multi_violation.name == "multi-fail-project" + # Message should indicate multiple positions failed + contains(multi_violation.message, "Multiple positions failed") +} + +# ============================================================================== +# CRITICAL TESTS (2): Multiple failures and functional purity +# ============================================================================== + +# Test 9: Multiple position failures per resource (THE BUG THAT WAS MISSED) +test_get_violations_multiple_failures_per_resource if { + # This test validates the fix for eval_conflict_error + # When a resource fails multiple pattern positions, _build_violation must + # return exactly ONE violation object (not multiple) + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + # Resource failing ALL 3 positions + { + "type": "google_project", + "values": { + "name": "bad-project", + "project_id": "bad-wrong-invalid", + }, + }, + # Resource failing 2 positions + { + "type": "google_project", + "values": { + "name": "partial-bad", + "project_id": "proj-bad-bad", + }, + }, + # Compliant resource + { + "type": "google_project", + "values": { + "name": "good-project", + "project_id": "proj-app-dev", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Pattern: *-*-* with strict whitelist (most resources will fail) + violations := pattern_whitelist.get_violations( + tf_variables, + ["project_id"], + ["*-*-*", [["proj"], ["app", "sec"], ["dev", "prod"]]], + ) with input as mock_input + + # Property: Returns a set with no duplicate resource names + shared_test._assert_unique_violations(violations) + + # CRITICAL: Must return exactly 1 violation per resource (not 3 for bad-project) + count(violations) == 2 + + # Verify structure of resource with 3 position failures + some v1 in violations + v1.name == "bad-project" + is_string(v1.message) + # Message must mention multiple failures + contains(v1.message, "Multiple positions failed") + + # Verify structure of resource with 2 position failures + some v2 in violations + v2.name == "partial-bad" + is_string(v2.message) +} + +# Test 10: Functional purity - _build_violation returns single output +test_build_violation_functional_purity if { + # This test ensures _build_violation never produces multiple outputs + # for the same inputs (Rego functional semantics requirement) + mock_resource := { + "type": "google_project", + "values": { + "name": "test-project", + "project_id": "fail-fail-fail", + }, + } + + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Call _build_violation with resource that fails all 3 positions + # This would have caused eval_conflict_error before the fix + violation := pattern_whitelist._build_violation( + tf_variables, + ["project_id"], + ["*-*-*", [["good"], ["good"], ["good"]]], + mock_resource, + ) + + # Must return exactly ONE violation object + is_object(violation) + violation.name == "test-project" + is_string(violation.message) + violation.message != "" + + # Verify deterministic behavior - calling twice yields same result + violation2 := pattern_whitelist._build_violation( + tf_variables, + ["project_id"], + ["*-*-*", [["good"], ["good"], ["good"]]], + mock_resource, + ) + violation == violation2 +} + +# ============================================================================== +# REALITY CHECK (1): Test with real Terraform plan structure +# ============================================================================== + +# Test 8: get_violations with real Terraform plan +test_get_violations_with_real_terraform_plan if { + # Use real fixture - gcp_project from fixtures + tf_variables := { + "resource_type": "google_project", + "friendly_resource_name": "Project", + "resource_value_name": "name", + } + + # Test with real data - whitelist specific patterns + # If project has parent with hierarchical structure + violations := pattern_whitelist.get_violations( + tf_variables, + ["parent"], + ["organizations/*/folders/*", [[], ["prod", "production", "main"]]], + ) with input as data.gcp_project_plan + + # Property: Returns a set with no duplicate resource names + shared_test._assert_unique_violations(violations) + + # Verify no crashes and proper structure + every v in violations { + shared_test._assert_valid_violation(v) + contains(v.message, "Project") + contains(v.message, "should be set to one of") + } +} + +# Test 11: Utilize fixture attribute - project_id pattern from project +test_project_id_fixture if { + # Test using actual project_id patterns from gcp_project_plan + # Whitelist only dev projects with allowed teams + tf_variables := { + "resource_type": "google_project", + "resource_value_name": "name", + "friendly_resource_name": "Project", + } + + # Pattern "proj-*-*" matches: proj-app-dev, proj-sec-prod, proj-app-prod, proj-ops-staging + # Whitelist: first position can be "app", second position can be "dev" + # Only proj-app-dev (c123) matches both → compliant + # Violations: c223 (proj-sec-prod), c323 (proj-app-prod), nc223 (proj-ops-staging) + violations := pattern_whitelist.get_violations( + tf_variables, + ["project_id"], + ["proj-*-*", [["app"], ["dev"]]], + ) with input as data.gcp_project_plan + + # 3 projects match pattern but don't meet whitelist criteria + count(violations) == 3 + violation_names := {v.name | some v in violations} + violation_names == {"c223", "c323", "nc223"} + + every v in violations { + contains(v.message, "project_id") + } +} diff --git a/tests/_helpers/policy_debug.sh b/tests/_helpers/policy_debug.sh new file mode 100644 index 000000000..5d564e979 --- /dev/null +++ b/tests/_helpers/policy_debug.sh @@ -0,0 +1,136 @@ +#!/bin/bash +# Policy Debug Tool +# Shows full policy output for debugging and validation + +# Navigate to repository root +cd "$(git rev-parse --show-toplevel)" || exit 1 + +SUCCESS=0 +ERRORS=0 + +test_policy() { + local name="$1" + local input="$2" + local query="$3" + + echo "" + echo "Testing: $name" + echo "========================================" + + # Check if input file exists + if [[ ! -f "$input" ]]; then + echo "❌ ERROR: Input file not found" + echo " Path: $input" + ((ERRORS++)) + return + fi + + # Capture output and exit code + local output + local exit_code + output=$(opa eval \ + --data ./policies/_helpers \ + --data ./policies/gcp \ + --input "$input" \ + "$query" \ + --format raw 2>&1) + exit_code=$? + + # Check for errors + if [[ $exit_code -ne 0 ]]; then + echo "❌ ERROR: Policy evaluation failed" + echo "$output" + ((ERRORS++)) + return + fi + + # Parse and format the JSON output + if echo "$output" | jq -e . >/dev/null 2>&1; then + local header + local situations + + # Extract header (first element) + header=$(echo "$output" | jq -r '.[0] // empty') + + if [[ -z "$header" ]]; then + echo "❌ ERROR: Unexpected output format" + echo "$output" + ((ERRORS++)) + return + fi + + echo "$header" + + # Check if there are violations (array length > 1) + local violations_count + violations_count=$(echo "$output" | jq 'length - 1') + + if [[ $violations_count -eq 0 ]]; then + echo "Policy executed: All resources compliant" + ((SUCCESS++)) + else + echo "Policy executed: Found $violations_count violation(s)" + ((SUCCESS++)) + echo "" + + # Format each situation + echo "$output" | jq -r ' + .[] | + select(type == "array") | + to_entries | + map( + if .key == 0 then + " " + .value + else + " " + .value + end + ) | + join("\n") + ' + fi + else + # Handle non-JSON output (like "undefined") + if [[ "$output" == "undefined" ]]; then + echo "❌ ERROR: Query returned undefined (likely wrong query path)" + ((ERRORS++)) + else + echo "Output: $output" + ((SUCCESS++)) + fi + fi + + echo "" +} + +echo "Policy Debug Output" +echo "======================================" + +test_policy "Blacklist & Element Blacklist" \ + "./inputs/gcp/access_context_manager_vpc_service_controls/access_context_manager_service_perimeter/status/plan.json" \ + "data.terraform.gcp.security.access_context_manager_vpc_service_controls.access_context_manager_service_perimeter.status.message" + +test_policy "Whitelist" \ + "./inputs/gcp/api_hub/google_apihub_api_hub_instance/config_encryption_type/plan.json" \ + "data.terraform.gcp.security.api_hub.google_apihub_api_hub_instance.config_encryption_type.message" + +test_policy "Range" \ + "./inputs/gcp/cloud_storage/google_storage_bucket/retention_period/plan.json" \ + "data.terraform.gcp.security.cloud_storage.google_storage_bucket.retention_period.message" + +test_policy "Pattern Blacklist" \ + "./inputs/gcp/cloud_storage/google_storage_default_object_acl/public_access_prevention/plan.json" \ + "data.terraform.gcp.security.cloud_storage.google_storage_default_object_acl.public_access_prevention.message" + +test_policy "Pattern Whitelist" \ + "./inputs/gcp/cloud_platform_service/google_project/project_id/plan.json" \ + "data.terraform.gcp.security.cloud_platform_service.google_project.project_id.message" + +echo "" +echo "======================================" +echo "Summary" +echo "======================================" +echo "✅ Successful: $SUCCESS" +echo "❌ Errors: $ERRORS" +echo "======================================" + +exit $ERRORS diff --git a/tests/_helpers/range_test.rego b/tests/_helpers/range_test.rego new file mode 100644 index 000000000..8d80b3fa0 --- /dev/null +++ b/tests/_helpers/range_test.rego @@ -0,0 +1,234 @@ +package terraform.helpers.policies.range_test + +# Range Policy Test Suite +# +# Tests the range policy module which validates numeric attributes fall within bounds. +# Covers boundary values and numeric edge cases. Both bounds are required. + +import data.terraform.helpers.policies.range +import data.terraform.helpers.shared +import data.terraform.helpers.shared_test +import rego.v1 + +# ============================================================================== +# UNIT TESTS (6): Test _test_value_range helper function +# ============================================================================== + +# Test 1: Value within range (happy path) +test_value_range_within if { + range._test_value_range(50, 10, 100) +} + +# Test 2: Value below range (boundary: below) +test_value_range_below if { + not range._test_value_range(5, 10, 100) +} + +# Test 3: Value above range (boundary: above) +test_value_range_above if { + not range._test_value_range(150, 10, 100) +} + +# Test 4: Value at lower boundary (boundary: exact min) +test_value_range_lower_boundary if { + range._test_value_range(10, 10, 100) +} + +# Test 5: Value at upper boundary (boundary: exact max) +test_value_range_upper_boundary if { + range._test_value_range(100, 10, 100) +} + +# ============================================================================== +# MOCK DATA PROVENANCE +# ============================================================================== +# Minimal mocks in tests 6-7 are synthetic, designed to test specific logic paths. +# They represent simplified versions of real Terraform resources with controlled +# numeric values to validate boundary conditions. +# +# Reality check (test 8) uses: tests/_helpers/fixtures/gcp_storage_bucket/plan.json +# Source: inputs/gcp/cloud_storage/google_storage_bucket/retention_period/ +# Purpose: Tests numeric range validation on actual retention_period values: +# - c123: retention_period=604800 (7 days in seconds) +# - nc123: retention_period=2692000 (31 days in seconds) +# ============================================================================== + +# Test 6: get_violations with minimal mock (violation + compliant) +test_get_violations_minimal if { + # Mock with resources in and out of range + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_storage_bucket", + "values": { + "name": "compliant-bucket", + "retention_policy": [ + { + "retention_period": 90, + }, + ], + }, + }, + { + "type": "google_storage_bucket", + "values": { + "name": "violating-bucket", + "retention_policy": [ + { + "retention_period": 400, + }, + ], + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Range: [30, 365] days + violations := range.get_violations( + tf_variables, + ["retention_policy", 0, "retention_period"], + [30, 365], + ) with input as mock_input + + count(violations) == 1 + some v in violations + v.name == "violating-bucket" + shared_test._assert_valid_violation(v) + contains(v.message, "violating-bucket") # Resource name + contains(v.message, "400") # Violating value + contains(v.message, "must be between") # Verdict +} + +# ============================================================================== +# INTEGRATION TEST (1): Numeric edge cases +# ============================================================================== + +# Test 7: get_violations with realistic numeric edge cases +test_get_violations_realistic if { + # Realistic mock with various numeric edge cases + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + # Resource with value in range + { + "type": "google_storage_bucket", + "values": { + "name": "compliant-bucket", + "lifecycle_rule": [ + { + "action": [{"type": "Delete"}], + "condition": [{"age": 30}], + }, + ], + }, + }, + # Resource with value below range + { + "type": "google_storage_bucket", + "values": { + "name": "below-bucket", + "lifecycle_rule": [ + { + "action": [{"type": "Delete"}], + "condition": [{"age": -10}], + }, + ], + }, + }, + # Resource with large value (out of range) + { + "type": "google_storage_bucket", + "values": { + "name": "large-bucket", + "lifecycle_rule": [ + { + "action": [{"type": "Delete"}], + "condition": [{"age": 10000}], + }, + ], + }, + }, + # Different resource type (should be ignored) + { + "type": "google_project", + "values": { + "name": "test-project", + "lifecycle_rule": [ + { + "action": [{"type": "Delete"}], + "condition": [{"age": 5000}], + }, + ], + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Range: [0, 365] - zero is inclusive, negatives and large values violate + violations := range.get_violations( + tf_variables, + ["lifecycle_rule", 0, "condition", 0, "age"], + [0, 365], + ) with input as mock_input + + # Should flag below-bucket and large-bucket + count(violations) == 2 + violation_names := {v.name | some v in violations} + violation_names == {"below-bucket", "large-bucket"} + + # Verify messages include range information + every v in violations { + contains(v.message, "must be between") + contains(v.message, "0") + contains(v.message, "365") + } +} + +# ============================================================================== +# REALITY CHECK (1): Test with real Terraform plan structure +# ============================================================================== + +# Test 8: get_violations with real Terraform plan +test_real_plan_violations if { + # Use real fixture - gcp_storage_bucket from fixtures + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Test with real data - check retention_period attribute + # Range: 604800 to 2592000 seconds (7 to 30 days) + violations := range.get_violations( + tf_variables, + ["retention_policy", 0, "retention_period"], + [604800, 2592000], # 7 days to 30 days in seconds + ) with input as data.gcp_storage_bucket_plan + + # Verify no crashes and proper structure + is_set(violations) + every v in violations { + shared_test._assert_valid_violation(v) + contains(v.message, "Storage Bucket") + contains(v.message, "must be between") + } +} diff --git a/tests/_helpers/shared_test.rego b/tests/_helpers/shared_test.rego new file mode 100644 index 000000000..3bfe4901a --- /dev/null +++ b/tests/_helpers/shared_test.rego @@ -0,0 +1,326 @@ +package terraform.helpers.shared_test + +# Shared Utilities Test Suite +# +# Tests the shared utility module which provides helper functions used by all policy types. +# Foundation tests - all other policy tests depend on these utilities working correctly. + +import rego.v1 + +import data.terraform.helpers.shared + +# ============================================================================== +# UNIT TESTS (10): Test individual utility functions +# ============================================================================== + +# Test 1: get_resource_attribute - Happy Path +test_get_resource_attribute_found if { + resource := {"values": {"name": "test-resource"}} + result := shared.get_resource_attribute(resource, "name") + result == "test-resource" +} + +# Test 2: get_resource_attribute - Not Found +test_get_resource_attribute_not_found if { + resource := {"values": {}} + result := shared.get_resource_attribute(resource, "missing_key") + result == null +} + +# Test 3: format_attribute_path - Array Path +test_format_attribute_path_array if { + path := ["status", 0, "restricted_services"] + result := shared.format_attribute_path(path) + result == "status.[0].restricted_services" +} + +# Test 4: format_attribute_path - String Path +test_format_attribute_path_string if { + path := "attribute_name" + result := shared.format_attribute_path(path) + result == "attribute name" +} + +# Test 5: ensure_array - Already Array +test_ensure_array_with_array if { + input_array := [1, 2, 3] + result := shared.ensure_array(input_array) + result == [1, 2, 3] +} + +# Test 6: ensure_array - Scalar to Array +test_ensure_array_with_scalar if { + input_scalar := "value" + result := shared.ensure_array(input_scalar) + result == ["value"] +} + +# Test 7: value_in_array - Exists +test_value_in_array_exists if { + array := [1, 2, 3] + value := 2 + shared.value_in_array(array, value) +} + +# Test 8: value_in_array - Not Exists +test_value_in_array_not_exists if { + array := [1, 2, 3] + value := 4 + not shared.value_in_array(array, value) +} + +# Test 9: get_target_list - Wildcard Extraction +test_get_target_list_wildcard_extraction if { + mock_resource := { + "values": { + "project_id": "projects/test-project/locations/us-east1", + }, + } + attribute_path := ["project_id"] + target := "projects/*/locations/*" + result := shared.get_target_list(mock_resource, attribute_path, target) + result == ["test-project", "us-east1"] +} + +# Test 10: final_formatter - Pattern Highlighting +test_final_formatter_highlight if { + target := "projects/test-project/locations/us" + sub_pattern := "test-project" + result := shared.final_formatter(target, sub_pattern) + result == "projects/'test-project'/locations/us" +} + +# ============================================================================== +# INTEGRATION TEST (1): Deep Nesting (Realistic Mock) +# ============================================================================== +# ============================================================================ +# MOCK DATA PROVENANCE +# ============================================================================ +# Source: tests/_helpers/fixtures/real_terraform_plans/gcp_access_level_plan.json +# Extracted: 2025-12-02 +# Terraform: v1.12.2 +# Provider: google (from plan file) +# +# Fields used in this mock: basic, basic.conditions, basic.conditions.device_policy +# Testing: Deep nested path access (5 levels) +# +# Fields intentionally omitted: custom, description, timeouts, title +# Reason: Not needed for nested attribute access testing +# +# Validation: See mock_validator_test.rego +# ============================================================================ + +# Test 11: Deep nesting with realistic mock +test_shared_utilities_with_deep_nesting if { + # Realistic mock with 5 levels of nesting from real Terraform plan + mock_resource := { + "type": "google_access_context_manager_access_level", + "values": { + "basic": [{ + "conditions": [{ + "device_policy": [{ + "require_screen_lock": true, + "os_constraints": [{"os_type": "DESKTOP_CHROME_OS"}], + }], + "regions": ["US", "EU"], + }], + }], + }, + } + + # Test get_attribute_value with deep path + screen_lock := shared.get_attribute_value( + mock_resource, + ["basic", 0, "conditions", 0, "device_policy", 0, "require_screen_lock"], + ) + screen_lock == true + + # Test format_attribute_path with complex array indices + formatted_path := shared.format_attribute_path([ + "basic", + 0, + "conditions", + 0, + "device_policy", + 0, + "require_screen_lock", + ]) + formatted_path == "basic.[0].conditions.[0].device_policy.[0].require_screen_lock" + + # Test ensure_array with nested array attribute + regions := shared.get_attribute_value(mock_resource, ["basic", 0, "conditions", 0, "regions"]) + ensured_regions := shared.ensure_array(regions) + ensured_regions == ["US", "EU"] +} + +# ============================================================================== +# ARRAY-OF-OBJECTS FIELD EXTRACTION (1): Test new enhancement +# ============================================================================== + +# Test 12: Array-of-objects field extraction (new enhancement) +test_get_attribute_value_array_of_objects_extraction if { + # Mock resource with array of objects (realistic os_constraints pattern) + mock_resource := { + "type": "google_access_context_manager_access_level", + "values": { + "basic": [{ + "conditions": [{ + "device_policy": [{ + "os_constraints": [ + {"os_type": "ANDROID", "minimum_version": "10"}, + {"os_type": "IOS", "minimum_version": "14"}, + {"os_type": "OS_UNSPECIFIED", "minimum_version": null}, + ], + }], + }], + }], + }, + } + + # Test: Extract os_type field from array of objects + os_types := shared.get_attribute_value( + mock_resource, + ["basic", 0, "conditions", 0, "device_policy", 0, "os_constraints", "os_type"], + ) + + # Should return array of extracted field values + trace(sprintf("Extracted os_types: %v", [os_types])) + is_array(os_types) + count(os_types) == 3 + os_types == ["ANDROID", "IOS", "OS_UNSPECIFIED"] + + # Test: Also works with other fields in the same array + versions := shared.get_attribute_value( + mock_resource, + ["basic", 0, "conditions", 0, "device_policy", 0, "os_constraints", "minimum_version"], + ) + trace(sprintf("Extracted versions: %v", [versions])) + is_array(versions) + count(versions) == 2 # null values are filtered out + versions == ["10", "14"] +} + +# Test 13: Array-of-objects extraction edge cases +test_get_attribute_value_array_of_objects_edge_cases if { + mock_resource := { + "type": "test_resource", + "values": { + "empty_array": [], + "scalar_value": "not-an-array", + "array_of_scalars": ["a", "b", "c"], + "nested": [{ + "items": [ + {"field": "value1"}, + {"field": "value2"}, + {"different": "ignored"}, # Missing 'field' key + ], + }], + }, + } + + # Empty array should return null (fallback to object.get) + empty_result := shared.get_attribute_value(mock_resource, ["empty_array", "field"]) + empty_result == null + + # Scalar value with field access should return null + scalar_result := shared.get_attribute_value(mock_resource, ["scalar_value", "field"]) + scalar_result == null + + # Array of scalars (not objects) should return null + scalar_array_result := shared.get_attribute_value(mock_resource, ["array_of_scalars", "field"]) + scalar_array_result == null + + # Extraction from nested array with missing field in some objects + nested_result := shared.get_attribute_value(mock_resource, ["nested", 0, "items", "field"]) + trace(sprintf("Nested extraction: %v", [nested_result])) + is_array(nested_result) + count(nested_result) == 2 # Only objects with 'field' key + nested_result == ["value1", "value2"] +} + +# ============================================================================== +# REALITY CHECK (1): Test with real Terraform plan structure +# ============================================================================== + +# Test 14: Reality check with actual fixture data +test_shared_utilities_with_real_structure if { + # Access real Terraform plan loaded by OPA from fixtures/gcp_access_level/ + # The wrapped file loads as data.gcp_access_level_plan (wrapper key becomes the path) + real_plan_data := data.gcp_access_level_plan + + trace(sprintf("Assertion 1: Plan data loaded = %v", [real_plan_data != null])) + real_plan_data != null + + real_resource := real_plan_data.planned_values.root_module.resources[0] + trace(sprintf("Assertion 2: Resource exists = %v", [real_resource != null])) + real_resource != null + + trace(sprintf("Assertion 3: Resource type = %v (expected google_access_context_manager_access_level)", [real_resource.type])) + real_resource.type == "google_access_context_manager_access_level" + + basic_config := shared.get_resource_attribute(real_resource, "basic") + trace(sprintf("Assertion 4: basic_config type = %v, is_array = %v", [type_name(basic_config), is_array(basic_config)])) + is_array(basic_config) + + trace(sprintf("Assertion 5: basic_config count = %v", [count(basic_config)])) + count(basic_config) > 0 + + require_screen_lock := shared.get_attribute_value( + real_resource, + ["basic", 0, "conditions", 0, "device_policy", 0, "require_screen_lock"], + ) + trace(sprintf("Assertion 6: require_screen_lock = %v, type = %v", [require_screen_lock, type_name(require_screen_lock)])) + require_screen_lock != null + + # Assertion 7: Should be boolean (validates deep path exists in real data) + trace(sprintf("Assertion 7: require_screen_lock is_boolean = %v", [is_boolean(require_screen_lock)])) + is_boolean(require_screen_lock) + + conditions := real_resource.values.basic[0].conditions + trace(sprintf("Assertion 8: conditions is_array = %v, type = %v", [is_array(conditions), type_name(conditions)])) + is_array(conditions) +} + +# ============================================================================== +# TEST ASSERTION HELPERS (4): Reusable validation functions +# ============================================================================== + +# Verifies violations is a set with no duplicate resource names +_assert_unique_violations(violations) if { + is_set(violations) + violation_names := [v.name | some v in violations] + count(violation_names) == count({n | some n in violation_names}) +} + +# Verifies a single violation has the required structure +_assert_valid_violation(v) if { + is_string(v.name) + is_string(v.message) + v.name != "" + v.message != "" +} + +# Test 13: Assertion helper - Unique violations +test_assert_unique_violations_pass if { + mock_violations := { + {"name": "resource-1", "message": "error 1"}, + {"name": "resource-2", "message": "error 2"}, + } + _assert_unique_violations(mock_violations) +} + +# Test 14: Assertion helper - Valid violation structure +test_assert_valid_violation_pass if { + mock_violation := {"name": "test-resource", "message": "Test violation message"} + _assert_valid_violation(mock_violation) +} + +test_assert_valid_violation_fails_empty_name if { + mock_violation := {"name": "", "message": "Test violation message"} + not _assert_valid_violation(mock_violation) +} + +test_assert_valid_violation_fails_empty_message if { + mock_violation := {"name": "test-resource", "message": ""} + not _assert_valid_violation(mock_violation) +} diff --git a/tests/_helpers/smoke_test_helpers.sh b/tests/_helpers/smoke_test_helpers.sh new file mode 100644 index 000000000..0b4af5f5a --- /dev/null +++ b/tests/_helpers/smoke_test_helpers.sh @@ -0,0 +1,122 @@ +#!/bin/bash +# Smoke tests for helper refactoring +# Tests all 6 policy types with minimal output for quick verification + +# Navigate to repository root +cd "$(git rev-parse --show-toplevel)" || exit 1 + +echo "Helper Refactor Smoke Tests" +echo "================================" +echo "Testing against actual Terraform plans for:" +echo " • access_context_manager_service_perimeter.status" +echo " • google_apihub_api_hub_instance.config_encryption_type" +echo " • google_storage_bucket.retention_period" +echo " • google_storage_default_object_acl.public_access_prevention" +echo " • google_project.project_id" +echo "" + +FAILED=0 +PASSED=0 + +run_test() { + local name="$1" + local input="$2" + local query="$3" + local expected_violations="$4" + local expected_resource="$5" + + echo -n "Testing $name... " + + # Check if input file exists + if [[ ! -f "$input" ]]; then + echo "❌ FAIL (input file not found: $input)" + ((FAILED++)) + return + fi + + # Capture output and exit code + local output + local exit_code + output=$(opa eval \ + --data ./policies/_helpers \ + --data ./policies/gcp \ + --input "$input" \ + "$query" \ + --format raw 2>&1) + exit_code=$? + + # Check for OPA errors + if [[ $exit_code -ne 0 ]]; then + echo "❌ FAIL (policy error: $output)" + ((FAILED++)) + return + fi + + # Validate output is valid JSON + if ! echo "$output" | jq -e . >/dev/null 2>&1; then + echo "❌ FAIL (invalid JSON output)" + ((FAILED++)) + return + fi + + # Check expected violation count + local violation_count + violation_count=$(echo "$output" | jq 'length - 1') + + if [[ "$violation_count" != "$expected_violations" ]]; then + echo "❌ FAIL (expected $expected_violations violations, found $violation_count)" + ((FAILED++)) + return + fi + + # If expecting violations, check for expected resource in output + if [[ $expected_violations -gt 0 ]] && [[ -n "$expected_resource" ]]; then + if ! echo "$output" | grep -q "$expected_resource"; then + echo "❌ FAIL (expected resource '$expected_resource' not found in output)" + ((FAILED++)) + return + fi + fi + + echo "✅ PASS" + ((PASSED++)) +} + +# Test all 6 policy types +# Format: run_test "name" "input" "query" expected_violations expected_resource_in_output + +run_test "Blacklist & Element Blacklist" \ + "./inputs/gcp/access_context_manager_vpc_service_controls/access_context_manager_service_perimeter/status/plan.json" \ + "data.terraform.gcp.security.access_context_manager_vpc_service_controls.access_context_manager_service_perimeter.status.message" \ + 1 \ + "nc-null-restricted-services" + +run_test "Whitelist" \ + "./inputs/gcp/api_hub/google_apihub_api_hub_instance/config_encryption_type/plan.json" \ + "data.terraform.gcp.security.api_hub.google_apihub_api_hub_instance.config_encryption_type.message" \ + 0 \ + "" + +run_test "Range" \ + "./inputs/gcp/cloud_storage/google_storage_bucket/retention_period/plan.json" \ + "data.terraform.gcp.security.cloud_storage.google_storage_bucket.retention_period.message" \ + 1 \ + "nc123" + +run_test "Pattern Blacklist" \ + "./inputs/gcp/cloud_storage/google_storage_default_object_acl/public_access_prevention/plan.json" \ + "data.terraform.gcp.security.cloud_storage.google_storage_default_object_acl.public_access_prevention.message" \ + 1 \ + "nc123" + +run_test "Pattern Whitelist" \ + "./inputs/gcp/cloud_platform_service/google_project/project_id/plan.json" \ + "data.terraform.gcp.security.cloud_platform_service.google_project.project_id.message" \ + 1 \ + "nc123" + +echo "" +echo "================================" +echo "Results: $PASSED passed, $FAILED failed" + +exit $FAILED diff --git a/tests/_helpers/unit_test_helpers.sh b/tests/_helpers/unit_test_helpers.sh new file mode 100644 index 000000000..578e2ef65 --- /dev/null +++ b/tests/_helpers/unit_test_helpers.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# Unit tests for policy helpers +# Runs comprehensive test suites for all helper modules with fixtures + +# Navigate to repository root +cd "$(git rev-parse --show-toplevel)" || exit 1 + +echo "Policy Helper Unit Tests" +echo "============================" + +# Common fixtures needed by all tests +FIXTURES=( + "tests/_helpers/fixtures/gcp_storage_bucket/plan.json" + "tests/_helpers/fixtures/gcp_project/plan.json" + "tests/_helpers/fixtures/gcp_access_level/plan.json" +) + +# Common helper modules +HELPERS=( + "policies/_helpers/shared.rego" +) + +# Test utilities (assertion helpers used by all test files) +TEST_HELPERS=( + "tests/_helpers/shared_test.rego" +) + +FAILED=0 +PASSED=0 +TOTAL_TESTS_PASSED=0 +TOTAL_TESTS_FAILED=0 + +run_test_suite() { + local name="$1" + local test_file="$2" + local policy_file="$3" + local include_test_helpers="${4:-true}" # Default to true + + echo "" + echo "Testing $name..." + echo "============================" + + # Build test command with optional test helpers + if [ "$include_test_helpers" = "true" ]; then + output=$(opa test "$test_file" "$policy_file" "${HELPERS[@]}" "${TEST_HELPERS[@]}" "${FIXTURES[@]}" -v 2>&1) + else + output=$(opa test "$test_file" "$policy_file" "${HELPERS[@]}" "${FIXTURES[@]}" -v 2>&1) + fi + exit_code=$? + + echo "$output" + + if [ $exit_code -eq 0 ]; then + ((PASSED++)) + # Count PASS occurrences in individual test lines (format: "data.package.test_name: PASS") + pass_count=$(echo "$output" | grep -c ": PASS") + ((TOTAL_TESTS_PASSED += pass_count)) + else + ((FAILED++)) + # Count both PASS and FAIL occurrences in individual test lines + pass_count=$(echo "$output" | grep -c ": PASS") + fail_count=$(echo "$output" | grep -c ": FAIL") + ((TOTAL_TESTS_PASSED += pass_count)) + ((TOTAL_TESTS_FAILED += fail_count)) + fi +} + +# Run all helper test suites +run_test_suite "Shared Helpers" \ + "tests/_helpers/shared_test.rego" \ + "policies/_helpers/shared.rego" \ + "false" # Don't include shared_test.rego when testing itself + +run_test_suite "Blacklist Policy" \ + "tests/_helpers/blacklist_test.rego" \ + "policies/_helpers/policies/blacklist.rego" + +run_test_suite "Whitelist Policy" \ + "tests/_helpers/whitelist_test.rego" \ + "policies/_helpers/policies/whitelist.rego" + +run_test_suite "Range Policy" \ + "tests/_helpers/range_test.rego" \ + "policies/_helpers/policies/range.rego" + +run_test_suite "Pattern Blacklist Policy" \ + "tests/_helpers/pattern_blacklist_test.rego" \ + "policies/_helpers/policies/pattern_blacklist.rego" + +run_test_suite "Pattern Whitelist Policy" \ + "tests/_helpers/pattern_whitelist_test.rego" \ + "policies/_helpers/policies/pattern_whitelist.rego" + +run_test_suite "Element Blacklist Policy" \ + "tests/_helpers/element_blacklist_test.rego" \ + "policies/_helpers/policies/element_blacklist.rego" + +echo "" +echo "================================" +echo "Test Suites: $PASSED passed, $FAILED failed" +echo "Total Tests: $TOTAL_TESTS_PASSED passed, $TOTAL_TESTS_FAILED failed" + +exit $FAILED diff --git a/tests/_helpers/whitelist_test.rego b/tests/_helpers/whitelist_test.rego new file mode 100644 index 000000000..f6cbaee8e --- /dev/null +++ b/tests/_helpers/whitelist_test.rego @@ -0,0 +1,345 @@ +package terraform.helpers.policies.whitelist_test + +# Whitelist Policy Test Suite +# +# Tests the whitelist policy module which detects resources with non-allowed values. +# Covers scalar values, array AND logic (all must be whitelisted), and message formatting. + +import data.terraform.helpers.policies.whitelist +import data.terraform.helpers.shared +import data.terraform.helpers.shared_test +import rego.v1 + +# ============================================================================== +# UNIT TESTS (6): Test _is_whitelisted helper function +# ============================================================================== + +# Test 1: Scalar value in whitelist (boundary: match) +test_is_whitelisted_scalar_match if { + whitelist._is_whitelisted(["allowed", "permitted"], "allowed") +} + +# Test 2: Scalar value not in whitelist (boundary: no match) +test_is_whitelisted_scalar_no_match if { + not whitelist._is_whitelisted(["allowed", "permitted"], "forbidden") +} + +# Test 3: Array with ALL whitelisted values (AND logic proof) +test_is_whitelisted_array_all_match if { + whitelist._is_whitelisted(["good", "better", "best"], ["good", "best"]) +} + +# Test 4: Array with SOME non-whitelisted values (AND logic negative) +test_is_whitelisted_array_partial_match if { + not whitelist._is_whitelisted(["good", "better"], ["good", "bad"]) +} + +# Test 5: Empty array whitelisting (edge case) +test_is_whitelisted_empty_array if { + whitelist._is_whitelisted(["allowed"], []) +} + +# ============================================================================== +# MOCK DATA PROVENANCE +# ============================================================================== +# Minimal mocks in tests 6-10 are synthetic, designed to test specific logic paths. +# They represent simplified versions of real Terraform resources with controlled +# attributes to validate exact behavior (e.g., AND logic, edge cases). +# +# Reality check (test 8) uses: tests/_helpers/fixtures/gcp_storage_bucket/plan.json +# Source: inputs/gcp/cloud_storage/google_storage_bucket/retention_period/ +# Purpose: Tests against actual Terraform plan structure (see blacklist_test.rego) +# ============================================================================== + +# Test 6: get_violations with minimal mock (happy path + structure validation) +test_get_violations_minimal if { + # Minimal mock with non-whitelisted location + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_storage_bucket", + "values": { + "name": "test-bucket", + "location": "ASIA", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + violations := whitelist.get_violations( + tf_variables, + ["location"], + ["US", "EU"], + ) with input as mock_input + + count(violations) == 1 + some v in violations + v.name == "test-bucket" + shared_test._assert_valid_violation(v) + contains(v.message, "test-bucket") # Resource name + contains(v.message, "ASIA") # Violating value + contains(v.message, "should be set to") # Verdict +} + +# ============================================================================== +# INTEGRATION TEST (1): Realistic structure with edge cases +# ============================================================================== + +# Test 7: get_violations with realistic Terraform structures +test_get_violations_realistic if { + # Realistic mock including edge cases + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + # Resource with non-whitelisted value + { + "type": "google_storage_bucket", + "values": { + "name": "violating-bucket", + "location": "ASIA", + "storage_class": "STANDARD", + }, + }, + # Resource with whitelisted value + { + "type": "google_storage_bucket", + "values": { + "name": "compliant-bucket", + "location": "US", + "storage_class": "STANDARD", + }, + }, + # Resource with null location (edge case - should violate) + { + "type": "google_storage_bucket", + "values": { + "name": "null-bucket", + "location": null, + "storage_class": "STANDARD", + }, + }, + # Different resource type (should be ignored) + { + "type": "google_project", + "values": { + "name": "test-project", + "location": "ASIA", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + violations := whitelist.get_violations( + tf_variables, + ["location"], + ["US", "EU"], + ) with input as mock_input + + # Should flag violating-bucket and null-bucket + count(violations) == 2 + violation_names := {v.name | some v in violations} + violation_names == {"violating-bucket", "null-bucket"} + + # Verify message format + some v in violations + v.name == "violating-bucket" + contains(v.message, "Storage Bucket") + contains(v.message, "location") + contains(v.message, "should be set to") +} + +# ============================================================================== +# REALITY CHECK (1): Test with real Terraform plan structure +# ============================================================================== + +# Test 8: get_violations with real Terraform plan +test_get_violations_with_real_terraform_plan if { + # Use real fixture - gcp_storage_bucket from fixtures + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Test with real data - whitelist specific locations + violations := whitelist.get_violations( + tf_variables, + ["location"], + ["US-CENTRAL1", "US-EAST1"], + ) with input as data.gcp_storage_bucket_plan + + is_set(violations) + every v in violations { + shared_test._assert_valid_violation(v) + contains(v.message, "Storage Bucket") + contains(v.message, "location") + contains(v.message, "should be set to") + } +} + +# Test 11: Utilize fixture attribute - storage_class whitelist +test_storage_class_fixture if { + # Test using actual storage_class attribute from gcp_storage_bucket_plan + # Fixture has storage_class: "STANDARD" for both buckets + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Whitelist only NEARLINE and COLDLINE (both buckets should violate) + violations := whitelist.get_violations( + tf_variables, + ["storage_class"], + ["NEARLINE", "COLDLINE"], + ) with input as data.gcp_storage_bucket_plan + + # Both c123 and nc123 have non-whitelisted storage_class: "STANDARD" + count(violations) == 2 + violation_names := {v.name | some v in violations} + violation_names == {"c123", "nc123"} + + every v in violations { + contains(v.message, "storage_class") + contains(v.message, "STANDARD") + contains(v.message, "should be set to") + } +} + +# ============================================================================== +# ADDITIONAL TESTS (2): Real-world usage patterns +# ============================================================================== + +# Test 9: Boolean whitelisting (real-world use case - versioning enabled) +test_get_violations_boolean_whitelist if { + # Mock matching real policy: versioning.enabled must be true + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_storage_bucket", + "values": { + "name": "compliant-bucket", + "versioning": [ + { + "enabled": true, + }, + ], + "location": "US", + }, + }, + { + "type": "google_storage_bucket", + "values": { + "name": "non-compliant-bucket", + "versioning": [ + { + "enabled": false, + }, + ], + "location": "US", + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Whitelist versioning.enabled: true (actual policy usage pattern) + violations := whitelist.get_violations( + tf_variables, + ["versioning", 0, "enabled"], + [true], + ) with input as mock_input + + # Should only flag non-compliant-bucket + count(violations) == 1 + some v in violations + v.name == "non-compliant-bucket" + contains(v.message, "versioning") + contains(v.message, "false") + contains(v.message, "should be set to") +} + +# Test 10: Array attribute with AND logic (all elements must be whitelisted) +test_get_violations_array_attribute_and_logic if { + # Mock with array attributes testing AND logic + mock_input := { + "planned_values": { + "root_module": { + "resources": [ + { + "type": "google_storage_bucket", + "values": { + "name": "compliant-bucket", + "cors": [ + { + "method": ["GET", "POST"], + "origin": ["https://example.com"], + }, + ], + }, + }, + { + "type": "google_storage_bucket", + "values": { + "name": "violating-bucket", + "cors": [ + { + "method": ["GET", "DELETE"], + "origin": ["https://example.com"], + }, + ], + }, + }, + ], + }, + }, + } + + tf_variables := { + "resource_type": "google_storage_bucket", + "friendly_resource_name": "Storage Bucket", + "resource_value_name": "name", + } + + # Whitelist only safe HTTP methods (AND logic: ALL must be in whitelist) + violations := whitelist.get_violations( + tf_variables, + ["cors", 0, "method"], + ["GET", "POST", "HEAD"], + ) with input as mock_input + + # Should flag bucket with DELETE (not in whitelist) + count(violations) == 1 + some v in violations + v.name == "violating-bucket" + contains(v.message, "cors") + contains(v.message, "method") +} From 6224c815a075cc099af505296c937a1c403f8c20 Mon Sep 17 00:00:00 2001 From: Tikster123 Date: Wed, 17 Dec 2025 19:06:58 +1100 Subject: [PATCH 2/9] Merge main branch - kept main version of test/template files --- .../backup_channel/description/plan.json | Bin 17920 -> 8478 bytes .../backup_plan/backup_config/plan.json | Bin 14690 -> 14690 bytes .../backup_plan/backup_config/policy.rego | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/plan.json b/inputs/gcp/backup_for_gke/backup_channel/description/plan.json index 8d3f9032567ab52861833517b08be9b9fa96399a..ed568edd2b217afa436e7a9d5a804f0d4b7b789a 100644 GIT binary patch literal 8478 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 Date: Wed, 17 Dec 2025 22:03:15 +1100 Subject: [PATCH 3/9] Resolve merge conflicts - use main branch versions of test/template files --- templates/gcp/c.tf | 6 -- tests/_helpers/check_ux.sh | 82 ---------------- tests/_helpers/policy_debug.sh | 136 --------------------------- tests/_helpers/smoke_test_helpers.sh | 122 ------------------------ tests/_helpers/unit_test_helpers.sh | 103 -------------------- 5 files changed, 449 deletions(-) delete mode 100644 templates/gcp/c.tf delete mode 100644 tests/_helpers/check_ux.sh delete mode 100644 tests/_helpers/policy_debug.sh delete mode 100644 tests/_helpers/smoke_test_helpers.sh delete mode 100644 tests/_helpers/unit_test_helpers.sh diff --git a/templates/gcp/c.tf b/templates/gcp/c.tf deleted file mode 100644 index 9343bf01c..000000000 --- a/templates/gcp/c.tf +++ /dev/null @@ -1,6 +0,0 @@ -# Describe your resource type here -# Keep "c" as the name to indicate that this resource and its attributes are compliant - -resource "RESOURCE TYPE" "c" { - -} diff --git a/tests/_helpers/check_ux.sh b/tests/_helpers/check_ux.sh deleted file mode 100644 index 775037ee2..000000000 --- a/tests/_helpers/check_ux.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash -# UX Message Review Tool -# Displays actual violation messages to verify they are clear and actionable - -# Navigate to repository root -cd "$(git rev-parse --show-toplevel)" || exit 1 - -echo "🔍 UX Message Review" -echo "======================================" -echo "" - -inspect_policy() { - local name="$1" - local input="$2" - local query="$3" - - - echo "Policy: $name" - echo "======================================" - echo "" - - # Get message and details fields - message=$(opa eval \ - --data ./policies/_helpers \ - --data ./policies/gcp \ - --input "$input" \ - "${query}.message" \ - --format pretty 2>&1) - - details=$(opa eval \ - --data ./policies/_helpers \ - --data ./policies/gcp \ - --input "$input" \ - "${query}.details" \ - --format pretty 2>&1) - - if [ $? -eq 0 ]; then - echo "MESSAGE:" - echo "$message" - echo "" - echo "DETAILS:" - echo "$details" - else - echo "❌ Error evaluating policy:" - echo "$message" - fi - - echo "" - echo "" -} - -# Test all 6 policy types with their violations - -inspect_policy "Blacklist & Element Blacklist (Access Context Manager)" \ - "./inputs/gcp/access_context_manager_vpc_service_controls/access_context_manager_service_perimeter/status/plan.json" \ - "data.terraform.gcp.security.access_context_manager_vpc_service_controls.access_context_manager_service_perimeter.status" - -inspect_policy "Whitelist (API Hub Encryption)" \ - "./inputs/gcp/api_hub/google_apihub_api_hub_instance/config_encryption_type/plan.json" \ - "data.terraform.gcp.security.api_hub.google_apihub_api_hub_instance.config_encryption_type" - -inspect_policy "Range (Storage Bucket Retention Period)" \ - "./inputs/gcp/cloud_storage/google_storage_bucket/retention_period/plan.json" \ - "data.terraform.gcp.security.cloud_storage.google_storage_bucket.retention_period" - -inspect_policy "Pattern Blacklist (Storage Default Object ACL)" \ - "./inputs/gcp/cloud_storage/google_storage_default_object_acl/public_access_prevention/plan.json" \ - "data.terraform.gcp.security.cloud_storage.google_storage_default_object_acl.public_access_prevention" - -inspect_policy "Pattern Whitelist (Project ID)" \ - "./inputs/gcp/cloud_platform_service/google_project/project_id/plan.json" \ - "data.terraform.gcp.security.cloud_platform_service.google_project.project_id" - -echo "======================================" -echo "✅ Inspection complete" -echo "" -echo "Use this to verify:" -echo " - Violation messages are clear and actionable" -echo " - Resource names are displayed correctly" -echo " - Attribute paths are formatted properly" -echo " - Blacklist/whitelist values are shown" -echo " - Empty values show (EMPTY!) warning" diff --git a/tests/_helpers/policy_debug.sh b/tests/_helpers/policy_debug.sh deleted file mode 100644 index 5d564e979..000000000 --- a/tests/_helpers/policy_debug.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/bash -# Policy Debug Tool -# Shows full policy output for debugging and validation - -# Navigate to repository root -cd "$(git rev-parse --show-toplevel)" || exit 1 - -SUCCESS=0 -ERRORS=0 - -test_policy() { - local name="$1" - local input="$2" - local query="$3" - - echo "" - echo "Testing: $name" - echo "========================================" - - # Check if input file exists - if [[ ! -f "$input" ]]; then - echo "❌ ERROR: Input file not found" - echo " Path: $input" - ((ERRORS++)) - return - fi - - # Capture output and exit code - local output - local exit_code - output=$(opa eval \ - --data ./policies/_helpers \ - --data ./policies/gcp \ - --input "$input" \ - "$query" \ - --format raw 2>&1) - exit_code=$? - - # Check for errors - if [[ $exit_code -ne 0 ]]; then - echo "❌ ERROR: Policy evaluation failed" - echo "$output" - ((ERRORS++)) - return - fi - - # Parse and format the JSON output - if echo "$output" | jq -e . >/dev/null 2>&1; then - local header - local situations - - # Extract header (first element) - header=$(echo "$output" | jq -r '.[0] // empty') - - if [[ -z "$header" ]]; then - echo "❌ ERROR: Unexpected output format" - echo "$output" - ((ERRORS++)) - return - fi - - echo "$header" - - # Check if there are violations (array length > 1) - local violations_count - violations_count=$(echo "$output" | jq 'length - 1') - - if [[ $violations_count -eq 0 ]]; then - echo "Policy executed: All resources compliant" - ((SUCCESS++)) - else - echo "Policy executed: Found $violations_count violation(s)" - ((SUCCESS++)) - echo "" - - # Format each situation - echo "$output" | jq -r ' - .[] | - select(type == "array") | - to_entries | - map( - if .key == 0 then - " " + .value - else - " " + .value - end - ) | - join("\n") - ' - fi - else - # Handle non-JSON output (like "undefined") - if [[ "$output" == "undefined" ]]; then - echo "❌ ERROR: Query returned undefined (likely wrong query path)" - ((ERRORS++)) - else - echo "Output: $output" - ((SUCCESS++)) - fi - fi - - echo "" -} - -echo "Policy Debug Output" -echo "======================================" - -test_policy "Blacklist & Element Blacklist" \ - "./inputs/gcp/access_context_manager_vpc_service_controls/access_context_manager_service_perimeter/status/plan.json" \ - "data.terraform.gcp.security.access_context_manager_vpc_service_controls.access_context_manager_service_perimeter.status.message" - -test_policy "Whitelist" \ - "./inputs/gcp/api_hub/google_apihub_api_hub_instance/config_encryption_type/plan.json" \ - "data.terraform.gcp.security.api_hub.google_apihub_api_hub_instance.config_encryption_type.message" - -test_policy "Range" \ - "./inputs/gcp/cloud_storage/google_storage_bucket/retention_period/plan.json" \ - "data.terraform.gcp.security.cloud_storage.google_storage_bucket.retention_period.message" - -test_policy "Pattern Blacklist" \ - "./inputs/gcp/cloud_storage/google_storage_default_object_acl/public_access_prevention/plan.json" \ - "data.terraform.gcp.security.cloud_storage.google_storage_default_object_acl.public_access_prevention.message" - -test_policy "Pattern Whitelist" \ - "./inputs/gcp/cloud_platform_service/google_project/project_id/plan.json" \ - "data.terraform.gcp.security.cloud_platform_service.google_project.project_id.message" - -echo "" -echo "======================================" -echo "Summary" -echo "======================================" -echo "✅ Successful: $SUCCESS" -echo "❌ Errors: $ERRORS" -echo "======================================" - -exit $ERRORS diff --git a/tests/_helpers/smoke_test_helpers.sh b/tests/_helpers/smoke_test_helpers.sh deleted file mode 100644 index 0b4af5f5a..000000000 --- a/tests/_helpers/smoke_test_helpers.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/bash -# Smoke tests for helper refactoring -# Tests all 6 policy types with minimal output for quick verification - -# Navigate to repository root -cd "$(git rev-parse --show-toplevel)" || exit 1 - -echo "Helper Refactor Smoke Tests" -echo "================================" -echo "Testing against actual Terraform plans for:" -echo " • access_context_manager_service_perimeter.status" -echo " • google_apihub_api_hub_instance.config_encryption_type" -echo " • google_storage_bucket.retention_period" -echo " • google_storage_default_object_acl.public_access_prevention" -echo " • google_project.project_id" -echo "" - -FAILED=0 -PASSED=0 - -run_test() { - local name="$1" - local input="$2" - local query="$3" - local expected_violations="$4" - local expected_resource="$5" - - echo -n "Testing $name... " - - # Check if input file exists - if [[ ! -f "$input" ]]; then - echo "❌ FAIL (input file not found: $input)" - ((FAILED++)) - return - fi - - # Capture output and exit code - local output - local exit_code - output=$(opa eval \ - --data ./policies/_helpers \ - --data ./policies/gcp \ - --input "$input" \ - "$query" \ - --format raw 2>&1) - exit_code=$? - - # Check for OPA errors - if [[ $exit_code -ne 0 ]]; then - echo "❌ FAIL (policy error: $output)" - ((FAILED++)) - return - fi - - # Validate output is valid JSON - if ! echo "$output" | jq -e . >/dev/null 2>&1; then - echo "❌ FAIL (invalid JSON output)" - ((FAILED++)) - return - fi - - # Check expected violation count - local violation_count - violation_count=$(echo "$output" | jq 'length - 1') - - if [[ "$violation_count" != "$expected_violations" ]]; then - echo "❌ FAIL (expected $expected_violations violations, found $violation_count)" - ((FAILED++)) - return - fi - - # If expecting violations, check for expected resource in output - if [[ $expected_violations -gt 0 ]] && [[ -n "$expected_resource" ]]; then - if ! echo "$output" | grep -q "$expected_resource"; then - echo "❌ FAIL (expected resource '$expected_resource' not found in output)" - ((FAILED++)) - return - fi - fi - - echo "✅ PASS" - ((PASSED++)) -} - -# Test all 6 policy types -# Format: run_test "name" "input" "query" expected_violations expected_resource_in_output - -run_test "Blacklist & Element Blacklist" \ - "./inputs/gcp/access_context_manager_vpc_service_controls/access_context_manager_service_perimeter/status/plan.json" \ - "data.terraform.gcp.security.access_context_manager_vpc_service_controls.access_context_manager_service_perimeter.status.message" \ - 1 \ - "nc-null-restricted-services" - -run_test "Whitelist" \ - "./inputs/gcp/api_hub/google_apihub_api_hub_instance/config_encryption_type/plan.json" \ - "data.terraform.gcp.security.api_hub.google_apihub_api_hub_instance.config_encryption_type.message" \ - 0 \ - "" - -run_test "Range" \ - "./inputs/gcp/cloud_storage/google_storage_bucket/retention_period/plan.json" \ - "data.terraform.gcp.security.cloud_storage.google_storage_bucket.retention_period.message" \ - 1 \ - "nc123" - -run_test "Pattern Blacklist" \ - "./inputs/gcp/cloud_storage/google_storage_default_object_acl/public_access_prevention/plan.json" \ - "data.terraform.gcp.security.cloud_storage.google_storage_default_object_acl.public_access_prevention.message" \ - 1 \ - "nc123" - -run_test "Pattern Whitelist" \ - "./inputs/gcp/cloud_platform_service/google_project/project_id/plan.json" \ - "data.terraform.gcp.security.cloud_platform_service.google_project.project_id.message" \ - 1 \ - "nc123" - -echo "" -echo "================================" -echo "Results: $PASSED passed, $FAILED failed" - -exit $FAILED diff --git a/tests/_helpers/unit_test_helpers.sh b/tests/_helpers/unit_test_helpers.sh deleted file mode 100644 index 578e2ef65..000000000 --- a/tests/_helpers/unit_test_helpers.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/bash -# Unit tests for policy helpers -# Runs comprehensive test suites for all helper modules with fixtures - -# Navigate to repository root -cd "$(git rev-parse --show-toplevel)" || exit 1 - -echo "Policy Helper Unit Tests" -echo "============================" - -# Common fixtures needed by all tests -FIXTURES=( - "tests/_helpers/fixtures/gcp_storage_bucket/plan.json" - "tests/_helpers/fixtures/gcp_project/plan.json" - "tests/_helpers/fixtures/gcp_access_level/plan.json" -) - -# Common helper modules -HELPERS=( - "policies/_helpers/shared.rego" -) - -# Test utilities (assertion helpers used by all test files) -TEST_HELPERS=( - "tests/_helpers/shared_test.rego" -) - -FAILED=0 -PASSED=0 -TOTAL_TESTS_PASSED=0 -TOTAL_TESTS_FAILED=0 - -run_test_suite() { - local name="$1" - local test_file="$2" - local policy_file="$3" - local include_test_helpers="${4:-true}" # Default to true - - echo "" - echo "Testing $name..." - echo "============================" - - # Build test command with optional test helpers - if [ "$include_test_helpers" = "true" ]; then - output=$(opa test "$test_file" "$policy_file" "${HELPERS[@]}" "${TEST_HELPERS[@]}" "${FIXTURES[@]}" -v 2>&1) - else - output=$(opa test "$test_file" "$policy_file" "${HELPERS[@]}" "${FIXTURES[@]}" -v 2>&1) - fi - exit_code=$? - - echo "$output" - - if [ $exit_code -eq 0 ]; then - ((PASSED++)) - # Count PASS occurrences in individual test lines (format: "data.package.test_name: PASS") - pass_count=$(echo "$output" | grep -c ": PASS") - ((TOTAL_TESTS_PASSED += pass_count)) - else - ((FAILED++)) - # Count both PASS and FAIL occurrences in individual test lines - pass_count=$(echo "$output" | grep -c ": PASS") - fail_count=$(echo "$output" | grep -c ": FAIL") - ((TOTAL_TESTS_PASSED += pass_count)) - ((TOTAL_TESTS_FAILED += fail_count)) - fi -} - -# Run all helper test suites -run_test_suite "Shared Helpers" \ - "tests/_helpers/shared_test.rego" \ - "policies/_helpers/shared.rego" \ - "false" # Don't include shared_test.rego when testing itself - -run_test_suite "Blacklist Policy" \ - "tests/_helpers/blacklist_test.rego" \ - "policies/_helpers/policies/blacklist.rego" - -run_test_suite "Whitelist Policy" \ - "tests/_helpers/whitelist_test.rego" \ - "policies/_helpers/policies/whitelist.rego" - -run_test_suite "Range Policy" \ - "tests/_helpers/range_test.rego" \ - "policies/_helpers/policies/range.rego" - -run_test_suite "Pattern Blacklist Policy" \ - "tests/_helpers/pattern_blacklist_test.rego" \ - "policies/_helpers/policies/pattern_blacklist.rego" - -run_test_suite "Pattern Whitelist Policy" \ - "tests/_helpers/pattern_whitelist_test.rego" \ - "policies/_helpers/policies/pattern_whitelist.rego" - -run_test_suite "Element Blacklist Policy" \ - "tests/_helpers/element_blacklist_test.rego" \ - "policies/_helpers/policies/element_blacklist.rego" - -echo "" -echo "================================" -echo "Test Suites: $PASSED passed, $FAILED failed" -echo "Total Tests: $TOTAL_TESTS_PASSED passed, $TOTAL_TESTS_FAILED failed" - -exit $FAILED From 7d3754d7b8a85b5fea2cc07aa8db0d8cda5c30f3 Mon Sep 17 00:00:00 2001 From: Tikster123 Date: Sun, 28 Dec 2025 13:02:30 +1100 Subject: [PATCH 4/9] Remove templates/gcp/policy.rego - file not in main branch --- templates/gcp/policy.rego | 121 -------------------------------------- 1 file changed, 121 deletions(-) delete mode 100644 templates/gcp/policy.rego diff --git a/templates/gcp/policy.rego b/templates/gcp/policy.rego deleted file mode 100644 index 86198ff34..000000000 --- a/templates/gcp/policy.rego +++ /dev/null @@ -1,121 +0,0 @@ -package terraform.gcp.security... # Edit here -import data.terraform.gcp.helpers -import data.terraform.gcp.security...vars - -# STEP 1: STUDY YOUR RESOURCE AND ITS ATTRIBUTES, THEN FILL IN THE VARS FILE - -# STEP 2: CREATE SCENARIOS (can be simple (one condition) or complex (multiple linked conditions) ) -conditions := [ - [ - {"situation_description" : "A self documenting message about the conditions within", - "remedies":[ "Something that fixes the issues in this situation","You can have multiple items in the array"]}, - { - "condition": "A message about what the condition does", - "attribute_path" : [], # An array of strings and indicies eg. ["rsa",0,"key"] - "values" : [], # Values to compare against - "policy_type" : "" # Policy type eg. 'whitelist', 'blacklist', 'range', 'pattern whitelist', 'pattern blacklist' - } - ] -] - """ - Examples - Remove this in actual policies - - Whitelist like previous policies - [ - {"situation_description" : "Resource is not using Linux", - "remedies":[ "Change the OS to linux"]}, - { - "condition": "Test if an OS is not Linux", - "attribute_path" : ["parent"], - "values" : ["Linux"], - "policy_type" : "whitelist" - } - ] - - Blacklist - Disallow the use of specific values - - [ - {"situation_description" : "Resource is using Linux", - "remedies":[ "Change the OS from linux"]}, - { - "condition": "Test if an OS is Linux", - "attribute_path" : ["parent"], - "values" : ["Linux"], - "policy_type" : "blacklist" - } - ] - - Range - Use with numeric data to set a minimum, maximum or range - - Minimum - [ - {"situation_description" : "Check if key is over 1000 bits", - "remedies":[ "Enforce a key over 1000 bits"]}, - { - "condition": "Test if key size is over 1000 bits", - "attribute_path" : ["rsa",0,"key"], - "values" : [1000,null], - "policy_type" : "range" - } - ] - - Maximum - [ - {"situation_description" : "Check if key is under 1000 bits", - "remedies":[ "Enforce a key under 1000 bits"]}, - { - "condition": "Test if key size is under 1000 bits", - "attribute_path" : ["rsa",0,"key"], - "values" : [null,1000], - "policy_type" : "range" - } - ] - - Range - [ - {"situation_description" : "Check if key is between 1000 and 2000 bits", - "remedies":[ "Ensure key is 1000 to 2000 bits"]}, - { - "condition": "Test if key size is within 1000 to 2000 bits", - "attribute_path" : ["rsa",0,"key"], - "values" : [1000,2000], - "policy_type" : "range" - } - ] - - Patterns - - Whitelist - [ - {"situation_description" : "Check description fits a defined pattern", - "remedies":[ "Fix description to fit pattern"]}, - { - "condition": "Wrong description pattern", - "attribute_path" : ["description"], - "values" : ["project/*/gcp/*", [["a","c","d"],["b","d"]]], # Value to be compared - "policy_type" : "pattern whitelist" # First value must be one of a,c,d. Second value must be one of b,d. - } - ] - - Blacklist - [ - {"situation_description" : "Check description fits a defined pattern", - "remedies":[ "Fix description to fit pattern"]}, - { - "condition": "Wrong description pattern", - "attribute_path" : ["description"], - "values" : ["project/*", [["root"]], # Value to be compared - "policy_type" : "pattern blacklist" # Can be any value but root - } - ] - """ - -# Displays a general message about policy compliance -# Use 'opa eval ... "data.terraform.gcp.security....message" -message := helpers.get_multi_summary(conditions, vars.variables).message - -# Displays a detailed summary of each resources compliance to every condition and situation -# Useful for debugging -# Use 'opa eval ... "data.terraform.gcp.security....details" -details := helpers.get_multi_summary(conditions, vars.variables).details \ No newline at end of file From d562534e2b7e59e8c99cb03d9d4a6e002e5b2cd3 Mon Sep 17 00:00:00 2001 From: Tikster123 Date: Fri, 9 Jan 2026 12:10:32 +1100 Subject: [PATCH 5/9] Complete GKE Backup documentation --- .../backup_channel/description/plan.json | Bin 8478 -> 17920 bytes .../backup_plan/backup_config/plan.json | Bin 14690 -> 37570 bytes .../backup_plan/include_secrets/nc.tf | 12 ++++++++++++ .../backup_plan/permissive_mode/c.tf | 18 ++++++++++++++++++ .../backup_plan/permissive_mode/nc.tf | 18 ++++++++++++++++++ .../destination_project/config.tf | 14 ++++++++++++++ .../backup_for_gke/restore_plan/cluster/c.tf | 14 ++++++++++++++ .../restore_plan/cluster_resource_scope/c.tf | 17 +++++++++++++++++ .../restore_plan/conflict_plan/plan.json | Bin 16802 -> 0 bytes .../.terraform.lock.hcl | 0 .../{conflict_plan => conflict_policy}/c.tf | 0 .../config.tf | 0 .../{conflict_plan => conflict_policy}/nc.tf | 0 .../restore_plan/conflict_policy/plan.json | Bin 0 -> 41472 bytes .../restore_plan/excluded_namespaces/c.tf | 14 ++++++++++++++ .../restore_plan/excluded_namespaces/nc.tf | 12 ++++++++++++ .../restore_plan/field_actions/nc.tf | 14 ++++++++++++++ .../plan.json | Bin 16802 -> 16802 bytes .../cross_project_groups/c.tf | 12 ++++++++++++ .../cross_project_groups/plan.json | Bin 4834 -> 4834 bytes .../restore_plan_iam/domain_access/c.tf | 12 ++++++++++++ .../restore_plan_iam/domain_access/nc.tf | 11 +++++++++++ .../restore_plan_iam/member_count/c.tf | 12 ++++++++++++ .../restore_plan_iam/member_count/config.tf | 14 ++++++++++++++ .../restore_plan_iam/project_roles/nc.tf | 13 +++++++++++++ .../restore_plan_iam/public_access/nc.tf | 12 ++++++++++++ .../backup_channel/description/policy.rego | 1 - .../destination_project/policy.rego | 1 - .../backup_channel/labels/policy.rego | 1 - .../backup_channel/location/policy.rego | 1 - .../backup_channel/name/policy.rego | 1 - .../backup_plan/all_namespaces/policy.rego | 1 - .../backup_delete_lock_days/policy.rego | 1 - .../backup_plan/encryption_key/policy.rego | 1 - .../backup_plan/include_secrets/policy.rego | 1 - .../backup_plan/permissive_mode/policy.rego | 1 - .../policy.rego | 16 ++++++++++++++++ .../cross_project_groups/policy.rego | 16 ++++++++++++++++ 38 files changed, 251 insertions(+), 10 deletions(-) delete mode 100644 inputs/gcp/backup_for_gke/restore_plan/conflict_plan/plan.json rename inputs/gcp/backup_for_gke/restore_plan/{conflict_plan => conflict_policy}/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/restore_plan/{conflict_plan => conflict_policy}/c.tf (100%) rename inputs/gcp/backup_for_gke/restore_plan/{conflict_plan => conflict_policy}/config.tf (100%) rename inputs/gcp/backup_for_gke/restore_plan/{conflict_plan => conflict_policy}/nc.tf (100%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan/conflict_policy/plan.json create mode 100644 policies/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/policy.rego diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/plan.json b/inputs/gcp/backup_for_gke/backup_channel/description/plan.json index ed568edd2b217afa436e7a9d5a804f0d4b7b789a..9d889b3a09b65396cb7ee8d2f311a6a209bd1ba6 100644 GIT binary patch literal 17920 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 S3&;5~`s{h01Z2m*p45N4HqT`M literal 14690 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 diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/.terraform.lock.hcl similarity index 100% rename from inputs/gcp/backup_for_gke/restore_plan/conflict_plan/.terraform.lock.hcl rename to inputs/gcp/backup_for_gke/restore_plan/conflict_policy/.terraform.lock.hcl diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/c.tf b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/c.tf similarity index 100% rename from inputs/gcp/backup_for_gke/restore_plan/conflict_plan/c.tf rename to inputs/gcp/backup_for_gke/restore_plan/conflict_policy/c.tf diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/config.tf b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/config.tf similarity index 100% rename from inputs/gcp/backup_for_gke/restore_plan/conflict_plan/config.tf rename to inputs/gcp/backup_for_gke/restore_plan/conflict_policy/config.tf diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_plan/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/nc.tf similarity index 100% rename from inputs/gcp/backup_for_gke/restore_plan/conflict_plan/nc.tf rename to inputs/gcp/backup_for_gke/restore_plan/conflict_policy/nc.tf diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/plan.json b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/plan.json new file mode 100644 index 0000000000000000000000000000000000000000..8b9ed5cfad07957347078701df409d01ac6bba5b GIT binary patch literal 41472 zcmeHQZEqtr5cX#z{zJ8&=_}kF;v1k7Iw8Rc?hvA?qO@sy;o7uH(gHg5uLJX}Gxd7b z-q_yFrcJDx6PHB)1{J5h!D zhMp_bq1sbNRDL1eotIBf>0Pd+sfI)KCDn82sOO$)m{OZVb*iqY&e@`6yRW9tm+DO2 zQg3hRtsC_xy>Ujp*S&SWW8OtuSL%-5;n7_zt|wH-F4c6SM&-D6)mQ4J`dYnG2lUxh zALzQUAi%XgSa%<4aJr=yh6K+E)jKMo%zaokQjG7W#LRWsue%aHVI!SVYcqQ5j-Yf_ ze%J3ETfOBm$g&xZ^67%cH=>VjlSfsk%d-EMWv>Tx^^y89AS@55M<1zYz@mOpy$_>)>9y&x#XVs zOVjnBgh#bj!2ObbpAn@^X}o(>LJm|pd#{uU`@{u9dhP>Vfm5agn|%w*@nf7(O&_Q| zV9G5&4g^O@tjp_y*@D;7r#m4f;T*@^Z+A5Q}ccAxC= z+rOoc8=M0=g_gQ~#FifagdlQ7A6q*z%$Ah})qFu8t;5Ep1|F2SJf(YA)T(YJP9Dov zjU?V(;I7KspbTgl$OzW`T3TxT52>IvX4Q6(ZTPOGKJ+~&?-vdzw1u_gH>TiFo=c}7 zDamKV*TA~AI3}gsfJ}uAa!a@X=bw=*PH)kcO+3;V`IO$a)alR_7~`09h3-k16(VVZ zuiJ40*8-~roNF}Vj9?Gj#Mq$iD2`j=Qc6&^evFkipw>04GzGvax9LIiSwx>ibL)(mmxiuSck;Cq29CgbgWJir6l))OGwSX zsdi{1$Yxm8%wcsLcG+&d6|}8KUd5t>g>9F1O;rQKjyWNHddv2cR3*bgTW?a%H z^zi%U(C&}@}iVQkWw*n&{dP`UONpcYfRIqvX)d0E9-$?c}^DBw%Ivx z)Dre|s2+`*rL87PHlg`cte0og<78#STRUst3rR;sTee!+B3vJsu zN6M-gMD#hw%$QnZ$~araSMw&s%)V3Ks_)g0 z>b-hPUYZ;)lQGX6FJqr!T26=Low|1|`)jhlMpB7=o#SO)@!s?D-e^0kYx$GoWz~GQ z94~{c$?>vJD%8(s%Vxk%MqqNhOv0#sy}qn1iLGpZW&5j6pVd1#URH%h%=a8G)6fcw zG)c&&MlAt#xn{?0=fw3Z?CIvGPMk4k`yHu?S;JN{JFrfOeSs#w%@xmX_I0f$4!1lC z*EZ?~9QU^x&E$%*?>A(GPb-FoIEMRCjPPP1HDVycJeMOn)-|bpB%nMex25ub@J*mx@ zXMAOMYu);f+|~8Os@Ar#Pt;!Vk39_ZivF+_{BeFownNPN^sZ+5VS30FA zbIUM!8f(@ppXjZ_jZ*3ZS)5n^$I)8TW+tJzm{jNcCwYloGXYC}C zlvFNyOtYh9&Aw~a535{b=AO&?dgQxr&wYJQ`R<3#5q$6W@1ent9P3>>mezx=bE)I- z9*gI2A5h3lR8r6Lu%p|r0SmR=tMlgp<)uw%MjA{ z^mdYdTYX9r8`;uG(F}N}9sS8x`}eLGxf3GwWPg3v+0yVqrs@86SQ_EFJcJ^feJ}1` zeY(4um!WaH-wiorP4jclFbNxD&M`5v0d@&=G+X2$oNyAjyOC{?YCAFKnDoE@va~%l zCOF!`(eTY#O`da141fE-`E---jm^q2S^cVT$zRNMIokyLKbjl^j_Jl}20xW9_vo`n zAS~Ntm8-p_WZsteLp>8AXPRI|O{it%r~dwTJI zG%=KvGffOEG#8nb8adM>b>(Wa&(4N;{c2k+y&V5Zr8h}K?dVU|mg7HFh`7D?)hC+1 zx3}8+-eYDv;y)%sMEhP+b3#l#InxAuVEgrRriordYfj$EnI@o-eoxrS>v)h$cO0}v zyh)egw`^&+Ae1vrTu@ndZ#yiFr;uq?e662Dh7BAT)Jl% zz8EaDSw6YF37!mBF56}!yJBQ!pavARqXua8ac|tJwUvgX^b5uYUD-+iU@YiihSK6dOZgXXg^`o)L)xlCf!}dk<$*;6oUAnZ? z8nXM{fOvfEsGDn%Qr(r8#PfirEUIpLQ|%RIG0j>#{ABwS-s8S-nMw)#K9}prqT#l? z#S+(QY}k6P-)dSkEo<6rqLbrJWD~dOE7=BLWuA|0J58d=TI98R{wkjez3!&Ab|X#e zLtLA&(g9KcJC2^yIn+2A9p^w#ALmnAUmpZfZfMJKoVdP~Ns_WQeZC*ElBo_8Z5jEz zb$Q0W%yzIX%f45{>seCBw$@6{*k@V{j8p-qiIQXW`l6`G- zQ(Kzc=02tMA+F6>>Col8ze&2CEZMn%eeGki^iIjvGrs&VKLMi1ZXdlr$As}BOTCI8 zy9Ob9W4_27iQTQg2^!pDGex+6weL!NBYR*>J{-UgyWL$=%z`b&BXyvT)C)R={E$lg zKTz-J?J|6iy-=y^K^58ulzeXb~G&)Cs*y7QW~G(^k5qdq|fSnxfqPk++6 Nti0Q+y=T*d`X5{t(ewZS literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf index e69de29bb..da323126d 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf @@ -0,0 +1,14 @@ +resource "google_gke_backup_restore_plan" "c" { + name = "system-namespace-protected" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + all_namespaces = true + excluded_namespaces { + namespaces = ["kube-system", "kube-public", "kube-node-lease", "gke-system"] # SECURE: System namespaces excluded + } + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf index e69de29bb..071a1776e 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "no-namespace-exclusions" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + all_namespaces = true + # SECURITY RISK: No excluded namespaces - will restore system namespaces! + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf index e69de29bb..e4b9bcf5f 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf @@ -0,0 +1,14 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "insecure-no-transformation" + location = "australia-southeast1" + project = var.gcp_project + backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + + restore_config { + selected_namespaces { + namespaces = ["production"] + } + # SECURITY RISK: No transformation rules - keeping all sensitive fields! + } +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/plan.json b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/plan.json index 8f3c6471cda5ec06d03cbe9823e10e2cbf77dc65..0f0587d6f626a82b4ff5e0d7f3c2b5c2678dd01d 100644 GIT binary patch delta 35 mcmZ3~%($qTaf5=Rs1buDLkNQbkhEej1=3bPY&O}{F&6-p9|uqX delta 35 ncmZ3~%($qTaf5=Rr~!i|LkNQ*5Lz*qFqi>JBL?HirjEG)l&l9! diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/c.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/c.tf index e69de29bb..a20b6550d 100644 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/c.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_restore_plan_iam_binding" "c" { + name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" + location = "australia-southeast1" + project = var.gcp_project + + role = "roles/gkebackup.restoreViewer" + + members = [ + "group:sre-team@yourdomain.com", # SECURE: Company domain group + "group:dr-team@yourdomain.com" # SECURE: Company domain group + ] +} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/plan.json index 9541c5e9468a3c02707ae53d5b29276999a05778..f49caa03d8b77735c46669274ecb6007e667e7d8 100644 GIT binary patch delta 33 lcmaE)`bc#{f{>^YgC#=^IgC#= Date: Sun, 25 Jan 2026 23:36:58 +1100 Subject: [PATCH 6/9] Update Backup_for_GKE policies and documentation --- .gitignore | 1 + .../gke_backup_backup_channel.md | 18 ++ .../Backup_for_GKE/gke_backup_backup_plan.md | 124 +++++++++++++ .../gke_backup_backup_plan_iam.md | 18 ++ .../gke_backup_restore_channel.md | 18 ++ .../Backup_for_GKE/gke_backup_restore_plan.md | 167 ++++++++++++++++++ .../gke_backup_restore_plan_iam.md | 18 ++ .../gke_backup_backup_channel.json | 24 +-- .../resource_json/gke_backup_backup_plan.json | 56 +++--- .../gke_backup_backup_plan_iam.json | 18 +- .../gke_backup_restore_channel.json | 24 +-- .../gke_backup_restore_plan.json | 32 ++-- .../gke_backup_restore_plan_iam.json | 16 +- .../bandwidth/.terraform.lock.hcl | 21 +++ .../backup_channel/bandwidth/c.tf | 13 ++ .../bandwidth}/config.tf | 4 +- .../backup_channel/bandwidth/nc.tf | 11 ++ .../backup_channel/description/c.tf | 9 +- .../backup_channel/description/config.tf | 3 - .../backup_channel/description/nc.tf | 10 +- .../backup_channel/description/plan.json | Bin 17920 -> 3770 bytes .../backup_channel/destination_project/c.tf | 8 +- .../destination_project/config.tf | 3 - .../backup_channel/destination_project/nc.tf | 9 +- .../destination_project/plan.json | Bin 17394 -> 3585 bytes .../backup_for_gke/backup_channel/labels/c.tf | 12 +- .../backup_channel/labels/config.tf | 3 - .../backup_channel/labels/nc.tf | 10 +- .../backup_channel/labels/plan.json | Bin 20978 -> 4426 bytes .../backup_channel/location/c.tf | 9 +- .../backup_channel/location/config.tf | 3 - .../backup_channel/location/nc.tf | 11 +- .../backup_channel/location/plan.json | Bin 17334 -> 3534 bytes .../backup_for_gke/backup_channel/name/c.tf | 9 +- .../backup_channel/name/config.tf | 3 - .../backup_for_gke/backup_channel/name/nc.tf | 9 +- .../backup_channel/name/plan.json | Bin 17196 -> 3561 bytes .../all_namespaces/.terraform.lock.hcl | 26 +-- .../backup_plan/all_namespaces/c.tf | 16 +- .../backup_plan/all_namespaces/config.tf | 3 - .../backup_plan/all_namespaces/nc.tf | 15 +- .../backup_plan/all_namespaces/plan.json | Bin 13814 -> 6435 bytes .../backup_config/.terraform.lock.hcl | 26 +-- .../backup_plan/backup_config/c.tf | 24 +-- .../backup_plan/backup_config/config.tf | 3 - .../backup_plan/backup_config/nc.tf | 17 +- .../backup_plan/backup_config/plan.json | Bin 37570 -> 6758 bytes .../.terraform.lock.hcl | 26 +-- .../backup_plan/backup_delete_lock_days/c.tf | 19 +- .../backup_delete_lock_days/config.tf | 3 - .../backup_plan/backup_delete_lock_days/nc.tf | 22 ++- .../backup_delete_lock_days/plan.json | Bin 14182 -> 6845 bytes .../backup_schedule/.terraform.lock.hcl | 26 +-- .../backup_plan/backup_schedule/c.tf | 15 +- .../backup_plan/backup_schedule/config.tf | 3 - .../backup_plan/backup_schedule/nc.tf | 15 +- .../backup_plan/backup_schedule/plan.json | Bin 11018 -> 5034 bytes .../deactivated/.terraform.lock.hcl | 26 +-- .../backup_plan/deactivated/c.tf | 11 +- .../backup_plan/deactivated/config.tf | 3 - .../backup_plan/deactivated/nc.tf | 11 +- .../backup_plan/deactivated/plan.json | Bin 10120 -> 4606 bytes .../description/.terraform.lock.hcl | 26 +-- .../backup_plan/description/c.tf | 9 +- .../backup_plan/description/config.tf | 3 - .../backup_plan/description/nc.tf | 10 +- .../backup_plan/description/plan.json | Bin 10790 -> 4902 bytes .../encryption_key/.terraform.lock.hcl | 26 +-- .../backup_plan/encryption_key/c.tf | 25 +-- .../backup_plan/encryption_key/config.tf | 5 +- .../backup_plan/encryption_key/nc.tf | 24 ++- .../backup_plan/encryption_key/plan.json | Bin 14654 -> 7397 bytes .../include_secrets/.terraform.lock.hcl | 26 +-- .../backup_plan/include_secrets/c.tf | 13 +- .../backup_plan/include_secrets/config.tf | 3 - .../backup_plan/include_secrets/nc.tf | 13 +- .../backup_plan/include_secrets/plan.json | Bin 7546 -> 6402 bytes .../backup_plan/labels/.terraform.lock.hcl | 26 +-- .../backup_for_gke/backup_plan/labels/c.tf | 20 ++- .../backup_plan/labels/config.tf | 3 - .../backup_for_gke/backup_plan/labels/nc.tf | 14 +- .../backup_plan/labels/plan.json | Bin 11928 -> 5834 bytes .../backup_plan/labels/test_input.json | 28 +++ .../backup_plan/location/.terraform.lock.hcl | 21 +++ .../backup_for_gke/backup_plan/location/c.tf | 18 ++ .../location}/config.tf | 5 +- .../backup_for_gke/backup_plan/location/nc.tf | 18 ++ .../backup_plan/name/.terraform.lock.hcl | 26 +-- .../gcp/backup_for_gke/backup_plan/name/c.tf | 9 +- .../backup_for_gke/backup_plan/name/config.tf | 3 - .../gcp/backup_for_gke/backup_plan/name/nc.tf | 9 +- .../backup_for_gke/backup_plan/name/plan.json | Bin 9796 -> 4546 bytes .../permissive_mode/.terraform.lock.hcl | 26 +-- .../backup_plan/permissive_mode/c.tf | 15 +- .../backup_plan/permissive_mode/config.tf | 3 - .../backup_plan/permissive_mode/nc.tf | 15 +- .../backup_plan/permissive_mode/plan.json | Bin 878 -> 6840 bytes .../retention_policy/.terraform.lock.hcl | 26 +-- .../backup_plan/retention_policy/c.tf | 15 +- .../backup_plan/retention_policy/config.tf | 3 - .../backup_plan/retention_policy/nc.tf | 15 +- .../backup_plan/retention_policy/plan.json | Bin 11138 -> 5064 bytes .../backup_plan_iam/custom_roles/c.tf | 11 -- .../backup_plan_iam/custom_roles/plan.json | Bin 8420 -> 0 bytes .../backup_plan_iam/domain_access/nc.tf | 11 -- .../backup_plan_iam/domain_access/plan.json | Bin 8180 -> 0 bytes .../external_service_accounts/plan.json | Bin 9422 -> 0 bytes .../federated_identities/plan.json | Bin 424 -> 0 bytes .../backup_plan_iam/members/plan.json | Bin 7874 -> 0 bytes .../backup_plan_iam/project_roles/config.tf | 14 -- .../backup_plan_iam/project_roles/plan.json | Bin 8816 -> 0 bytes .../backup_for_gke/backup_plan_iam/role/c.tf | 12 -- .../backup_plan_iam/role/config.tf | 14 -- .../backup_for_gke/backup_plan_iam/role/nc.tf | 11 -- .../backup_plan_iam/role/plan.json | Bin 8186 -> 0 bytes .../custom_roles/.terraform.lock.hcl | 0 .../backup_plan_iam_binding/custom_roles/c.tf | 11 ++ .../custom_roles}/config.tf | 3 - .../custom_roles/nc.tf | 6 +- .../domain_access/.terraform.lock.hcl | 0 .../domain_access/c.tf | 6 +- .../domain_access}/config.tf | 3 - .../domain_access/nc.tf | 11 ++ .../.terraform.lock.hcl | 0 .../external_service_accounts/c.tf | 6 +- .../external_service_accounts/config.tf | 11 ++ .../external_service_accounts/nc.tf | 6 +- .../federated_identities/c.tf | 0 .../federated_identities/config.tf | 0 .../federated_identities/nc.tf | 0 .../members/.terraform.lock.hcl | 0 .../members/c.tf | 6 +- .../backup_plan_iam_binding/members/config.tf | 11 ++ .../members/fake-creds_test.json | 1 + .../members/nc.tf | 6 +- .../backup_plan_iam_binding/members/plan_test | Bin 0 -> 2756 bytes .../project_roles/.terraform.lock.hcl | 0 .../project_roles/c.tf | 6 +- .../project_roles/config.tf | 11 ++ .../project_roles/nc.tf | 6 +- .../role/.terraform.lock.hcl | 0 .../backup_plan_iam_binding/role/c.tf | 12 ++ .../backup_plan_iam_binding/role/config.tf | 11 ++ .../backup_plan_iam_binding/role/nc.tf | 11 ++ .../backup_plan_iam_binding/role/tfplan | Bin 0 -> 3000 bytes .../restore_channel/description/c.tf | 11 +- .../restore_channel/description/config.tf | 3 - .../restore_channel/description/nc.tf | 10 +- .../restore_channel/description/plan.json | Bin 8928 -> 4028 bytes .../restore_channel/destination_project/c.tf | 9 +- .../destination_project/config.tf | 3 - .../restore_channel/destination_project/nc.tf | 9 +- .../destination_project/plan.json | 1 + .../restore_channel/labels/c.tf | 21 ++- .../restore_channel/labels/config.tf | 3 - .../restore_channel/labels/nc.tf | 10 +- .../restore_channel/labels/plan.json | Bin 10246 -> 4970 bytes .../restore_channel/location/c.tf | 11 +- .../restore_channel/location/config.tf | 3 - .../restore_channel/location/nc.tf | 11 +- .../restore_channel/location/plan.json | Bin 8078 -> 3546 bytes .../backup_for_gke/restore_channel/name/c.tf | 9 +- .../restore_channel/name/config.tf | 3 - .../backup_for_gke/restore_channel/name/nc.tf | 9 +- .../restore_channel/name/plan.json | Bin 8424 -> 3830 bytes .../restore_plan/all_namespaces/c.tf | 13 +- .../restore_plan/all_namespaces/config.tf | 3 - .../restore_plan/all_namespaces/nc.tf | 14 +- .../restore_plan/all_namespaces/plan.json | Bin 17512 -> 7675 bytes .../backup_for_gke/restore_plan/cluster/c.tf | 13 +- .../restore_plan/cluster/config.tf | 3 - .../backup_for_gke/restore_plan/cluster/nc.tf | 13 +- .../restore_plan/cluster/plan.json | Bin 8286 -> 7007 bytes .../restore_plan/cluster_resource_scope/c.tf | 13 +- .../cluster_resource_scope/config.tf | 3 - .../restore_plan/cluster_resource_scope/nc.tf | 13 +- .../cluster_resource_scope/plan.json | Bin 9526 -> 7979 bytes .../restore_plan/conflict_policy/c.tf | 14 +- .../restore_plan/conflict_policy/config.tf | 3 - .../restore_plan/conflict_policy/nc.tf | 14 +- .../restore_plan/conflict_policy/plan.json | Bin 41472 -> 7332 bytes .../description/.terraform.lock.hcl | 21 +++ .../restore_plan/description/c.tf | 13 ++ .../restore_plan/description/nc.tf | 13 ++ .../restore_plan/excluded_namespaces/c.tf | 15 +- .../excluded_namespaces/config.tf | 3 - .../restore_plan/excluded_namespaces/nc.tf | 16 +- .../excluded_namespaces/plan.json | Bin 878 -> 7133 bytes .../restore_plan/field_actions/c.tf | 17 +- .../restore_plan/field_actions/config.tf | 3 - .../restore_plan/field_actions/nc.tf | 12 +- .../restore_plan/field_actions/plan.json | Bin 12746 -> 9141 bytes .../namespaced_resource_restore_mode/c.tf | 12 +- .../config.tf | 3 - .../namespaced_resource_restore_mode/nc.tf | 14 +- .../plan.json | Bin 16802 -> 7332 bytes .../restore_plan/transformation_rules/c.tf | 12 +- .../transformation_rules/config.tf | 3 - .../restore_plan/transformation_rules/nc.tf | 13 +- .../transformation_rules/plan.json | Bin 19132 -> 8470 bytes .../restore_plan/volume_bindings/c.tf | 13 +- .../restore_plan/volume_bindings/config.tf | 3 - .../restore_plan/volume_bindings/nc.tf | 13 +- .../restore_plan/volume_bindings/plan.json | Bin 17614 -> 7747 bytes .../restore_plan/volume_data_restore/c.tf | 12 +- .../volume_data_restore/config.tf | 3 - .../restore_plan/volume_data_restore/nc.tf | 14 +- .../volume_data_restore/plan.json | Bin 16922 -> 7392 bytes .../cross_project_groups/config.tf | 14 -- .../cross_project_groups/nc.tf | 12 -- .../cross_project_groups/plan.json | Bin 4834 -> 0 bytes .../restore_plan_iam/domain_access/config.tf | 14 -- .../restore_plan_iam/domain_access/nc.tf | 11 -- .../restore_plan_iam/domain_access/plan.json | Bin 878 -> 0 bytes .../restore_plan_iam/member_count/config.tf | 14 -- .../restore_plan_iam/member_count/plan.json | Bin 424 -> 0 bytes .../personal_emails/config.tf | 14 -- .../personal_emails/plan.json | Bin 8648 -> 0 bytes .../restore_plan_iam/project_roles/config.tf | 14 -- .../restore_plan_iam/project_roles/plan.json | Bin 4792 -> 0 bytes .../restore_plan_iam/public_access/config.tf | 14 -- .../restore_plan_iam/public_access/plan.json | Bin 5050 -> 0 bytes .../restore_plan_iam/restore_permissions/c.tf | 11 -- .../restore_permissions/config.tf | 14 -- .../restore_permissions/plan.json | Bin 8276 -> 0 bytes .../backup_for_gke/restore_plan_iam/role/c.tf | 12 -- .../restore_plan_iam/role/config.tf | 14 -- .../restore_plan_iam/role/nc.tf | 11 -- .../restore_plan_iam/role/plan.json | Bin 8486 -> 0 bytes .../service_accounts/config.tf | 14 -- .../service_accounts/plan.json | Bin 9530 -> 0 bytes .../cross_project_groups/.terraform.lock.hcl | 0 .../cross_project_groups/c.tf | 6 +- .../cross_project_groups/config.tf | 11 ++ .../cross_project_groups/nc.tf | 12 ++ .../domain_access/.terraform.lock.hcl | 0 .../domain_access/c.tf | 6 +- .../domain_access/config.tf | 11 ++ .../domain_access/nc.tf | 11 ++ .../member_count/.terraform.lock.hcl | 21 +++ .../member_count/c.tf | 6 +- .../member_count/config.tf | 11 ++ .../member_count/nc.tf | 6 +- .../personal_emails/.terraform.lock.hcl | 0 .../personal_emails/c.tf | 6 +- .../personal_emails/config.tf | 11 ++ .../personal_emails/nc.tf | 6 +- .../project_roles/.terraform.lock.hcl | 0 .../project_roles/c.tf | 6 +- .../project_roles/config.tf | 11 ++ .../project_roles/nc.tf | 6 +- .../public_access/.terraform.lock.hcl | 0 .../public_access/c.tf | 6 +- .../public_access/config.tf | 11 ++ .../public_access/nc.tf | 6 +- .../restore_permissions/.terraform.lock.hcl | 0 .../restore_permissions/c.tf | 11 ++ .../restore_permissions/config.tf | 11 ++ .../restore_permissions/nc.tf | 6 +- .../role/.terraform.lock.hcl | 0 .../restore_plan_iam_binding/role/c.tf | 12 ++ .../restore_plan_iam_binding/role/config.tf | 11 ++ .../restore_plan_iam_binding/role/nc.tf | 11 ++ .../service_accounts/.terraform.lock.hcl | 0 .../service_accounts/c.tf | 8 +- .../service_accounts/config.tf | 11 ++ .../service_accounts/nc.tf | 6 +- .../backup_channel/bandwidth/policy.rego | 21 +++ .../backup_channel/bandwidth/vars.rego | 8 + .../backup_channel/description/policy.rego | 47 +++-- .../destination_project/policy.rego | 71 ++++++-- .../backup_channel/labels/policy.rego | 47 +++-- .../backup_channel/location/policy.rego | 41 +++-- .../backup_channel/name/policy.rego | 29 +-- .../backup_for_gke/backup_channel/vars.rego | 2 +- .../backup_plan/all_namespaces/policy.rego | 29 +-- .../backup_plan/backup_config/policy.rego | 42 +++-- .../backup_delete_lock_days/policy.rego | 29 +-- .../backup_plan/backup_schedule/policy.rego | 42 +++-- .../backup_plan/deactivated/policy.rego | 30 ++-- .../backup_plan/description/policy.rego | 30 ++-- .../backup_plan/encryption_key/policy.rego | 87 +++++++-- .../backup_plan/include_secrets/policy.rego | 29 +-- .../backup_plan/labels/policy.rego | 79 +++++++-- .../backup_plan/location/policy.rego | 26 +++ .../backup_plan/name/policy.rego | 17 -- .../backup_plan/permissive_mode/policy.rego | 29 +-- .../backup_plan/retention_policy/policy.rego | 30 ++-- .../gcp/backup_for_gke/backup_plan/vars.rego | 2 +- .../backup_plan_iam/custom_roles/policy.rego | 17 -- .../backup_plan_iam/domain_access/policy.rego | 17 -- .../external_service_accounts/policy.rego | 17 -- .../federated_identities/policy.rego | 17 -- .../backup_plan_iam/members/policy.rego | 17 -- .../backup_plan_iam/project_roles/policy.rego | 17 -- .../backup_plan_iam/role/policy.rego | 17 -- .../custom_roles/policy.rego | 21 +++ .../domain_access/policy.rego | 70 ++++++++ .../external_service_accounts/policy.rego | 69 ++++++++ .../federated_identities/policy.rego | 21 +++ .../members/policy.rego | 33 ++++ .../project_roles/policy.rego | 21 +++ .../backup_plan_iam_binding/role/policy.rego | 28 +++ .../vars.rego | 4 +- .../restore_channel/description/policy.rego | 48 +++-- .../destination_project/policy.rego | 30 ++-- .../restore_channel/labels/policy.rego | 48 +++-- .../restore_channel/location/policy.rego | 42 +++-- .../restore_channel/name/policy.rego | 17 -- .../backup_for_gke/restore_channel/vars.rego | 2 +- .../restore_plan/all_namespaces/policy.rego | 30 ++-- .../restore_plan/cluster/policy.rego | 74 ++++++-- .../cluster_resource_scope/policy.rego | 30 ++-- .../restore_plan/conflict_policy/policy.rego | 30 ++-- .../restore_plan/description/policy.rego | 21 +++ .../restore_plan/descripttion/policy.rego | 17 -- .../excluded_namespaces/debug.rego | 11 ++ .../excluded_namespaces/policy.rego | 55 ++++-- .../restore_plan/field_actions/policy.rego | 30 ++-- .../policy.rego | 29 +-- .../transformation_rules/policy.rego | 42 +++-- .../gcp/backup_for_gke/restore_plan/vars.rego | 2 +- .../restore_plan/volume_bindings/policy.rego | 17 -- .../volume_data_restore/policy.rego | 30 ++-- .../cross_project_groups/policy.rego | 16 -- .../domain_access/policy.rego | 17 -- .../restore_plan_iam/member_count/policy.rego | 17 -- .../personal_emails/policy.rego | 17 -- .../project_roles/policy.rego | 17 -- .../public_access/policy.rego | 17 -- .../restore_permissions/policy.rego | 17 -- .../restore_plan_iam/role/policy.rego | 17 -- .../service_accounts/policy.rego | 17 -- .../cross_project_groups/policy.rego | 59 +++++++ .../domain_access/policy.rego | 37 ++++ .../personal_emails/policy.rego | 58 ++++++ .../project_roles/policy.rego | 21 +++ .../public_access/policy.rego | 35 ++++ .../restore_permissions/policy.rego | 21 +++ .../restore_plan_iam_binding/role/policy.rego | 21 +++ .../service_accounts/policy.rego | 62 +++++++ .../vars.rego | 4 +- scripts/auto_test/auto_test.py | 38 ++-- 343 files changed, 3108 insertions(+), 1793 deletions(-) create mode 100644 docs/gcp/Backup_for_GKE/gke_backup_backup_channel.md create mode 100644 docs/gcp/Backup_for_GKE/gke_backup_backup_plan.md create mode 100644 docs/gcp/Backup_for_GKE/gke_backup_backup_plan_iam.md create mode 100644 docs/gcp/Backup_for_GKE/gke_backup_restore_channel.md create mode 100644 docs/gcp/Backup_for_GKE/gke_backup_restore_plan.md create mode 100644 docs/gcp/Backup_for_GKE/gke_backup_restore_plan_iam.md create mode 100644 inputs/gcp/backup_for_gke/backup_channel/bandwidth/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_channel/bandwidth/c.tf rename inputs/gcp/backup_for_gke/{backup_plan_iam/domain_access => backup_channel/bandwidth}/config.tf (69%) create mode 100644 inputs/gcp/backup_for_gke/backup_channel/bandwidth/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan/labels/test_input.json create mode 100644 inputs/gcp/backup_for_gke/backup_plan/location/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/backup_plan/location/c.tf rename inputs/gcp/backup_for_gke/{backup_plan_iam/custom_roles => backup_plan/location}/config.tf (69%) create mode 100644 inputs/gcp/backup_for_gke/backup_plan/location/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/c.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/plan.json delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/plan.json delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/plan.json delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/plan.json delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/members/plan.json delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/config.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/plan.json delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/role/c.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/role/config.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/role/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam/role/plan.json rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/custom_roles/.terraform.lock.hcl (100%) create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/c.tf rename inputs/gcp/backup_for_gke/{backup_plan_iam/external_service_accounts => backup_plan_iam_binding/custom_roles}/config.tf (69%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/custom_roles/nc.tf (63%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/domain_access/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/domain_access/c.tf (67%) rename inputs/gcp/backup_for_gke/{backup_plan_iam/members => backup_plan_iam_binding/domain_access}/config.tf (69%) create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/nc.tf rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/external_service_accounts/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/external_service_accounts/c.tf (73%) create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/config.tf rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/external_service_accounts/nc.tf (73%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/federated_identities/c.tf (100%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/federated_identities/config.tf (100%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/federated_identities/nc.tf (100%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/members/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/members/c.tf (62%) create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/fake-creds_test.json rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/members/nc.tf (59%) create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/plan_test rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/project_roles/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/project_roles/c.tf (67%) create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/config.tf rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/project_roles/nc.tf (70%) rename inputs/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/role/.terraform.lock.hcl (100%) create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/c.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/config.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/nc.tf create mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/tfplan create mode 100644 inputs/gcp/backup_for_gke/restore_plan/description/.terraform.lock.hcl create mode 100644 inputs/gcp/backup_for_gke/restore_plan/description/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan/description/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/plan.json delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/plan.json delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/member_count/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/member_count/plan.json delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/plan.json delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/project_roles/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/project_roles/plan.json delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/public_access/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/public_access/plan.json delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/c.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/plan.json delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/role/c.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/role/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/role/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/role/plan.json delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/service_accounts/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam/service_accounts/plan.json rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/cross_project_groups/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/cross_project_groups/c.tf (68%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/nc.tf rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/domain_access/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/domain_access/c.tf (67%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/nc.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/member_count/.terraform.lock.hcl rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/member_count/c.tf (70%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/member_count/config.tf rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/member_count/nc.tf (64%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/personal_emails/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/personal_emails/c.tf (67%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/personal_emails/config.tf rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/personal_emails/nc.tf (72%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/project_roles/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/project_roles/c.tf (63%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/project_roles/config.tf rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/project_roles/nc.tf (74%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/public_access/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/public_access/c.tf (67%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/public_access/config.tf rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/public_access/nc.tf (68%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/restore_permissions/.terraform.lock.hcl (100%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/restore_permissions/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/restore_permissions/config.tf rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/restore_permissions/nc.tf (63%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/role/.terraform.lock.hcl (100%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/role/c.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/role/config.tf create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/role/nc.tf rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/service_accounts/.terraform.lock.hcl (100%) rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/service_accounts/c.tf (52%) create mode 100644 inputs/gcp/backup_for_gke/restore_plan_iam_binding/service_accounts/config.tf rename inputs/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/service_accounts/nc.tf (72%) create mode 100644 policies/gcp/backup_for_gke/backup_channel/bandwidth/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_channel/bandwidth/vars.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/location/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan/name/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/custom_roles/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/domain_access/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/federated_identities/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/members/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/project_roles/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan_iam/role/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam_binding/members/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/policy.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan_iam_binding/role/policy.rego rename policies/gcp/backup_for_gke/{backup_plan_iam => backup_plan_iam_binding}/vars.rego (70%) delete mode 100644 policies/gcp/backup_for_gke/restore_channel/name/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/description/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan/descripttion/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/debug.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/domain_access/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/member_count/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/personal_emails/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/project_roles/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/public_access/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/restore_permissions/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/role/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan_iam/service_accounts/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam_binding/personal_emails/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam_binding/project_roles/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam_binding/public_access/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam_binding/restore_permissions/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam_binding/role/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam_binding/service_accounts/policy.rego rename policies/gcp/backup_for_gke/{restore_plan_iam => restore_plan_iam_binding}/vars.rego (70%) diff --git a/.gitignore b/.gitignore index f3287088e..17fe2a7aa 100644 --- a/.gitignore +++ b/.gitignore @@ -99,6 +99,7 @@ dmypy.json *.tfstate *.tfstate.* *.tfstate.backup +.tfshared/ # Lock files (uncomment if you don't want to track lock files) # .terraform.lock.hcl diff --git a/docs/gcp/Backup_for_GKE/gke_backup_backup_channel.md b/docs/gcp/Backup_for_GKE/gke_backup_backup_channel.md new file mode 100644 index 000000000..9883086df --- /dev/null +++ b/docs/gcp/Backup_for_GKE/gke_backup_backup_channel.md @@ -0,0 +1,18 @@ +## 🛡️ Policy Deployment Engine: `gke_backup_backup_channel` + +This section provides a concise policy evaluation for the `gke_backup_backup_channel` resource in GCP. + +Reference: [Terraform Registry – gke_backup_backup_channel](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_backup_backup_channel) + +--- + +## Argument Reference + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `name` | The full name of the BackupChannel Resource. | true | false | None | None | None | +| `destination_project` | The project where Backups are allowed to be stored. The format is `projects/{project}`. {project} can be project number or project id. | true | true | Backups must be stored in a dedicated backup project to ensure isolation. | projects/backup-prod | projects/my-app-dev | +| `location` | The region of the Backup Channel. | true | true | Data sovereignty requires backups to be stored in specific Australian regions. | australia-southeast1 | us-central1 | +| `description` | User specified descriptive string for this BackupChannel. | false | false | None | None | None | +| `labels` | Description: A set of custom labels supplied by the user. A list of key->value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. Please refer to the field `effective_labels` for all of the labels present on the resource. | false | false | Labels are required for cost allocation and ownership tracking. | environment='prod', cost-center='123', owner='team' | missing required labels | +| `project` | If it is not provided, the provider project is used. | false | false | None | None | None | diff --git a/docs/gcp/Backup_for_GKE/gke_backup_backup_plan.md b/docs/gcp/Backup_for_GKE/gke_backup_backup_plan.md new file mode 100644 index 000000000..942994e8b --- /dev/null +++ b/docs/gcp/Backup_for_GKE/gke_backup_backup_plan.md @@ -0,0 +1,124 @@ +## 🛡️ Policy Deployment Engine: `gke_backup_backup_plan` + +This section provides a concise policy evaluation for the `gke_backup_backup_plan` resource in GCP. + +Reference: [Terraform Registry – gke_backup_backup_plan](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_backup_backup_plan) + +--- + +## Argument Reference + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `name` | The full name of the BackupPlan Resource. | true | false | None | None | None | +| `cluster` | The source cluster from which Backups will be created via this BackupPlan. | true | false | None | None | None | +| `location` | The region of the Backup Plan. | true | true | Data sovereignty requires backups to be stored in specific Australian regions. | australia-southeast1 | us-central1 | +| `description` | User specified descriptive string for this BackupPlan. | false | false | None | None | None | +| `retention_policy` | RetentionPolicy governs lifecycle of Backups created under this plan. Structure is [documented below](#nested_retention_policy). | false | false | None | None | None | +| `labels` | Description: A set of custom labels supplied by the user. A list of key->value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. Please refer to the field `effective_labels` for all of the labels present on the resource. | false | false | Labels are required for cost allocation and ownership tracking. | environment='prod', cost-center='123', owner='team' | missing required labels | +| `backup_schedule` | Defines a schedule for automatic Backup creation via this BackupPlan. Structure is [documented below](#nested_backup_schedule). | false | false | None | None | None | +| `deactivated` | This flag indicates whether this BackupPlan has been deactivated. Setting this field to True locks the BackupPlan such that no further updates will be allowed (except deletes), including the deactivated field itself. It also prevents any new Backups from being created via this BackupPlan (including scheduled Backups). | false | true | Deactivated plans do not create backups, putting data at risk. | false | true | +| `backup_config` | Defines the configuration of Backups created via this BackupPlan. Structure is [documented below](#nested_backup_config). | false | true | Backup configuration must explicitly define secret handling and encryption. | See sub-arguments | See sub-arguments | +| `project` | If it is not provided, the provider project is used. | false | false | None | None | None | +| `rpo_config` | | false | false | None | None | None | +| `exclusion_windows` | | false | false | None | None | None | +| `start_time` | | false | false | None | None | None | +| `single_occurrence_date` | | false | false | None | None | None | +| `days_of_week` | | false | false | None | None | None | +| `encryption_key` | | false | false | None | None | None | +| `selected_namespaces` | | false | false | None | None | None | +| `selected_applications` | | false | false | None | None | None | +| `namespaced_names` | | false | false | None | None | None | + +### retention_policy Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `backup_delete_lock_days` | Minimum age for a Backup created via this BackupPlan (in days). Must be an integer value between 0-90 (inclusive). A Backup created under this BackupPlan will not be deletable until it reaches Backup's (create time + backup_delete_lock_days). Updating this field of a BackupPlan does not affect existing Backups. Backups created after a successful update will inherit this new value. | false | false | None | None | None | +| `backup_retain_days` | The default maximum age of a Backup created via this BackupPlan. This field MUST be an integer value >= 0 and <= 365. If specified, a Backup created under this BackupPlan will be automatically deleted after its age reaches (createTime + backupRetainDays). If not specified, Backups created under this BackupPlan will NOT be subject to automatic deletion. Updating this field does NOT affect existing Backups under it. Backups created AFTER a successful update will automatically pick up the new value. NOTE: backupRetainDays must be >= backupDeleteLockDays. If cronSchedule is defined, then this must be <= 360 * the creation interval. If rpo_config is defined, then this must be <= 360 * targetRpoMinutes/(1440minutes/day) | false | true | Retention period must be sufficient for disaster recovery but not exceed data retention policies (7-90 days). | 30 | 1 | +| `locked` | This flag denotes whether the retention policy of this BackupPlan is locked. If set to True, no further update is allowed on this policy, including the locked field itself. | false | false | None | None | None | + +### backup_schedule Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `cron_schedule` | A standard cron string that defines a repeating schedule for creating Backups via this BackupPlan. This is mutually exclusive with the rpoConfig field since at most one schedule can be defined for a BackupPlan. If this is defined, then backupRetainDays must also be defined. | false | true | Backups should run during off-peak hours to minimize impact. | 0 2 * * * | * * * * * | +| `paused` | This flag denotes whether automatic Backup creation is paused for this BackupPlan. | false | false | None | None | None | +| `rpo_config` | Defines the RPO schedule configuration for this BackupPlan. This is mutually exclusive with the cronSchedule field since at most one schedule can be defined for a BackupPLan. If this is defined, then backupRetainDays must also be defined. Structure is [documented below](#nested_backup_schedule_rpo_config). | false | false | None | None | None | + +### backup_config Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `include_volume_data` | This flag specifies whether volume data should be backed up when PVCs are included in the scope of a Backup. | false | false | None | None | None | +| `include_secrets` | This flag specifies whether Kubernetes Secret resources should be included when they fall into the scope of Backups. | false | false | None | None | None | +| `encryption_key` | This defines a customer managed encryption key that will be used to encrypt the "config" portion (the Kubernetes resources) of Backups created via this plan. Structure is [documented below](#nested_backup_config_encryption_key). | false | false | None | None | None | +| `all_namespaces` | If True, include all namespaced resources. | false | false | None | None | None | +| `selected_namespaces` | If set, include just the resources in the listed namespaces. Structure is [documented below](#nested_backup_config_selected_namespaces). | false | false | None | None | None | +| `selected_applications` | A list of namespaced Kubernetes Resources. Structure is [documented below](#nested_backup_config_selected_applications). | false | false | None | None | None | +| `permissive_mode` | This flag specifies whether Backups will not fail when Backup for GKE detects Kubernetes configuration that is non-standard or requires additional setup to restore. | false | false | None | None | None | + +### rpo_config Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `target_rpo_minutes` | Defines the target RPO for the BackupPlan in minutes, which means the target maximum data loss in time that is acceptable for this BackupPlan. This must be at least 60, i.e., 1 hour, and at most 86400, i.e., 60 days. | true | false | None | None | None | +| `exclusion_windows` | User specified time windows during which backup can NOT happen for this BackupPlan. Backups should start and finish outside of any given exclusion window. Note: backup jobs will be scheduled to start and finish outside the duration of the window as much as possible, but running jobs will not get canceled when it runs into the window. All the time and date values in exclusionWindows entry in the API are in UTC. We only allow <=1 recurrence (daily or weekly) exclusion window for a BackupPlan while no restriction on number of single occurrence windows. Structure is [documented below](#nested_backup_schedule_rpo_config_exclusion_windows). | false | false | None | None | None | + +### exclusion_windows Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `start_time` | Specifies the start time of the window using time of the day in UTC. Structure is [documented below](#nested_backup_schedule_rpo_config_exclusion_windows_exclusion_windows_start_time). | true | false | None | None | None | +| `duration` | Specifies duration of the window in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s". Restrictions for duration based on the recurrence type to allow some time for backup to happen: - single_occurrence_date: no restriction - daily window: duration < 24 hours - weekly window: - days of week includes all seven days of a week: duration < 24 hours - all other weekly window: duration < 168 hours (i.e., 24 * 7 hours) | true | false | None | None | None | +| `single_occurrence_date` | No recurrence. The exclusion window occurs only once and on this date in UTC. Only one of singleOccurrenceDate, daily and daysOfWeek may be set. Structure is [documented below](#nested_backup_schedule_rpo_config_exclusion_windows_exclusion_windows_single_occurrence_date). | false | false | None | None | None | +| `daily` | The exclusion window occurs every day if set to "True". Specifying this field to "False" is an error. Only one of singleOccurrenceDate, daily and daysOfWeek may be set. | false | false | None | None | None | +| `days_of_week` | The exclusion window occurs on these days of each week in UTC. Only one of singleOccurrenceDate, daily and daysOfWeek may be set. Structure is [documented below](#nested_backup_schedule_rpo_config_exclusion_windows_exclusion_windows_days_of_week). | false | false | None | None | None | + +### start_time Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `hours` | Hours of day in 24 hour format. | false | false | None | None | None | +| `minutes` | Minutes of hour of day. | false | false | None | None | None | +| `seconds` | Seconds of minutes of the time. | false | false | None | None | None | +| `nanos` | Fractions of seconds in nanoseconds. | false | false | None | None | None | + +### single_occurrence_date Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `year` | Year of the date. | false | false | None | None | None | +| `month` | Month of a year. | false | false | None | None | None | +| `day` | Day of a month. | false | false | None | None | None | + +### days_of_week Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `days_of_week` | A list of days of week. Each value may be one of: `MONDAY`, `TUESDAY`, `WEDNESDAY`, `THURSDAY`, `FRIDAY`, `SATURDAY`, `SUNDAY`. | false | false | None | None | None | + +### encryption_key Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `gcp_kms_encryption_key` | Google Cloud KMS encryption key. Format: projects/*/locations/*/keyRings/*/cryptoKeys/* | true | true | CMEK keys must be in the same region as the backup plan (australia-southeast1). | projects/p/locations/australia-southeast1/keyRings/k/cryptoKeys/c | projects/p/locations/us-central1/keyRings/k/cryptoKeys/c | + +### selected_namespaces Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `namespaces` | A list of Kubernetes Namespaces. | true | false | None | None | None | + +### selected_applications Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `namespaced_names` | A list of namespaced Kubernetes resources. Structure is [documented below](#nested_backup_config_selected_applications_namespaced_names). | true | false | None | None | None | + +### namespaced_names Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `namespace` | The namespace of a Kubernetes Resource. | true | false | None | None | None | +| `name` | The name of a Kubernetes Resource. | true | false | None | None | None | diff --git a/docs/gcp/Backup_for_GKE/gke_backup_backup_plan_iam.md b/docs/gcp/Backup_for_GKE/gke_backup_backup_plan_iam.md new file mode 100644 index 000000000..669e5eb12 --- /dev/null +++ b/docs/gcp/Backup_for_GKE/gke_backup_backup_plan_iam.md @@ -0,0 +1,18 @@ +## 🛡️ Policy Deployment Engine: `gke_backup_backup_plan_iam` + +This section provides a concise policy evaluation for the `gke_backup_backup_plan_iam` resource in GCP. + +Reference: [Terraform Registry – gke_backup_backup_plan_iam](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_backup_backup_plan_iam) + +--- + +## Argument Reference + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `location` | Used to find the parent resource to bind the IAM policy to. If not specified, the value will be parsed from the identifier of the parent resource. If no location is provided in the parent identifier and no location is specified, it is taken from the provider configuration. | false | false | None | None | None | +| `name` | | false | false | None | None | None | +| `project` | If it is not provided, the project will be parsed from the identifier of the parent resource. If no project is provided in the parent identifier and no project is specified, the provider project is used. | false | false | None | None | None | +| `member/members` | Each entry can have one of the following values: * **allUsers**: A special identifier that represents anyone who is on the internet; with or without a Google account. * **allAuthenticatedUsers**: A special identifier that represents anyone who is authenticated with a Google account or a service account. * **user:{emailid}**: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com. * **serviceAccount:{emailid}**: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com. * **group:{emailid}**: An email address that represents a Google group. For example, admins@example.com. * **domain:{domain}**: A G Suite domain (primary, instead of alias) name that represents all the users of that domain. For example, google.com or example.com. * **projectOwner:projectid**: Owners of the given project. For example, "projectOwner:my-example-project" * **projectEditor:projectid**: Editors of the given project. For example, "projectEditor:my-example-project" * **projectViewer:projectid**: Viewers of the given project. For example, "projectViewer:my-example-project" | false | true | Only corporate identities and internal service accounts are allowed. Personal emails and external accounts are blocked. | group:team@company.com | user:hacker@gmail.com | +| `role` | `google_gke_backup_backup_plan_iam_binding` can be used per role. Note that custom roles must be of the format `[projects|organizations]/{parent-name}/roles/{role-name}`. | false | true | Least privilege principle: use specific backup roles. | roles/gkebackup.viewer | roles/owner | +| `policy_data` | a `google_iam_policy` data source. | false | false | None | None | None | diff --git a/docs/gcp/Backup_for_GKE/gke_backup_restore_channel.md b/docs/gcp/Backup_for_GKE/gke_backup_restore_channel.md new file mode 100644 index 000000000..60c66ee9d --- /dev/null +++ b/docs/gcp/Backup_for_GKE/gke_backup_restore_channel.md @@ -0,0 +1,18 @@ +## 🛡️ Policy Deployment Engine: `gke_backup_restore_channel` + +This section provides a concise policy evaluation for the `gke_backup_restore_channel` resource in GCP. + +Reference: [Terraform Registry – gke_backup_restore_channel](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_backup_restore_channel) + +--- + +## Argument Reference + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `name` | The full name of the RestoreChannel Resource. | true | false | None | None | None | +| `destination_project` | The project where Backups will be restored. The format is `projects/{project}`. {project} can be project number or project id. | true | true | Restores must be performed in approved projects, typically the same region as the backup. | projects/restore-prod | projects/untrusted-dev | +| `location` | The region of the Restore Channel. | true | true | Data sovereignty requires restores to occur in specific Australian regions. | australia-southeast1 | us-central1 | +| `description` | User specified descriptive string for this RestoreChannel. | false | false | None | None | None | +| `labels` | Description: A set of custom labels supplied by the user. A list of key->value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. Please refer to the field `effective_labels` for all of the labels present on the resource. | false | false | Labels are required for cost allocation and ownership tracking. | environment='prod', cost-center='123', owner='team' | missing required labels | +| `project` | If it is not provided, the provider project is used. | false | false | None | None | None | diff --git a/docs/gcp/Backup_for_GKE/gke_backup_restore_plan.md b/docs/gcp/Backup_for_GKE/gke_backup_restore_plan.md new file mode 100644 index 000000000..ae92547cf --- /dev/null +++ b/docs/gcp/Backup_for_GKE/gke_backup_restore_plan.md @@ -0,0 +1,167 @@ +## 🛡️ Policy Deployment Engine: `gke_backup_restore_plan` + +This section provides a concise policy evaluation for the `gke_backup_restore_plan` resource in GCP. + +Reference: [Terraform Registry – gke_backup_restore_plan](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_backup_restore_plan) + +--- + +## Argument Reference + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `name` | The full name of the BackupPlan Resource. | true | false | None | None | None | +| `backup_plan` | A reference to the BackupPlan from which Backups may be used as the source for Restores created via this RestorePlan. | true | false | None | None | None | +| `cluster` | The source cluster from which Restores will be created via this RestorePlan. | true | true | Restores must target a designated DR cluster in the approved region. | projects/*/locations/australia-southeast1/clusters/*-dr | projects/*/locations/us-central1/clusters/*-dr | +| `restore_config` | Defines the configuration of Restores created via this RestorePlan. Structure is [documented below](#nested_restore_config). | true | false | None | None | None | +| `location` | The region of the Restore Plan. | true | true | Restore plans must be created in the approved region (australia-southeast1). | australia-southeast1 | us-central1 | +| `description` | User specified descriptive string for this RestorePlan. | false | false | None | None | None | +| `labels` | Description: A set of custom labels supplied by the user. A list of key->value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. Please refer to the field `effective_labels` for all of the labels present on the resource. | false | false | None | None | None | +| `project` | If it is not provided, the provider project is used. | false | false | None | None | None | +| `excluded_namespaces` | | false | false | None | None | None | +| `selected_namespaces` | | false | false | None | None | None | +| `selected_applications` | | false | false | None | None | None | +| `namespaced_names` | | false | false | None | None | None | +| `cluster_resource_restore_scope` | | false | false | None | None | None | +| `excluded_group_kinds` | | false | false | None | None | None | +| `selected_group_kinds` | | false | false | None | None | None | +| `transformation_rules` | | false | false | None | None | None | +| `resource_filter` | | false | false | None | None | None | +| `group_kinds` | | false | false | None | None | None | +| `field_actions` | | false | false | None | None | None | +| `volume_data_restore_policy_bindings` | | false | false | None | None | None | +| `restore_order` | | false | false | None | None | None | +| `group_kind_dependencies` | | false | false | None | None | None | +| `satisfying` | | false | false | None | None | None | +| `requiring` | | false | false | None | None | None | + +### restore_config Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `all_namespaces` | If True, restore all namespaced resources in the Backup. Setting this field to False will result in an error. | false | false | None | None | None | +| `excluded_namespaces` | A list of selected namespaces excluded from restoration. All namespaces except those in this list will be restored. Structure is [documented below](#nested_restore_config_excluded_namespaces). | false | false | None | None | None | +| `selected_namespaces` | A list of selected namespaces to restore from the Backup. The listed Namespaces and all resources contained in them will be restored. Structure is [documented below](#nested_restore_config_selected_namespaces). | false | false | None | None | None | +| `selected_applications` | A list of selected ProtectedApplications to restore. The listed ProtectedApplications and all the resources to which they refer will be restored. Structure is [documented below](#nested_restore_config_selected_applications). | false | false | None | None | None | +| `no_namespaces` | Do not restore any namespaced resources if set to "True". Specifying this field to "False" is not allowed. | false | false | None | None | None | +| `namespaced_resource_restore_mode` | Defines the behavior for handling the situation where sets of namespaced resources being restored already exist in the target cluster. This MUST be set to a value other than `NAMESPACED_RESOURCE_RESTORE_MODE_UNSPECIFIED` if the `namespacedResourceRestoreScope` is anything other than `noNamespaces`. See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#namespacedresourcerestoremode for more information on each mode. Possible values are: `DELETE_AND_RESTORE`, `FAIL_ON_CONFLICT`, `MERGE_SKIP_ON_CONFLICT`, `MERGE_REPLACE_VOLUME_ON_CONFLICT`, `MERGE_REPLACE_ON_CONFLICT`. | false | false | None | None | None | +| `volume_data_restore_policy` | Specifies the mechanism to be used to restore volume data. This should be set to a value other than `NAMESPACED_RESOURCE_RESTORE_MODE_UNSPECIFIED` if the `namespacedResourceRestoreScope` is anything other than `noNamespaces`. If not specified, it will be treated as `NO_VOLUME_DATA_RESTORATION`. See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#VolumeDataRestorePolicy for more information on each policy option. Possible values are: `RESTORE_VOLUME_DATA_FROM_BACKUP`, `REUSE_VOLUME_HANDLE_FROM_BACKUP`, `NO_VOLUME_DATA_RESTORATION`. | false | false | None | None | None | +| `cluster_resource_restore_scope` | Identifies the cluster-scoped resources to restore from the Backup. Structure is [documented below](#nested_restore_config_cluster_resource_restore_scope). | false | false | None | None | None | +| `cluster_resource_conflict_policy` | Defines the behavior for handling the situation where cluster-scoped resources being restored already exist in the target cluster. This MUST be set to a value other than `CLUSTER_RESOURCE_CONFLICT_POLICY_UNSPECIFIED` if `clusterResourceRestoreScope` is anyting other than `noGroupKinds`. See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#clusterresourceconflictpolicy for more information on each policy option. Possible values are: `USE_EXISTING_VERSION`, `USE_BACKUP_VERSION`. | false | true | Conflict policy should default to using existing versions to preserve state stability. | USE_EXISTING_VERSION | USE_BACKUP_VERSION | +| `transformation_rules` | A list of transformation rules to be applied against Kubernetes resources as they are selected for restoration from a Backup. Rules are executed in order defined - this order matters, as changes made by a rule may impact the filtering logic of subsequent rules. An empty list means no transformation will occur. Structure is [documented below](#nested_restore_config_transformation_rules). | false | false | None | None | None | +| `volume_data_restore_policy_bindings` | A table that binds volumes by their scope to a restore policy. Bindings must have a unique scope. Any volumes not scoped in the bindings are subject to the policy defined in volume_data_restore_policy. Structure is [documented below](#nested_restore_config_volume_data_restore_policy_bindings). | false | false | None | None | None | +| `restore_order` | It contains custom ordering to use on a Restore. Structure is [documented below](#nested_restore_config_restore_order). | false | false | None | None | None | + +### excluded_namespaces Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `namespaces` | A list of Kubernetes Namespaces. | true | false | None | None | None | + +### selected_namespaces Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `namespaces` | A list of Kubernetes Namespaces. | true | false | None | None | None | + +### selected_applications Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `namespaced_names` | A list of namespaced Kubernetes resources. Structure is [documented below](#nested_restore_config_selected_applications_namespaced_names). | true | false | None | None | None | + +### namespaced_names Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `namespace` | The namespace of a Kubernetes Resource. | true | false | None | None | None | +| `name` | The name of a Kubernetes Resource. | true | false | None | None | None | + +### cluster_resource_restore_scope Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `all_group_kinds` | If True, all valid cluster-scoped resources will be restored. Mutually exclusive to any other field in `clusterResourceRestoreScope`. | false | true | Avoid full cluster restores to prevent overwriting critical existing resources unless explicitly intended. | selected_group_kinds | all_group_kinds=true | +| `excluded_group_kinds` | A list of cluster-scoped resource group kinds to NOT restore from the backup. If specified, all valid cluster-scoped resources will be restored except for those specified in the list. Mutually exclusive to any other field in `clusterResourceRestoreScope`. Structure is [documented below](#nested_restore_config_cluster_resource_restore_scope_excluded_group_kinds). | false | false | None | None | None | +| `selected_group_kinds` | A list of cluster-scoped resource group kinds to restore from the backup. If specified, only the selected resources will be restored. Mutually exclusive to any other field in the `clusterResourceRestoreScope`. Structure is [documented below](#nested_restore_config_cluster_resource_restore_scope_selected_group_kinds). | false | false | None | None | None | +| `no_group_kinds` | If True, no cluster-scoped resources will be restored. Mutually exclusive to any other field in `clusterResourceRestoreScope`. | false | false | None | None | None | + +### excluded_group_kinds Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `resource_group` | API Group string of a Kubernetes resource, e.g. "apiextensions.k8s.io", "storage.k8s.io", etc. Use empty string for core group. | false | false | None | None | None | +| `resource_kind` | Kind of a Kubernetes resource, e.g. "CustomResourceDefinition", "StorageClass", etc. | false | false | None | None | None | + +### selected_group_kinds Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `resource_group` | API Group string of a Kubernetes resource, e.g. "apiextensions.k8s.io", "storage.k8s.io", etc. Use empty string for core group. | false | false | None | None | None | +| `resource_kind` | Kind of a Kubernetes resource, e.g. "CustomResourceDefinition", "StorageClass", etc. | false | false | None | None | None | + +### transformation_rules Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `description` | The description is a user specified string description of the transformation rule. | false | false | None | None | None | +| `resource_filter` | This field is used to specify a set of fields that should be used to determine which resources in backup should be acted upon by the supplied transformation rule actions, and this will ensure that only specific resources are affected by transformation rule actions. Structure is [documented below](#nested_restore_config_transformation_rules_transformation_rules_resource_filter). | false | false | None | None | None | +| `field_actions` | A list of transformation rule actions to take against candidate resources. Actions are executed in order defined - this order matters, as they could potentially interfere with each other and the first operation could affect the outcome of the second operation. Structure is [documented below](#nested_restore_config_transformation_rules_transformation_rules_field_actions). | true | false | None | None | None | + +### resource_filter Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `namespaces` | (Filtering parameter) Any resource subject to transformation must be contained within one of the listed Kubernetes Namespace in the Backup. If this field is not provided, no namespace filtering will be performed (all resources in all Namespaces, including all cluster-scoped resources, will be candidates for transformation). To mix cluster-scoped and namespaced resources in the same rule, use an empty string ("") as one of the target namespaces. | false | false | None | None | None | +| `group_kinds` | (Filtering parameter) Any resource subject to transformation must belong to one of the listed "types". If this field is not provided, no type filtering will be performed (all resources of all types matching previous filtering parameters will be candidates for transformation). Structure is [documented below](#nested_restore_config_transformation_rules_transformation_rules_resource_filter_group_kinds). | false | false | None | None | None | +| `json_path` | This is a JSONPath expression that matches specific fields of candidate resources and it operates as a filtering parameter (resources that are not matched with this expression will not be candidates for transformation). | false | false | None | None | None | + +### group_kinds Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `resource_group` | API Group string of a Kubernetes resource, e.g. "apiextensions.k8s.io", "storage.k8s.io", etc. Use empty string for core group. | false | false | None | None | None | +| `resource_kind` | Kind of a Kubernetes resource, e.g. "CustomResourceDefinition", "StorageClass", etc. | false | false | None | None | None | + +### field_actions Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `op` | Specifies the operation to perform. Possible values are: `REMOVE`, `MOVE`, `COPY`, `ADD`, `TEST`, `REPLACE`. | true | false | None | None | None | +| `from_path` | A string containing a JSON Pointer value that references the location in the target document to move the value from. | false | false | None | None | None | +| `path` | A string containing a JSON-Pointer value that references a location within the target document where the operation is performed. | false | false | None | None | None | +| `value` | A string that specifies the desired value in string format to use for transformation. | false | false | None | None | None | + +### volume_data_restore_policy_bindings Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `policy` | Specifies the mechanism to be used to restore this volume data. See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#VolumeDataRestorePolicy for more information on each policy option. Possible values are: `RESTORE_VOLUME_DATA_FROM_BACKUP`, `REUSE_VOLUME_HANDLE_FROM_BACKUP`, `NO_VOLUME_DATA_RESTORATION`. | true | false | None | None | None | +| `volume_type` | The volume type, as determined by the PVC's bound PV, to apply the policy to. Possible values are: `GCE_PERSISTENT_DISK`. | true | false | None | None | None | + +### restore_order Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `group_kind_dependencies` | A list of group kind dependency pairs that is used by Backup for GKE to generate a group kind restore order. Structure is [documented below](#nested_restore_config_restore_order_group_kind_dependencies). | true | false | None | None | None | + +### group_kind_dependencies Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `satisfying` | The satisfying group kind must be restored first in order to satisfy the dependency. Structure is [documented below](#nested_restore_config_restore_order_group_kind_dependencies_group_kind_dependencies_satisfying). | true | false | None | None | None | +| `requiring` | The requiring group kind requires that the satisfying group kind be restored first. Structure is [documented below](#nested_restore_config_restore_order_group_kind_dependencies_group_kind_dependencies_requiring). | true | false | None | None | None | + +### satisfying Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `resource_group` | API Group of a Kubernetes resource, e.g. "apiextensions.k8s.io", "storage.k8s.io", etc. Use empty string for core group. | false | false | None | None | None | +| `resource_kind` | Kind of a Kubernetes resource, e.g. "CustomResourceDefinition", "StorageClass", etc. | false | false | None | None | None | + +### requiring Block + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `resource_group` | API Group of a Kubernetes resource, e.g. "apiextensions.k8s.io", "storage.k8s.io", etc. Use empty string for core group. | false | false | None | None | None | +| `resource_kind` | Kind of a Kubernetes resource, e.g. "CustomResourceDefinition", "StorageClass", etc. | false | false | None | None | None | diff --git a/docs/gcp/Backup_for_GKE/gke_backup_restore_plan_iam.md b/docs/gcp/Backup_for_GKE/gke_backup_restore_plan_iam.md new file mode 100644 index 000000000..23a84d577 --- /dev/null +++ b/docs/gcp/Backup_for_GKE/gke_backup_restore_plan_iam.md @@ -0,0 +1,18 @@ +## 🛡️ Policy Deployment Engine: `gke_backup_restore_plan_iam` + +This section provides a concise policy evaluation for the `gke_backup_restore_plan_iam` resource in GCP. + +Reference: [Terraform Registry – gke_backup_restore_plan_iam](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/gke_backup_restore_plan_iam) + +--- + +## Argument Reference + +| Argument | Description | Required | Security Impact | Rationale | Compliant | Non-Compliant | +|----------|-------------|----------|-----------------|-----------|-----------|---------------| +| `location` | Used to find the parent resource to bind the IAM policy to. If not specified, the value will be parsed from the identifier of the parent resource. If no location is provided in the parent identifier and no location is specified, it is taken from the provider configuration. | false | false | None | None | None | +| `name` | | false | false | None | None | None | +| `project` | If it is not provided, the project will be parsed from the identifier of the parent resource. If no project is provided in the parent identifier and no project is specified, the provider project is used. | false | false | None | None | None | +| `member/members` | Each entry can have one of the following values: * **allUsers**: A special identifier that represents anyone who is on the internet; with or without a Google account. * **allAuthenticatedUsers**: A special identifier that represents anyone who is authenticated with a Google account or a service account. * **user:{emailid}**: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com. * **serviceAccount:{emailid}**: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com. * **group:{emailid}**: An email address that represents a Google group. For example, admins@example.com. * **domain:{domain}**: A G Suite domain (primary, instead of alias) name that represents all the users of that domain. For example, google.com or example.com. * **projectOwner:projectid**: Owners of the given project. For example, "projectOwner:my-example-project" * **projectEditor:projectid**: Editors of the given project. For example, "projectEditor:my-example-project" * **projectViewer:projectid**: Viewers of the given project. For example, "projectViewer:my-example-project" | false | true | Only corporate identities and internal service accounts are allowed. Cross-project groups and personal emails are blocked. | group:team@company.com | group:external@other.com | +| `role` | `google_gke_backup_restore_plan_iam_binding` can be used per role. Note that custom roles must be of the format `[projects|organizations]/{parent-name}/roles/{role-name}`. | false | true | Least privilege principle: use specific restore roles. | roles/gkebackup.restoreAdmin | roles/owner | +| `policy_data` | a `google_iam_policy` data source. | false | false | None | None | None | diff --git a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_channel.json b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_channel.json index 9f76a988f..378a3bcdc 100644 --- a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_channel.json +++ b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_channel.json @@ -14,19 +14,19 @@ "destination_project": { "description": "The project where Backups are allowed to be stored. The format is `projects/{project}`. {project} can be project number or project id.", "required": true, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Backups must be stored in a dedicated backup project to ensure isolation.", + "compliant": "projects/backup-prod", + "non-compliant": "projects/my-app-dev", "parent": null }, "location": { "description": "The region of the Backup Channel.", "required": true, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Data sovereignty requires backups to be stored in specific Australian regions.", + "compliant": "australia-southeast1", + "non-compliant": "us-central1", "parent": null }, "description": { @@ -41,10 +41,10 @@ "labels": { "description": "Description: A set of custom labels supplied by the user. A list of key->value pairs. Example: { \"name\": \"wrench\", \"mass\": \"1.3kg\", \"count\": \"3\" }. **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. Please refer to the field `effective_labels` for all of the labels present on the resource.", "required": false, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": false, + "rationale": "Labels are required for cost allocation and ownership tracking.", + "compliant": "environment='prod', cost-center='123', owner='team'", + "non-compliant": "missing required labels", "parent": null }, "project": { diff --git a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_plan.json b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_plan.json index 7ded8e92a..0ceaadbfb 100644 --- a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_plan.json +++ b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_plan.json @@ -23,10 +23,10 @@ "location": { "description": "The region of the Backup Plan.", "required": true, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Data sovereignty requires backups to be stored in specific Australian regions.", + "compliant": "australia-southeast1", + "non-compliant": "us-central1", "parent": null }, "description": { @@ -59,10 +59,10 @@ "backup_retain_days": { "description": "The default maximum age of a Backup created via this BackupPlan. This field MUST be an integer value >= 0 and <= 365. If specified, a Backup created under this BackupPlan will be automatically deleted after its age reaches (createTime + backupRetainDays). If not specified, Backups created under this BackupPlan will NOT be subject to automatic deletion. Updating this field does NOT affect existing Backups under it. Backups created AFTER a successful update will automatically pick up the new value. NOTE: backupRetainDays must be >= backupDeleteLockDays. If cronSchedule is defined, then this must be <= 360 * the creation interval. If rpo_config is defined, then this must be <= 360 * targetRpoMinutes/(1440minutes/day)", "required": false, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Retention period must be sufficient for disaster recovery but not exceed data retention policies (7-90 days).", + "compliant": "30", + "non-compliant": "1", "parent": "retention_policy" }, "locked": { @@ -79,10 +79,10 @@ "labels": { "description": "Description: A set of custom labels supplied by the user. A list of key->value pairs. Example: { \"name\": \"wrench\", \"mass\": \"1.3kg\", \"count\": \"3\" }. **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. Please refer to the field `effective_labels` for all of the labels present on the resource.", "required": false, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": false, + "rationale": "Labels are required for cost allocation and ownership tracking.", + "compliant": "environment='prod', cost-center='123', owner='team'", + "non-compliant": "missing required labels", "parent": null }, "backup_schedule": { @@ -97,10 +97,10 @@ "cron_schedule": { "description": "A standard cron string that defines a repeating schedule for creating Backups via this BackupPlan. This is mutually exclusive with the rpoConfig field since at most one schedule can be defined for a BackupPlan. If this is defined, then backupRetainDays must also be defined.", "required": false, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Backups should run during off-peak hours to minimize impact.", + "compliant": "0 2 * * *", + "non-compliant": "* * * * *", "parent": "backup_schedule" }, "paused": { @@ -126,19 +126,19 @@ "deactivated": { "description": "This flag indicates whether this BackupPlan has been deactivated. Setting this field to True locks the BackupPlan such that no further updates will be allowed (except deletes), including the deactivated field itself. It also prevents any new Backups from being created via this BackupPlan (including scheduled Backups).", "required": false, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Deactivated plans do not create backups, putting data at risk.", + "compliant": "false", + "non-compliant": "true", "parent": null }, "backup_config": { "description": "Defines the configuration of Backups created via this BackupPlan. Structure is [documented below](#nested_backup_config).", "required": false, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Backup configuration must explicitly define secret handling and encryption.", + "compliant": "See sub-arguments", + "non-compliant": "See sub-arguments", "parent": null, "arguments": { "include_volume_data": { @@ -417,10 +417,10 @@ "gcp_kms_encryption_key": { "description": "Google Cloud KMS encryption key. Format: projects/*/locations/*/keyRings/*/cryptoKeys/*", "required": true, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "CMEK keys must be in the same region as the backup plan (australia-southeast1).", + "compliant": "projects/p/locations/australia-southeast1/keyRings/k/cryptoKeys/c", + "non-compliant": "projects/p/locations/us-central1/keyRings/k/cryptoKeys/c", "parent": "encryption_key" } } diff --git a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_plan_iam.json b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_plan_iam.json index 25f1a51ad..95419ecda 100644 --- a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_plan_iam.json +++ b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_plan_iam.json @@ -31,20 +31,18 @@ }, "member/members": { "description": "Each entry can have one of the following values: * **allUsers**: A special identifier that represents anyone who is on the internet; with or without a Google account. * **allAuthenticatedUsers**: A special identifier that represents anyone who is authenticated with a Google account or a service account. * **user:{emailid}**: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com. * **serviceAccount:{emailid}**: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com. * **group:{emailid}**: An email address that represents a Google group. For example, admins@example.com. * **domain:{domain}**: A G Suite domain (primary, instead of alias) name that represents all the users of that domain. For example, google.com or example.com. * **projectOwner:projectid**: Owners of the given project. For example, \"projectOwner:my-example-project\" * **projectEditor:projectid**: Editors of the given project. For example, \"projectEditor:my-example-project\" * **projectViewer:projectid**: Viewers of the given project. For example, \"projectViewer:my-example-project\"", - "required": null, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Only corporate identities and internal service accounts are allowed. Personal emails and external accounts are blocked.", + "compliant": "group:team@company.com", + "non-compliant": "user:hacker@gmail.com", "parent": null }, "role": { "description": "`google_gke_backup_backup_plan_iam_binding` can be used per role. Note that custom roles must be of the format `[projects|organizations]/{parent-name}/roles/{role-name}`.", - "required": null, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Least privilege principle: use specific backup roles.", + "compliant": "roles/gkebackup.viewer", + "non-compliant": "roles/owner", "parent": null }, "policy_data": { diff --git a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_channel.json b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_channel.json index 5935d7987..402e7cd75 100644 --- a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_channel.json +++ b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_channel.json @@ -14,19 +14,19 @@ "destination_project": { "description": "The project where Backups will be restored. The format is `projects/{project}`. {project} can be project number or project id.", "required": true, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Restores must be performed in approved projects, typically the same region as the backup.", + "compliant": "projects/restore-prod", + "non-compliant": "projects/untrusted-dev", "parent": null }, "location": { "description": "The region of the Restore Channel.", "required": true, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Data sovereignty requires restores to occur in specific Australian regions.", + "compliant": "australia-southeast1", + "non-compliant": "us-central1", "parent": null }, "description": { @@ -41,10 +41,10 @@ "labels": { "description": "Description: A set of custom labels supplied by the user. A list of key->value pairs. Example: { \"name\": \"wrench\", \"mass\": \"1.3kg\", \"count\": \"3\" }. **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. Please refer to the field `effective_labels` for all of the labels present on the resource.", "required": false, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": false, + "rationale": "Labels are required for cost allocation and ownership tracking.", + "compliant": "environment='prod', cost-center='123', owner='team'", + "non-compliant": "missing required labels", "parent": null }, "project": { diff --git a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_plan.json b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_plan.json index 6ed3801c8..1cea25fe5 100644 --- a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_plan.json +++ b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_plan.json @@ -23,10 +23,10 @@ "cluster": { "description": "The source cluster from which Restores will be created via this RestorePlan.", "required": true, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Restores must target a designated DR cluster in the approved region.", + "compliant": "projects/*/locations/australia-southeast1/clusters/*-dr", + "non-compliant": "projects/*/locations/us-central1/clusters/*-dr", "parent": null }, "restore_config": { @@ -113,10 +113,10 @@ "cluster_resource_conflict_policy": { "description": "Defines the behavior for handling the situation where cluster-scoped resources being restored already exist in the target cluster. This MUST be set to a value other than `CLUSTER_RESOURCE_CONFLICT_POLICY_UNSPECIFIED` if `clusterResourceRestoreScope` is anyting other than `noGroupKinds`. See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#clusterresourceconflictpolicy for more information on each policy option. Possible values are: `USE_EXISTING_VERSION`, `USE_BACKUP_VERSION`.", "required": false, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Conflict policy should default to using existing versions to preserve state stability.", + "compliant": "USE_EXISTING_VERSION", + "non-compliant": "USE_BACKUP_VERSION", "parent": "restore_config" }, "transformation_rules": { @@ -151,10 +151,10 @@ "location": { "description": "The region of the Restore Plan.", "required": true, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Restore plans must be created in the approved region (australia-southeast1).", + "compliant": "australia-southeast1", + "non-compliant": "us-central1", "parent": null }, "description": { @@ -285,10 +285,10 @@ "all_group_kinds": { "description": "If True, all valid cluster-scoped resources will be restored. Mutually exclusive to any other field in `clusterResourceRestoreScope`.", "required": false, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Avoid full cluster restores to prevent overwriting critical existing resources unless explicitly intended.", + "compliant": "selected_group_kinds", + "non-compliant": "all_group_kinds=true", "parent": "cluster_resource_restore_scope" }, "excluded_group_kinds": { diff --git a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_plan_iam.json b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_plan_iam.json index 6b64d1691..c773a690f 100644 --- a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_plan_iam.json +++ b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_restore_plan_iam.json @@ -32,19 +32,19 @@ "member/members": { "description": "Each entry can have one of the following values: * **allUsers**: A special identifier that represents anyone who is on the internet; with or without a Google account. * **allAuthenticatedUsers**: A special identifier that represents anyone who is authenticated with a Google account or a service account. * **user:{emailid}**: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com. * **serviceAccount:{emailid}**: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com. * **group:{emailid}**: An email address that represents a Google group. For example, admins@example.com. * **domain:{domain}**: A G Suite domain (primary, instead of alias) name that represents all the users of that domain. For example, google.com or example.com. * **projectOwner:projectid**: Owners of the given project. For example, \"projectOwner:my-example-project\" * **projectEditor:projectid**: Editors of the given project. For example, \"projectEditor:my-example-project\" * **projectViewer:projectid**: Viewers of the given project. For example, \"projectViewer:my-example-project\"", "required": null, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Only corporate identities and internal service accounts are allowed. Cross-project groups and personal emails are blocked.", + "compliant": "group:team@company.com", + "non-compliant": "group:external@other.com", "parent": null }, "role": { "description": "`google_gke_backup_restore_plan_iam_binding` can be used per role. Note that custom roles must be of the format `[projects|organizations]/{parent-name}/roles/{role-name}`.", "required": null, - "security_impact": null, - "rationale": null, - "compliant": null, - "non-compliant": null, + "security_impact": true, + "rationale": "Least privilege principle: use specific restore roles.", + "compliant": "roles/gkebackup.restoreAdmin", + "non-compliant": "roles/owner", "parent": null }, "policy_data": { diff --git a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/.terraform.lock.hcl new file mode 100644 index 000000000..5698484ba --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.16.0" + hashes = [ + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/c.tf b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/c.tf new file mode 100644 index 000000000..5288bd019 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/c.tf @@ -0,0 +1,13 @@ +resource "google_gke_backup_backup_channel" "c" { + name = "c" + location = "australia-southeast1" + project = "PDE" + destination_project = "projects/backup-prod" + + labels = { + "environment" = "prod" + "owner" = "platform-team" + "cost-center" = "1234" + "bandwidth-limit" = "50mbps" + } +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/config.tf b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/config.tf similarity index 69% rename from inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/config.tf rename to inputs/gcp/backup_for_gke/backup_channel/bandwidth/config.tf index b9c23f44c..d066e09a3 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/config.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/config.tf @@ -1,4 +1,5 @@ ##### DO NOT EDIT ###### + terraform { required_providers { google = { @@ -9,6 +10,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/nc.tf new file mode 100644 index 000000000..183f1ce38 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/nc.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_backup_channel" "nc" { + name = "nc" + location = "australia-southeast1" + project = "PDE" + destination_project = "projects/backup-prod" + + labels = { + "environment" = "prod" + # Missing bandwidth-limit + } +} diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/c.tf b/inputs/gcp/backup_for_gke/backup_channel/description/c.tf index a94202b1c..9ce03a9a4 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/description/c.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/description/c.tf @@ -1,7 +1,8 @@ resource "google_gke_backup_backup_channel" "c" { - name = "backup-channel-with-desc" + name = "c" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" + project = "PDE" + destination_project = "projects/PDE" description = "Production backup channel for GKE cluster backup operations" -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/config.tf b/inputs/gcp/backup_for_gke/backup_channel/description/config.tf index 6d33dfcda..d066e09a3 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/description/config.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/description/config.tf @@ -10,6 +10,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf index 1660c215e..7538ca453 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf @@ -1,7 +1,7 @@ resource "google_gke_backup_backup_channel" "nc" { - name = "backup-channel-no-desc" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" - # Missing description - non-compliant -} \ No newline at end of file + project = "PDE" + destination_project = "projects/PDE" +} + diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/plan.json b/inputs/gcp/backup_for_gke/backup_channel/description/plan.json index 9d889b3a09b65396cb7ee8d2f311a6a209bd1ba6..2eff9153ac592d4674a57e94a1cac51a46ba6e67 100644 GIT binary patch literal 3770 zcmeHKO^?$s5WVv&DxceKTLcn4v*N&|2Tq_> zPKoXDeCN%}L1f03(kDBzt}vBYiurUQ#=?`elF#m)%wJFEIIOj-DoT@`)D1bYJP2!y zPfC+En!=KtX{_S2F9#vh)RM!y$c@Q0CHa<;wN%@t?jCBx8ue5`JJdjlC}kycO4*lv z%^QzhhGZp6mSiopHM=4uo3wkD^1^w$pZ1YW3v;uPZc`{@>zk+@7oFNrDNkX~#^Mxb zN>16L_Ayl}i-;93MlqaG8^;Kl8-4hAJ5suFFxVZNnyh4b2Sd>1iz+M=c>9%{6EG*?Z!mw6&=Wmp0F?n%7(RuvBt40{u~-ve1^5;l zMP~R$SoS|AU4n~em=yAuG}X2;-!T6|J|E(8QUF>RSqA|b%|~A5oy19Y2*k#s=>%{u zmNe;cQ7kj59n3_pe%e0_jRI&GvhgyJ@(H^C--Xb>vx@kfRKkL8+KAL@tYaCl)#&JjhFNDVB8Lf?}H6n&2)tj}i=;t9i!guYpJYY8@Yr zqQOX?H_>2!zn$qo&3NXb0m~Y#x0o&7PG&vm`vO^!GZo0o-0LBoImU3z68p6KKf55 zpzjhNJEl^V$jsnBGgzm%`T{&s%<>2reF0{iMfYk9J}a;0ke4xd?#i7%wtt;Kn(Z9w z3{$!n_?sF2$HUvoH(;7c%%N1pV?gY$au~GXiq)2D=$V!8)bJz^m9sa){S72;4Vq8T z(jMeB{KVLXr)HKm`2K7(W)1#4b!I!B#tk5S!g!pmay#-YS`spCSDB2HYn83U@QfJJ zPOZQf*Ft{4@07V6p3r*(N3sWox=gYMdz(3sck*7|!p@G39U||^bHDe}NFZlI;gg~` z&G4xqBubV-EVrl$M$X&W4Q4vdX12w0f^nwchUF>Orqo!{3;Z{4SS6I!rZ%%t!#(Ho z(mveNPOZ^Zkv3c{3-!dVCHYmgX-vKEuN3-wQ=61$lNWi>PnBM*OSWP2@eBxE1(#p5+3zCDwL42H&zBUwZG7v2vVjtG?BHmumUiuI%*oxq|n;UhnHs;^;j- z3}0^nJbOP+tweSEFy)#SsrU0@{8^O%`pAA>raXEG^V}3}*wgh-otI`8-9Emjm>`OF zbCv1OxQ{tIjR8KE!meL)kLN!&dyj{Di=5|fGmph+JcP>o<@+U$?AWNjUPe^@DJxn2 zu3qZ2kKb~1N;9)+%ovC0_jzE}CP7A#F(h|vG#ee~9g@Q7-g?AvMyag#R1^6C%>123;BQ)x~*8b$yldS=NVV0780XJ^lLV ze1&#sjStU4*c!@XS4QV&Kxxo6E2zdmi&^L9eLL-| zZIceC=Jdw5y=MB_8k^gi$iJqxn!CGNS)Hw5bsD1h`mM%U|?xvEK^YZ^O85vom@MEdF#tx7;hQz3M_b!z=l_ z<%qj>cfpDH9l35f;!5=GXc8+1xTnmPSD{Wf+?T3;I(7{UIk6T(b*L?l(~Y~`9q_sQ7<{gf-Gm}vin|N>$myYYUA;dLqUpui z@BIOnCw?RoXY*WGcDIW8jC#Ml-XHLD=56LV)WR3>?|lKEC%?KcP$yr0zRu^3dSRjO z(kS+?^4{W4H`z#$wIj@`>H9gDWwY?RNc0SM4xB(MYwAo=Q^$^Mr%+Y>@66aqvkO6}Xcu)?oa)%) z`FI{bzn(C@1-qdI=-cgT-h&#Yu(e1_RocPe@*9PHZYLfx_gh?#-X3n4LUK#dw~?_ph4y zMKa>c>|)|DI`3ab$Fvf}Yh6t9lILqqaX-FcKQT*f0GY`L1P-+WrFH_LaM<@z&eduUs8gf0II a%MYS*O>2+@$M8UUPojg~%k+|+U;O}ISPz;2 literal 17394 zcmeHPQE%He5a#oM{f9x%bK0csR`hr5X@wy;PV8oN9K&|f6+`~|w(m%PlSon0QHm8O z6O4qGC6dSEcgMTqQUCn?m-*5BV17D$GP5vuW@~QE%;knG5 zn=^BP^5>xL-afrWUAEHH!nt{ecFrU1JfMXw`ka|dvqGD@L(e{~1r>HA^t;{{@aCD2q^%`wV(9)f`vg4YV_vRP#(fn%O;xjQ{aGiM^V5^Vb zua6ZzZP3FE{9L2mE6Zil&^A&T-<_SATT9oy<&SQpTlBU=t$T23Zoj*FpFL_hhOlhr zWB7E2@m=BL`sAoGv$XUtE!8=$zJiV%vpfSuUqPA7qJK39pUJBg@G=L_ecXk8hu0a< z?BIB9u+oH=~wmM7&_W%ic1zXRg7 z81orQ(FbJ-KeM{wjh&?({@+-M*@8cByxC44;|?u-L4Pt^aXs=j83~276O(DUCblxm zGoeuQ)CPPhYsfW_yuv39r(xUDrpzPWy@Pe{6iC}MX7`tGYYm{hI%DJG{Y4-9O$F|$bP;a+A&-+<~3w;r>f(DzH zu)q<{Fg_=pvVzEpIl;B)_`Q{#nY~+GV@YdUnN@T`Sv$+>Sk}&NwG{o}P{H{rR^+Z& z^D)lR4}8tuIwwu@9*?6L+#7Ctt+1{0x2yG z8+okivmqmnVKki<*D)iFdfPywnL-K^6oyue~mn8dFik8c_cpV(6z9U z8Hrx&M&RSM8ujjmS?vm`9esf${S4~3-}IF4qmYI=nwu?3;q!4a7Bo@X*Wh>P#yNT( z#Hs9{jh=^23zBF3J&$9>$n~pplSbn>!}4WVan0;ia$MF=g?YcFe zhzd*bx%$SkwSD>)+~{%0T!^+DJ&q8S?plwlOB?Bud~M01t@8~=kHhWv$GwGc4w|2e z-}Qf;2A-W*d6GT9fW}!O;vm_xqJ4^t`nYGpm7$!WTW(3?`4x79VhvkTWa%BikTmnrzU6h`&J}h@)c~5F(kX-FwCy0+|$5XEiR8P0yldA&1OH}P|LU3kb|r>gyUKFu<|;`44;rpmWupSPb) z(u`W$a~cMoH#Vr+Q!~zcl=!2>fcQoRi3zzk zE_8pxLP&M9y%)dh{~GG@Vu!%_qqp#^>4RS2{SO!B1I{~~<1@kc_vSbJ_7U&L_<&zN z;rl!DJD&GFc(Kbi_^gm4%y(P3HscvLZq<{XCFbU`Q)L$Fo^~e+T|Ah%Mn&{jQ1xj3 E1tg%^*#H0l diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf b/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf index fd65e38f1..c69c0e24a 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf @@ -1,13 +1,15 @@ resource "google_gke_backup_backup_channel" "c" { - name = "backup-channel-with-labels" + name = "c" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" + project = "PDE" + destination_project = "projects/PDE" labels = { - environment = "production" + environment = "prod" team = "platform" compliance = "required" cost-center = "engineering" + owner = "platform-team" } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/config.tf b/inputs/gcp/backup_for_gke/backup_channel/labels/config.tf index 6d33dfcda..d066e09a3 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/labels/config.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/config.tf @@ -10,6 +10,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/labels/nc.tf index 8333763bc..7538ca453 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/labels/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/nc.tf @@ -1,7 +1,7 @@ resource "google_gke_backup_backup_channel" "nc" { - name = "backup-channel-no-labels" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" - # Missing labels - non-compliant -} \ No newline at end of file + project = "PDE" + destination_project = "projects/PDE" +} + diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/plan.json b/inputs/gcp/backup_for_gke/backup_channel/labels/plan.json index 5f736387db5b7c8121d759f25a09f70271f4df21..6dde275193e9bddb3af7d940bbed2034513a34bf 100644 GIT binary patch literal 4426 zcmeHKO^@0z5WV+j_#9ZEA5uBD_a1s`wTg@xf|tZjZHE>i{(IlpA+WoVfOfZKr9Bbs z@pwL-=gn-z!n#U^d`-@4Ys6HHhZB*BK+Z|tySFobI~-%PE~POv&)2eS$cyP#IBP>* z*?Ch^{7c?8PVwINt&sD%Bad%USX-2o7c0tVQmvYL|D%?yu^cLBhZ-mml{B)TIoq1=jVN@>0&Ij4@NTs!J`6Vv`;H zXtay&D(k~Qk%6JuAX8{V5Z4?f^r{% zlc+q)h`)eHKP+y643wHwoO3R^#fz-b$#P~IiK=Q1^NdiAWFT>yi5a29p{l0j$pwPJ zvaiLP+2Ue)c`e>dmG?RF(aVe=%Nw&Y2v-ZXhiyTwLCDOP-ah!102Wc=%@>s|PGfhKj20AV*k3{+K6AeRWvlScEwRJt#_f8);lt9pP zK=JU@`rI22o>4gek0#7(XxE=N^G_ORG}(U~>DU1?djqOf4UkSolMjQ@crbbYbv&7l mK2AsPzM)H!bzN@cjNg4?>-uwoMcrsQ1 literal 20978 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 SP7KeW_arIkRZQ>I`OQzyP5F`l literal 17334 zcmeHPZExE)5Wdd?_8$s;p3^34yQ05ipH>)x?MtnM6vakA6|w zKrj+ovPd3}&mHfMNB#TH-}1BkB(JugLMHMcOSzYktfiDkxy98=?r?W5g?z+wg9?ETqyC@y9mOC3;(-)&^V}yYIfQQC;Hd3+N~@%OgLyjf6_tiOD=%6I+GjnNp~F zY5~5~HRK#fp5c>+)3|MIQ|Fm&x9hh8z1Owg3VhGgV24t9i+(1UAJw&YZlx$OX4ToZ zD39ZB#S6;Tpapw_?bsE=T%%N@QqC2%UbENNIJUj7jP>@u=lOfl!i8fIF@pvh*Ra45 zjxatiow|bPiaEfw>iD&joss*sxyF*#ePz+m33ctPt7Ba|577Sx6f~(l6k{Q_IqGik z-PCnGz7;QplXqPwJkBWT#CVRZ<;qwAJl_J7D(#ilIh|Iw>a<+CDQC*Ncm-`oRcJ%9 z{;tyYw3X_-HSv75-W>WR-)?yM*4|-!>FquBUh}X`dF$=H0(z^r_lSpj*`>Xw)}C5j zx(2Fst5#ok*42s{yvG(QM?kZ1beQHbHMj4y>tc&Pk95L@As%Wc^R(oWlJpDqif>)a*b5mMiAn)8R0$*v*$ySeFkmZPdyd- zCPeeD8B5zs%IEWBC0HV|FTvlijkEVSh*RAy>pc#e79`KCt1a!eaF6)h`47Fv(S^rx znmBi^e{stAcJF2Q>_$o{?M++Eg}PwZI?vzZQvIxBi>x*Sy%@zMNvOO2{#oIA`6OW%^sR?~9=KF9UkS;MFE4Rs%@&z|q|shU>d{#`Um z56gWrT)LAD-?ow&ORG)Bs=jXJFPG`8d#%iK=KfbY;=wlJGSA04tPl1{J*j!hdhWuX zE8>Y4+K0z_aVb4PO5)PGBFFW1?UZ!ECwsw+ZOWw4Xc6LvWMh-s9g+W{$j4Wmd>%o|!@);AzD z>+iDM@=w5cPf;@(G~UCvDro%2zcu0TwLhcOPok)LlK%ict;t;g diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/c.tf b/inputs/gcp/backup_for_gke/backup_channel/name/c.tf index 1c7a84080..cb6e20b4b 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/name/c.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/name/c.tf @@ -1,6 +1,7 @@ resource "google_gke_backup_backup_channel" "c" { - name = "prod-backup-channel-001" + name = "c" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" -} \ No newline at end of file + project = "PDE" + destination_project = "projects/PDE" +} + diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/config.tf b/inputs/gcp/backup_for_gke/backup_channel/name/config.tf index 4a5fbbd4e..90318dbac 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/name/config.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/name/config.tf @@ -11,6 +11,3 @@ terraform { provider "google" {} # Add this variable definition if you want to use var.gcp_project -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/name/nc.tf index 6e20ccd02..7538ca453 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/name/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/name/nc.tf @@ -1,6 +1,7 @@ resource "google_gke_backup_backup_channel" "nc" { - name = "" # Non-compliant: Empty name + name = "nc" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" -} \ No newline at end of file + project = "PDE" + destination_project = "projects/PDE" +} + diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/plan.json b/inputs/gcp/backup_for_gke/backup_channel/name/plan.json index 4104c268a4131b668fbc8388196b0bccadb8c2b4..96933dc01d014df5a0c56e956ae9fe9e71dabceb 100644 GIT binary patch literal 3561 zcmeHKO^?$s5WVv=d``P<5i5~1+&ORpRo2v*q^6D?*-oLV`rnyxzSt!aDgvopIMubs z^YJ`>emRTM`5K};q7T|xk&E?mBQg=ud*HPvE9=+GH7zyu8rY#pm~q6#n9U+3%x6F~=OX$R z#U&Gic^At#l>(6gv{Vfk4GV%g?h!)dqj`!zpG=p-80y*_qOOr*P|}O0XJTG1m+Y#Zuz#j0lAC|KD+UN|v@N#O8G@K1QHNwosP2+My3Cmef$qGs%z{FB zgot9Bi5(KJ5>0hi8cMn&Z2O;Dm|7AXvb6{6zS3)yV0lijQWHZmLC*3jIl&0kU@_Uw zaZx7P!GQL4CnHCC6L|?HP?#>OALh?P)Hq-fNOkx^QeBpK%FsQmB?`aB!F*0uiX*Q#4W##bdo@&52H$Mq&(z0FsTpGf9I)0h+N_-m_s2$icFgCsD9htYcy8T3x37wq!t EJ3EF2ApigX literal 17196 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 diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl index 894abb857..5698484ba 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.16.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/c.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_config/c.tf index 728f37368..db82518a2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_config/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/c.tf @@ -1,20 +1,20 @@ resource "google_gke_backup_backup_plan" "c" { - name = "secure-backup-config" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - + project = "PDE" + backup_config { include_volume_data = true - include_secrets = false # SECURITY: Never backup secrets - #all_namespaces = false # SECURITY: Principle of least privilege - + include_secrets = false + selected_namespaces { - namespaces = ["production", "critical-apps"] # SECURITY: Only backup what's needed + namespaces = ["production", "critical-apps"] } - - encryption_key { # SECURITY: Customer-managed encryption - gcp_kms_encryption_key = "projects/fluent-coder-468700-h4/locations/australia-southeast1/keyRings/backup-keyring/cryptoKeys/backup-key" + + encryption_key { + gcp_kms_encryption_key = "projects/PDE/locations/australia-southeast1/keyRings/backup-keyring/cryptoKeys/backup-key" } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/config.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_config/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_config/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_config/nc.tf index b6dcedf71..9e43421ce 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_config/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/nc.tf @@ -1,13 +1,12 @@ resource "google_gke_backup_backup_plan" "nc" { - name = "insecure-backup-config" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - + project = "PDE" + backup_config { - include_volume_data = true - include_secrets = true # SECURITY RISK: Secrets exposed in backups - all_namespaces = true # SECURITY RISK: Overly broad scope - # SECURITY RISK: No encryption specified + include_secrets = true + all_namespaces = true } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/plan.json b/inputs/gcp/backup_for_gke/backup_plan/backup_config/plan.json index ef065b14accd9b13ae8e2fa2ea05d95e5a5d1d0f..b6fbc280834a741158dafa89ac594735dd56d3fd 100644 GIT binary patch literal 6758 zcmeHMO>f&c5WV+j@N8SLi!D%}yQf}?#hzLO0z-{uttnCV~{n z?uE0qPD`6Ln!+P_+c?Ez-}XXgnIn(yBDXfzl;#^sucX>ERrkRw&J>o$8dyP;(#V`L zR%BQ4i+g86%*c|(c!|o{ZIO{n+joxg!q;v$>us79Hd#x*E|hgu5|_qAuhvw`qrn#w zakQ}2S6Q96}htTzSt566Aq0wdD2i50hd*!i&jmThE4h*c6RVY zs^t}Fj{N9wOo?8aAK4FCqu6*vLAj#F9(sz+ytq8zXChkfbA)1!@!~MgBc=%ZDUNJs z`Gj|!c56&TMjl&-$aQwpY6ZL58=X!2kciVhlcrc?Tky$2vMvRCQ5+_s6OZoeA`5}B z&&i1`}+-j@a=QG#6$_S@lbm^{2jnP(_cVU3VDuTZ7pK_A2u(Hzu^A6gTBqhsF1 z{~XTw3!L)1BmMM~e2K%1qaV>ns@BrvX9hx|&J3bt=!l^~qJhhr1cGrz0A+n+maEYJ z_FaE`Lnm+OB>$DrNl5UtF&kt5#pPry(Fd*UCxRv!@gd&g>;fIOop*>SQL?C(xKu=m zqL&3ms3Y*MY?dn97~sMvG!Ack&1Iq$2@feMhv$1;oHl|Rv3t{PiSMz%;L^~-!v5M2 zLvii>xdr3t-Q~Q1;!AasHji)LbJ3jM5ag-Xu}5AMUj;!vrWRjIiV?cux$lp6Bg?l! zj7a=AcRxd^g}xEZHZIU&-2D4HbBA*y9TPdnmhJ1=ycPJ36Dh!OdH5Nb%xG^U6k943 z)DZnwF|W#;;X|R3xQmP2v$ug545(mcbx$PKPGl!X>B*rAf%-Wd`^t?HG8E^=1nEA_ zZ;*`pKoNIb?QrsUSjb32c5ESX@k#C)=OCf`kt!V7VU#??q?q|56BKiiI5d%H7!hEK zk&}MFe7`Qzd1SiFTZH`3;5I`BIOPsWPSZ0BIgr7lV;;y8CWui7$_f==ak2O?y_ioI rfBZdPEH6Id_bciSv%Ncc#bq~QL1oKIgQxDE@xLRG6u8F31N`oPsj07a literal 37570 zcmeHQ+in{-5an}${zI_Ol`pwCL4KicMW1RIf?~&x8(TIc+pQ7!*W1on>Xb|FjpTCI zvP=jGO=*`L4u^9m`R_kJ)X(ZC^=9)a)VaD*D|M|F>Q2qogZe79wYrpVm#R>o<+(x~ zsy+2q%3qv!@5-lF@-AEHYT;15lXeap+If%`R?_D}eNk7^=6ch!4Xc6qLY=Bxf%aD3 zx>0}18>a%jhPL?~^Dg?jQup!>M|ZxdFQtu{v~;7+%5lxqdv&BfsgLSFJ~Q=A>V<^? zw)$j!`&7fzt@N-Ed@iNkvl7dMp>L!Z-%U9)*Ckx{C4T%yx{}`3^47gz>9qV?zjtgw z%Q3iRHy+)m3mM;;d~}~2RiQ3Q_%BMR=TiGFaLi?v7Xs0Dfef=~*NCewp76c__jRT37<}jz@*rzV)AYQ=MzvMU*oFMQ z7AjlGX!oQ952&u{y^{~M&KE}1Q^iBH1JT>!<17|h4bMDp) z;bDHO%YDPX5-b`CRaR zRsND{ow&U|$eaQO@ZY&W0xDQ+dI$G~R+6f3NG<4f;Ox-npxMo(UX_oj`2w&C{SDff z)^rxKULesSF{(6A{+Vuu>wQyx8h$tzNT6c^O3wPRnidArZ&eR>DL=G67Kg0ka2)vE z@siJ;$(jH)(H=>&I^5n^FG`+pS@s8dy%IjGDHx+pIbZDYBx$RuxbBdV#=#J~23;ME z`XuNEoMh?&Tv^=NQ0&JMjyVgq1O8eD@H*UogrJMvdp-UJoPmh0? z+<^XgE*~u?D4FV3TLTj#k8j5RI z-{c5=b1ph8tAvy}3~2OO2(`GZ1H^5+5x6Vrj8bguSpV#6szhgQOmz+h>k~F!HB8 z6jMhan!E;6!(eQIVVa_!tS0@lj9pLTYh|`)mmVzJua&*coJXHBdz;&^wA9jWyWc;$C>jNRt}>T_BFNET+c1Zc`Z7&*W?||8Xf5rx%1i2 zX0T!Z<)^!MKh;cY_B*bpPJ1S+nep&PAh#JglO}8SxG`qc&B4a--}QU%hI;ED>8Hwb zH<1-uH$LOrF5ernf(*UradguKDIfG<^4W|P91?@kS!!RUC3x5UGE{smURb!`Sjg^Y z_7vmjejYE3@O+~=hG52EXdF+W-~12?x5TKX$+Gv;Z9?e99SiHjFv3M|;+DcoFwLR7Lz3-ZDd*9DnY~sj%{K3Ds@%_Ze{yB0)n)SY zuV3GB5|DkkWonLA$5mQ*UHF+-JWba7blL9BTDm*>zWPvZ7$Y;o`V8f`W5p9*Th{s* z+3Nn5dkkGYhu71!gZtK7y7&NEvUfew_8Th;y>4ZW6$>EG=3WqvY|O0l@p7xi_4&UH zsvqv#_g!gKTX`_`mF1%S;u$h zO4p5?Xo_USNcQG_%(toRWz(YlmuWvG^jU+qvCP_d8a&Qxp|2SGiQwzy{=~QpJ%5eX zSAH2R;2Z^^b4P5@k)GYGH?52r36=M*xQCq>0VIo3`;aB^T#d-aiP z8w;UnXI}d8aejz7&nvc7z-6Bc)Ff3PgTp+5h0IEQ=6$%AZ%=kqL!bU(@7dE-XLzUI z2yFeWz7sI(aO4pFW!B;J$thWf^QD=r!}(z<>u}9@8c&BCEB9v`{6Bu4@$RRZe{GZM z-O(M$;^){o_p)ti%Gxio0C8br{0UZ zCr(Evv}MT{bE*-!edWB0;qzC|2;WwHJx=Rumdq|4vmT1i@iea2wSO+hy-9&xWt%?P z_Rem_y~o@KN6j$DzT0TYe4k_A1{e6Ns;R#A*mtP>v@r=>*7cDbccvbVTvnfGf{WFc zssrW7VfZ=flw>(_$OvSP9BL``MWUYE50xW_E|2W5Pvud`60q)pc&!pJ$6dO0m*!vX zZ(W@fUUze58&2^y_jz=AnkiYU(SvGBUGI{+7~9F5>E9gcB#I9kA1z3`kwph zy0!27id$Fg6FS1*<&6wDeS!BePL=A+vF+uVrLW(mY!L(4R+ zxq3<{6nx%qw|iQe^`TLdlbV7Hv}p^(f^S*JR##McdaN;azFj!0+o+V&WA8pmI|HPW zuFT7EdNe(2dEUj{j|a(j_S9F>zL{pvz6%XF2yW=Yp2cZytRn;`qhL3UOdyPDS{pXf zI2dB38tB2k|1JK^c4E;-N^uo161>f46vxPfSh?A@^L-e1^qUd?z4g;#gfh>^^FtbJ zEB!D5xqB*lKYTUaH_uIr3ETQegAa@mcPpYqc5mN#hHaQ_`(EF#zLI<5Y4N$Eh`}Ly zi{rInJT`PKBf8#yOTEvieR~e$4$qbO&N*Yb+a5HZOnG90C8c7U?>qa@d{zyy*;a!7 zZQp#|nhIM{Z9VaOAE~pQ7O0yGt|cR6#hq}u6cUIyV!1oG+GP*NkaZX)eMuMD!hwzC ztE2Bbc3tb*KrpVUWnAfK6>5&vFvDj#m#jkD%o?QdQFjr;?BE4ucPUrT&l&tjq83UqJP z2Z8WVO8oy({Vv}fsn1e>C;xwtzyFZu?fe*M+PCt#lBgwTN4H6B*L@ziLC=`SzH@C5 S3&;5~`s{h01Z2m*p45N4HqT`M diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl index 894abb857..5698484ba 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.16.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/c.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/c.tf index 6e0d0bd6d..39ff6b641 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/c.tf @@ -1,19 +1,20 @@ resource "google_gke_backup_backup_plan" "c" { - name = "ransomware-protected-backup" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - + project = "PDE" + retention_policy { - backup_delete_lock_days = 30 # SECURE: 30-day protection against deletion - backup_retain_days = 180 + backup_delete_lock_days = 30 + backup_retain_days = 90 } - + backup_config { include_volume_data = true - include_secrets = false + include_secrets = false selected_namespaces { namespaces = ["production"] } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/config.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/nc.tf index e14e250a7..3c309d518 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/nc.tf @@ -1,14 +1,18 @@ resource "google_gke_backup_backup_plan" "nc" { - name = "vulnerable-to-deletion" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - - # SECURITY RISK: No retention policy means no delete protection - + project = "PDE" + backup_config { include_volume_data = true - include_secrets = false - all_namespaces = true + include_secrets = false + all_namespaces = true } -} \ No newline at end of file + + retention_policy { + backup_delete_lock_days = 5 + backup_retain_days = 3 + } +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/plan.json b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/plan.json index a104c8e3fefd77e7175162406599e35db831c822..996e166d29e4479a81cd18f40d83f73a913b2670 100644 GIT binary patch literal 6845 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 literal 11018 zcmeHN+fExX5S`~r{fCOjs)2;kQsq1PRD@P(!mYq2%7qqH{CeASe0ErS39y@j+Nu@` zo2>2ecxF5^XY8LpzT1`^+tlWEX(L-&VOMs9Ukf|K+Y+rqdP6CYr&vUdESo;X0&q0MNPJcO%+vp)_iw|Ep zbyVVW0!ovr$I`Ar$$M-*r{*K|%Uf#Bh4gX--AU3#;G*uwb)TSh0ol#L&o-X4qS#8d zgGKE?DEHHPM{jdXyQ_RV|t{qMa;*+`~huon(%t}jN1}#uyOYGwv zjEp(rSn)FnJ27sP3}`Qu9QXa~c22IO46?omvN*yTj?t65{w#Q)0`t&M9N}5(*6pN+ zeog!8Rh-aD-Fvy@>9yvVkD8S?Xi|^4X-Y_PZ!4p9`-nOpV}9p)iq} z&m4R1#{V39n164Q0VwtyRuPDKY>JAQ(K5#`14>a;&lpK^dRmMW%bA&+vH|7L#4IlR zEog*VV$RPD_^?7i%wdSYgm*miVvHcRS3c-;Q@peevv6G6>uzT2XgQ-QV%v+rb{=L(jRu2Sz=PjR15OwmNwluKHrifv_me@30u@BeOeXk#y3ETM~@+DbVi z@VHJ)3Fq8KS#F!$CS&%rj;!dOYsIYZXUwk1wFzdAqgBpqm@(zdM(0U6v+0)Es74TH zay-4NPYo$gW`1{T^YIw(<>z*Ow#t#|NpsqRmV1n>`vQN@d)BOT6jo>Q$$y;D`5Dl| z`Ypnp22~N$`woieNA@jPh;Bvrd9zzZiW)Yp7SWbub3#%?YP>Pvw>vo7{pa+;Ma}b) zHZ*ITL>uz`lAeHTk37zur0n-z{^m1%$!pySc^jE^srP86*h{pVq1#!z>%V#0&bf$c zcq@TVo<`D&X-xFsn{;V%K45vHtPu=fY5`#0cG51o%lbIN!nr;!byKm`P zmDi#bnJrnL-rTOe!(FHWo<029w~zSVhj;Dc2ImlM1N(&D%mham$D5JY_@Yl^Z)<= diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl index 894abb857..5698484ba 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.16.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/c.tf b/inputs/gcp/backup_for_gke/backup_plan/deactivated/c.tf index abec5bfe7..215bd9c7d 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/deactivated/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/c.tf @@ -1,7 +1,8 @@ resource "google_gke_backup_backup_plan" "c" { - name = "active-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - deactivated = false # SECURITY: Backup plan is active -} \ No newline at end of file + project = "PDE" + deactivated = false +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/config.tf b/inputs/gcp/backup_for_gke/backup_plan/deactivated/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/deactivated/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/deactivated/nc.tf index b0717a294..e24771f16 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/deactivated/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/nc.tf @@ -1,7 +1,8 @@ resource "google_gke_backup_backup_plan" "nc" { - name = "deactivated-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - deactivated = true # SECURITY RISK: No backups being created -} \ No newline at end of file + project = "PDE" + deactivated = true +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/plan.json b/inputs/gcp/backup_for_gke/backup_plan/deactivated/plan.json index 751c2ff790104caae843e53f3676e226e85044ad..8d50ba32e584e0c372a90aabd88e07f5735e5837 100644 GIT binary patch literal 4606 zcmeHL%Z{5c6y5hTye1)}52;zV`!2d_H9{V9LuibRY?C&M^6xzt1DPtQnsi2;NjodR zkIQ{=jt>X1wyu^T-;wi`HDV>Q`BEezkaLpfewoQ$&ofLmS{g$|zLUBoFIETPtPOc> zi&j(jNZz(i@!Z#gkVWCh<6e~3mYVW%OZlx-+qM}lY;mq&8a7}-)Y8b33U*}Q@W5|( zVwsUOFJlvpv%9Jwm-l0i%E||~pN}!kE1Pbl-&D%FCXJ@C(W?#B@)YnQ5vK@yf0Z@s zszg{fiRg!TTMV2Bm2N#=1Yh9CH&Vf;pFVs{wN)}8!9JCkcT!h!h8%?rNguMb-{n(m zDrSR?L=+@dsCF_S7pt|@o_NeFS2b)+tW2wQB51wFo2nh=#23I{9 zUv)8FUX+Raz~a3_O%pDA0iZzbLfxmvov9%TChje9g4j!lqcgi4BUiTkk%X`7AV+WL&s2N&B=y z<|<0YkpAcu13dq6$+{yu>tVES-Jo%oi{-o7BAYGWe$JMw#rswE<_i?KY#P0nxBLqx X(vq@uqan+OXZ+K_(RlciaD4R>O8SJz literal 10120 zcmeHN+iuf95S?cvej?B0%B9fn;E5`-++5ny#EEh#RES>(&e`Ls*NIaSNTC!fN>h7h zXJ_ZObJ_3TzF5P?HnW9IEwz;;c4H$vE$s?#GmM_%+qIVU@cRPaRTy6Y+UM<_)3ukF z+0AF(V9o+~Q#-c_uq^TZ)JVaF4Q!6J=NO;aM~n@yj*oKQ#MXE#YR36f2AC!wXEqEp zHSLwXvA1?&9ekR0iRXrW#fNmyF)PK6GQbYQJ{@a82Unj3E=&W~b)eJfSYYN7@7JJm z5dP=LS=d1eoI|`Pgz#}!#C8#IB>26?Xo9_`n0*Z_+;REIX>0*P+!h_abIK^g_X3!P zImF6tfyp6$eNC-L?9)4JPKD%h1KEkwNuZ*D`BZH=1VGT*EA7+-Je6=B@Ld}dJ z2Y9m%JL8TxLS2gWbcr1tqLXc4oMC^oH(41mr1>i3*#z%XXt1^983y;AgBS zq*^{i^U7MFl@HMaVWI6%BJ^g`2KvDnR-%R627aEIw07I79-8;0iFQt}x5}mK{Fij7 zJz0>V^o#oNC+u=RJrs?{=P^$e;-;n_+xKUXyL994djEos+W*t{K0W{Mp0@V>9zRu| zmGwDLp99m%I7jC|KR*o`h+N7!LIPjTh&Kx{yP~5yV-TN?n=!l~xnZ&D6*jzJwN=hd#4thLl<%g@i2 z!U7ZIAsMPC8Eozo{<@_f+aeFiE||ZuCPP}{h>F#c&3B5V=}nkFs}jX*j}y6}a9Tj-Br(EZw#XOzLW9)D0x+5i99YNL6K^+~`(LtPp z?TRLzZgkKOeU~`PWCyb79`R)0?zgM7@f?RL_u4eGoSl>*n7xbZ}da zUD!A(@@~NW@=Zd2S^c7N?^(Tsk$nytq7Jq99bGH7V-0GQ^hbFE^OCr;^RLAt%1f$G z*@6qI6fuLU+HXYGzeA~&Vhi1Og`z{dJBko?Y1Zbw3r6GY^zxUzAZiXd zb%wv}@Ga2i-*t1NsEB%ReRn6HG;mMCEckc396|16vorO+200 zd;H&lZ|m4Q{O#c$*#|(Y`aj3a32tKey)|NSJt72cnAmx9h;^UMaovRCT_?Ze5}zZ_ H?V0@mb_OH8 diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl index 894abb857..5698484ba 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.16.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/c.tf b/inputs/gcp/backup_for_gke/backup_plan/description/c.tf index 87204987d..18c7421bc 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/description/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/description/c.tf @@ -1,7 +1,8 @@ resource "google_gke_backup_backup_plan" "c" { - name = "backup-plan-with-description" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" description = "Daily backup plan for production GKE cluster with 90-day retention policy. Backs up critical namespaces and persistent volumes." -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/config.tf b/inputs/gcp/backup_for_gke/backup_plan/description/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/description/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/description/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf index 8d591462b..16bb977aa 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf @@ -1,7 +1,7 @@ resource "google_gke_backup_backup_plan" "nc" { - name = "backup-plan-no-description" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - # Missing description - non-compliant -} \ No newline at end of file + project = "PDE" +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/plan.json b/inputs/gcp/backup_for_gke/backup_plan/description/plan.json index 276c68ce81f0ab5b2ec210cc2d81a7c186dcd791..feb61d302d619e989a11ef92e3e8a1f0efdcc553 100644 GIT binary patch literal 4902 zcmeHLO>Y|^5WV+TAkO}-8YwG^*@)EyB8z*1K_54Z$GSYAbFWo(%Yn zhmF0`nq{?uTZ;j2hDad{0UN;<*zrxt7{;G2F2~wR5dm-*3(R|=D=`E{ajis% z({Upe#t*CTY5fxvc)+>}+beNn`Vwp<(p=|-L zUE$exg%t9lHXCEF(Th(HeW@s+cE}_2Lu!Y;T@=ShMS+V&UQu;xQJW*c#cj*kvXHhm z=!AJue_IKWQnp!=J_=-UpbJD6>*7R}|D5ba*9iH1DRhA08HAt4PlutW2xF&y z7y2xGYOV3f){__1Ghfg2gP-XI7*nEDwNLzrDrL6bJSg1a>tG}jLUbO7V(V}m zW|P_3a55dv-hH0V=9BaJ^y~{B5QKAjFRtjRD&L5t-8zjYlJ*;KU%2e!3YM-t$2UI! D**x#3 literal 10790 zcmeHNOK;Oa5S}v<|G~-`w@G;vdPE=&TscuymYXzfY2rk2(h?#5I`Dn_dFyrJ6bH3X zS}RIo?_+k}J2SgKe|)o!4Q*mG8(V5~OYG84@Rr*-S~K(>;M=nu+r$4eeCMuzhS7fB z<~cokj+wn;<|XFL05`Q`8v#m=_5&jZr`ESA)}Eq&VqehL$2z{3^G3EntFRdsZyCnK z7&) zIocP%vhSYRbLc2Y0ds(Mju1RjMQEoEMuPtf^d_J^#q0|}A;r}?VkatYaq(}}~P97noO(VK&JGvKp>e`-;vB|A=| zb|IA%gJQ)sZXZSFWhuFYXf zyO9AG7`LS3PD(0V2dPn%sPp#^PZ~}_b>b%wLmZ5KxCQm3~srB1kqCfi*19d|7c>J_~iefzwSxR;3}mZLXwlI2+G z$lvfj&2&>Z-ae1HcM>+W|F(Cy4E847__uppiATH3$yYwKUCvuFy;(DRDr2{Y;_EZ` zw${(LetujV+sMx!UFS;NNy1Dgfv;xVp1I6J5mB4>bX+WZyLnH@XCHSmx~1kalkvRo zpp8;u4#9jykrQJ|W#!6YLeIy1U6GZC8^(o{aGNQ$nNpi6`PxjIDb;1Jzu!SiKa(Jv z%8`-+9Xr62^6uu5pE4;{C|G4%g~9sQYMZhKu1PPg+9ESs z))?ti$ph6gLu|Im)fkm~KVPM(>`98XJ-htGw*QLWbepK}g zRWtn=nfy$31Y_c1aqe`t=easVV6~(@T@Pa;fBtc^d=qzXUh%uaa1?r%eA9pU6}V%+BwZbkB&D>u#PeeCDp;$q#|b2I)mKcCi0 zp=WBgLYOCRSDVp_RgLyullckH{`t?7Kw1&|4)IHynBkVdrrSwnz1-g)*?e1tIFQcA zc#0bCR;@R?`M%EoYlkgX;o@B#RrDA^@jj8N=FRRR`e?{k zQdPqnV-MHPyNBCSd-f8iwLSdDc-yy6c<#b0>9>npj-N4_5nPISywS77lWtWKN?7}& e^$|MnwXue^+E3rd$c!FPb-%KT_uZb_6Z-`%%brsJ diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl index 894abb857..5698484ba 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.16.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/c.tf b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/c.tf index cc4bcfd9b..86db20624 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/c.tf @@ -1,17 +1,22 @@ resource "google_gke_backup_backup_plan" "c" { - name = "cmek-encrypted-backups" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/my-cluster" location = "australia-southeast1" - project = var.gcp_project - + project = "PDE" + backup_config { include_volume_data = true - include_secrets = false - selected_namespaces { - namespaces = ["default", "production"] - } + include_secrets = true + all_namespaces = true + encryption_key { - gcp_kms_encryption_key = "projects/fluent-coder-468700-h4/locations/australia-southeast1/keyRings/backup-keyring/cryptoKeys/backup-key" + gcp_kms_encryption_key = "projects/PDE/locations/australia-southeast1/keyRings/pde-ring/cryptoKeys/pde-key" } } -} \ No newline at end of file + + retention_policy { + backup_delete_lock_days = 30 + backup_retain_days = 90 + } +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/config.tf b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/config.tf index b9c23f44c..7a9f34a60 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/config.tf @@ -1,4 +1,5 @@ ##### DO NOT EDIT ###### + terraform { required_providers { google = { @@ -8,7 +9,3 @@ terraform { } provider "google" {} - -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf index 664a6065d..fa96c7526 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf @@ -1,13 +1,21 @@ resource "google_gke_backup_backup_plan" "nc" { - name = "unencrypted-backups" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/my-cluster" location = "australia-southeast1" - project = var.gcp_project - + project = "PDE" + backup_config { include_volume_data = true - include_secrets = false - all_namespaces = true - # SECURITY RISK: No customer-managed encryption specified + include_secrets = true + all_namespaces = true + encryption_key { + gcp_kms_encryption_key = "projects/PDE/locations/us-central1/keyRings/pde-ring/cryptoKeys/pde-key" + } } -} \ No newline at end of file + + retention_policy { + backup_delete_lock_days = 30 + backup_retain_days = 180 + } +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/plan.json b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/plan.json index acfcc617dc8104c10021bdb5a945766dd6012cf4..d913691ee2057c57f2e1a4cd8192f7d37c0fc4db 100644 GIT binary patch literal 7397 zcmeHMO^@3+488Bq&^d{d4ECcrx2Il;#h$hp7#f*z+}M&K*=d6y|9u}N%d-=E1`}Y4 zW&oe!SQJH46!rLg5?f;{*`x=ut}t3`#A>k?GtrQ>lE)!%V6N(PU%B*hh%Nm_s&UDekDrp# zD9O`YB3qa%%R5{w{Rxk~*Wg#Z%(fF`wxe-tlVZ`w_uViqcFrG7i;btHQbBK)i(rqi)L*;h+-6VVh-LmqlkB9Kss?5Qo_NpO*50 zO5X3$VL!mubz$UChh$-S80@e)*uQHc(#>*7b(}{HGm()~w(uJe9iit$dk{f zd7lt-pEG;_kaHWs5fkT`h~gn0af2W*wnKv?h_aBxV!`|#`{b`DdkWpBGJ%WRdv@3jMUP|=Ky#0D&EBYMx z>FF`Df3STlqR&L)FH3q-4~+P%@wj1wP>n8!-{;f^(Q9ZPbfgEzorW0 zuesCJ73dyC2t_LZqg3sr&fgh63N|yolekWSRB+o1fDGA?z=iNYz>7V4kXwJFpW;0> z0jF_f)ZgLb!xM12N#NwOJ8kt|o9}3v#gi&*Bsr#w zA$`hry~)J@yd4mAYyFvK4AS!r5o?De4wP(1hW2FV77Wmp45@EmZjtB>{sz9aV~Rn! z(T|#G=g_E(Aq06r;GQ_7fGQevI5XP;sW3u%J*PX=aTTZeI+mC5RpfJfns>M|<1APo zC7&?A&q%Z8$fY8qF5_{PFJt!!%z30yNA!;ptC$qBcVvQMo)(E8xQ-D4re7g4idmoK zUx#|`mQXTA$qq$9(w^@jJ@}mPYth`hJS5j6w&`rd;w8WX-rV6}0`ZyC;R!MZR4Bn! zjV~wb<@%5Lay4K7{?BT?S$^28{`?npoxe96uIN>RVBp$0ZIW@|L)xI&S8w}&qFG5}J02U^ ztkVnv$DSF9qR5{VMRET5`>${iF2guX!hINoS*XHexX{%!+~{ttr>FWHhr@89@9*@P z#pe^X_I~U89Eb1K^LWwoQGF(&I|#prJ5ibH{%L@Nt1t`?8v8-d$KjKn4K#lKgxwxv;rl*$UFp50&!Vlrc@Kg90j`Y_H*SbCkpY;dd59&40jB2$V#d$i_#0R5~ zqZIBV)p_L8`IxBZRQKoNau|Q}S?9957hfsRG4vj zquk>^( z*-gaHp}s*;j*`QOsJ^r^P`hhgp}C28@2hW;l<_gu(`(US#;fpk6m^=Ak#tx}lrd@{ z^+sdl+Pafg(k!Op07)%7k6Xvh0PjIP#B1B(*fAV(t5fEv9l;mBtMfq_80vBqBgZ8L*HC(y~T5^mFN9T z0^{(rX7{wV4;FVGB}d<(_?So3RO*3UgO!1O*!aZYb=R*4349mIa1 z41ZvD4btw_8_Tfq^uE-GRqknuZpe$#O5ZlZ2c~H1KTD zx7nR7mt`KnlS6457NlzY8nG4 z$dxBw8>=NpVAX7A6umzPN!%h2d=xVTy~$>qNVpLCF4fXx#;UihL0g;5H}w`0$$eUH z!3mzxS4{KFNX=1-MZi}RA2}|Y)@*WbYtO5FH+FL?8I`^W{(6PAgRX?5eDx(Zu$8yn zS_>7kZ^m>ivaVyvSeW}vv#aG*;!EoQo{)?AM6)Z`gJ}tCt)n(+Yq;2Tohc>1dhKuv zUG@@h$us4iJpJC)2eq?J)7Q)6jffH2SpQ4Mb*zYHZTSjyAWXh)WS97OZ?T?D5`WkGXJB+Ey2J>{HZXUTxnaj$J&+K12@ionn(b zV^nF?ApgOh+H(zE{>b(WFPlHg<&5{WST604(~jEKad!UfgUvG7#anjM_Qt+LU^OG} znfAueE!Vd$`V<-5ri)7G+m76)*)cB(t+lwq5=lJgDD=$bS*J!{^x z>rfnzJWo}Il%e#>EG5;>UqCBI;n|G(i)c(A+Q{ygkYcZdn z+3!#EzRr&K>y&sG-_b?j)SeJQz26A@|BLSZh@wrtd2X62)>QAticOroTn&)-@m6KM zruFoA!q)z>1^cd2L2MQ-7ij=GU%*HqV?a?{V6U z=|1&q;jZNR`Lhhu$f{b@b~9~XuWBQ?F5QD{w&7u{-fUadYNM2P?_;sA?&<1d_*K7;6kFQ=54!)GTHEQ7z18!iIoaEWP;u*~ d1@-`S-hbglqWRq3U*iomf1@L}<8Q+^;a`2acr*Y2 diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/.terraform.lock.hcl index 894abb857..5698484ba 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.16.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/c.tf b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/c.tf index 3b9b3b412..c013c2253 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/c.tf @@ -1,14 +1,15 @@ resource "google_gke_backup_backup_plan" "c" { - name = "secure-secrets-handling" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - + project = "PDE" + backup_config { include_volume_data = true - include_secrets = false # SECURE: Secrets NOT included in backups + include_secrets = false selected_namespaces { namespaces = ["production", "app"] } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/config.tf b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/nc.tf index 02eb5db3e..edf8b6b2c 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/nc.tf @@ -1,12 +1,13 @@ resource "google_gke_backup_backup_plan" "nc" { - name = "insecure-secrets-exposed" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" backup_config { include_volume_data = true - include_secrets = true # SECURITY RISK: Secrets exposed in backups! - all_namespaces = true + include_secrets = true + all_namespaces = true } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/include_secrets/plan.json b/inputs/gcp/backup_for_gke/backup_plan/include_secrets/plan.json index e6c2d4f3c2b47d19499824d03eabde82b3097675..8e014ca15cec4bff3341b25db957ac6ca2095bc3 100644 GIT binary patch literal 6402 zcmeHMO-~y!5WV+j_?!=ts+GvOz4y>l5n37VB-zGmuk78lQI!AQH@0^vWI+LfLIgsB zWIb!ojGt$oA6qfEu9S7QCg%%l#7s;^Q!x-VIVXAS&dB8RXoA5?OJgX{)>1d*#cV5_ zwRKk7ywMcClDCahJa)AeGS3}(d=?997n-ugin1H2R!!CZ;TcB?Q)3RyAWCWEf^v3b zQ}KgG--MZwC7baSm9y(2CzqvXjuwTl-DcFqG%DY#;HD2^;Nu|6E_+lV# zBTW7(Yv#owhNX2_!dEgxY8tHvf{b#Tszxre6>VU6JrIRay2&Z?q#V^q#9V4mx6jvB zHzj4ctfiRMuE9`6t}MJS*2HN=XmNH=npBO{%c|0alDrNl8H;p79Cq+2)AEM&gTp+q z4T)R9jpA9653C`scla5I6g_7s?lG^3pgeMlwBxnk@XL>XeEUAuHu*J{71=}N>q zI{z&+-f01Nc&A@}$ggqEQ57OB$kbAr#hI~#=rgk$85$(FPl0|eYZBM!kOa2W^=UZ| zjd9yH&JWt~K^p*)R1XD%Y6-5L zI$>vv=3Pe?T-iKRwlSb<(Wswy_?i!CG6`QYoLkS=o%mYMzF_sHNK4{#JlU-x2n5@Pp8O7z35?xPH&B_F#Z zKAi3&lv?;3nPlUF^uvw6yUMm4GajWV#3c!=lep#(9iFI*1>*h|<-HhhRN0a~2)%~> zRxCC~U97Jcw>RoejN5Wf!3qpiP!=>(Ye&;>P4Cp`eRD48utfW~-x?lE9NjnTBHv!0ehJQGLqp8UHX zaKc54qDKIC&+-twu_}9J06`aiHbR1az~U(mYFR;@onB184lgFd>6f3A>FnZiHo5#2 hHEX?*H(dQ9&r-ImG&J1yJN~bMdpd}HP&Rj;{s9c%CEfr4 literal 7546 zcmeHM+fLg+5S`~r{fRs`gwWE`d`F*(kmcqADTx#1LW?SXz3n-BJl(aEfP?4*l7&Lz zz0A(_%g8NT1)vkCJntoD6}_w?;O zcJ|Aici6K6-Q2#}3{=(_9~e2fwxKO?_7d|8`;NIG&hc69o7onl;$~7l6ZXgFR?3!LUf$D@2b{k=k{jk>UFmvl(R1vHKQOC~@`4c|5@iXC2PI$e{4;ePsn7pWb1r0;JJ?Q|&H@*49p%2p>>9dTfu9q6(~D9sISC%sgH>{@ zyTKDJw*v1y?2VcdA8X9sfCeSr=U=D6rqMH^4XYaE83jCbiZfDc&0v)%#Ts1DD(;g7 ztiu)bn=$qegH%gMrKre)E$>T;S7F^WtfQY&M;T|5 zF87M4rwlY0$E1J!Zr{P!-=*!dj9EtH2+~smMPox(_<)^p&JFk}<_o3XF~LiVsT<%p-d^u)My zP7y*cql84%=$Um77(<2$R!V=w_Fc;fffa$>QX^^Pc1une|DG3wKh&CgCy|ymsQX3g zk97@6?@e{I51|xgMC5VMY#MXS0L05t(0maPKrvL$GR%S0Fk`(*P9YUVwstrwEJF-4 zwyM~$i-!N(3XB#a3A2^sk6S`^qUMTVPp*|`JQq)!V&pEeye2$K@jL#0E&?@+Oxfz? zeT`L-kTaf;);1Y@Skc2;!x5QC(N;PyTj`{FCLT)1G2glFI|1v*&_B_HnNJyye#AOT z`ORaTbF9!~ek0v#er#)_wl->Oqqa8UO@z0jwlm*)gfpU@xOSrW+S?COOcJnKeE8 zMa-7;1@)y;ZjPzWc-!*~UX>}%WFedLX6PNb^fYDk^nSMQE}^P!i^{$#rN()0_o_ji zit0^(dWjWowU#)vzG;2YM#b?_ag4toQk@}(8 zCMREFzjqEF@0+Hb(|U(d@%WSu{iN5>GnFOwbs(E)mAC0;om}sOx(yxgp4O%OxOp#A z63NzX0Y8n=z`ifP`TipIa5^ClR(MBq=&jpT=nWA8y;3{;7RGZKW9vEZ_E_&R5{c`o ztd8x)DmO_N-t|<}&k+a84`+BEcxLD55cl!j#nWf|g5Q1Mz&V}jCdt-kACdpk# diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/labels/.terraform.lock.hcl index 894abb857..5698484ba 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/labels/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/labels/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.16.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/c.tf b/inputs/gcp/backup_for_gke/backup_plan/labels/c.tf index 799db6824..dee6409bb 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/labels/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/labels/c.tf @@ -1,14 +1,16 @@ resource "google_gke_backup_backup_plan" "c" { - name = "backup-plan-with-labels" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - + project = "PDE" + labels = { - environment = "production" - team = "platform-engineering" - compliance = "required" + environment = "prod" + team = "platform-engineering" + compliance = "required" backup-frequency = "daily" - cost-center = "engineering" + cost-center = "engineering" + owner = "platform-team" } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/config.tf b/inputs/gcp/backup_for_gke/backup_plan/labels/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/labels/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/labels/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/labels/nc.tf index b6c3d25b4..46ca75e60 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/labels/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/labels/nc.tf @@ -1,7 +1,11 @@ resource "google_gke_backup_backup_plan" "nc" { - name = "backup-plan-no-labels" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project - # Missing labels - non-compliant -} \ No newline at end of file + project = "PDE" + labels = { + "environment" = "prod" + # Missing cost-center and owner + } +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/labels/plan.json b/inputs/gcp/backup_for_gke/backup_plan/labels/plan.json index 3ae766578c580d1c940799637b5c6cff98045c75..3d96dbeb57b89af288db8a3beacc0b58d59511e9 100644 GIT binary patch literal 5834 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 Rc*p-T7(>mYBIh`vzDJ z+<*3*I|>TG9HN~g1dmh^+Qh-g@w`HB4%!RMz5*0dTz~U8wlPB779O5*%BaM50!YJZ z#M*8E$&YyWnp%(0XTP9%EF_m}$WENj9Ts66>7Jl>1>P-zPa98aQLH6xr%@e9rNFog zyisyX;NHR9z$xLeLhl7&km7Cnb>d_iG$Y8c&QY#WLQ^lXhNRVZGwY-LYC}kcni-EA zpk?DIBSq|?F2#Df0tJWYWCsxEppW(@D6yOWW3t6Xe<&w$#DQ7$eRV zK0{{>ai4fenUO-;-s0Dqq@;B8P8~-^pka)Ww7g5_1#+xITOHvU`0HhrVO&$jS%nET z#d{EGD!E48kQK`!o6uuynj8|}_vO(xT@E~wC1y3-Bj)lC8Fah={!{3&;MAopOb(H^ zpwLFhF?uaYo&Ii)b!Z7(i@rqKd6%<~EeqmAd!~0=SJL+KkhE3~cS<$r$Dgpj{q#~e z9-qhDJqVk-)Ukbh3Asx*p4Q6;Jf!K#&nG`0qL=69=abK#VoymvyI*ooT<&?_foc zsVK?Atw;1J?r*tVEyevQ?pMV_c}p_~`+eLWEG zSncScMHwVLz#(}7GcQ(6nlM<;XtqgT=v#<^YDLV`STmwmArDlWim^E)^I#tDJzbrq z(34mGkQD%NI$lklFRrd^%MTR;Y>=_lsZ=}jdhcCxcw%Ozadt<(jDaU}|B>^@u_kOE zPyc>wKYWOs50S#YJWLs2ToELPQ;gv2H1$dxEhg0lS@BLe0})ZeX`#&i5Ae`ey(mN>J1(pDeA_;!p)la-vuJ!?~So4J2F z`HbTnUzxvOzPUTo)!9v`m`cjZQNB72(W$UM>+@Q1H+rC6NPmD}kw#DO&akEc?xk4-js{|$h@-v)U{hu-q3?Wymukc}RGONmu0)=Ri+t3Jd%T=$mf z$M?Ib?>+R?AP^X7ZL6k8ft1`DhX1{@Bqb*mkvfl}ap6-e zakbiAj&_HWy;vGs$tK&9b*0f_A!d`g7>S0gmArOuW%hP5!(y$Z)>LF$sakSku@}~u zCaX-*D)N`)OlxyqyWR^~6qX!*is1vn>mjW_`9-11oUIR~2vPYM@06uqN10Hf zqRshPakx1k!rpCfl__~kid`p{{Q^H3>%z4QyU+GW*P+_sP2Ul)n|}H9d8$kdcq*}O zr7GnZKxx(_T{D};r`(jo8+SfNq9B*s($`chVwIOmc;)JJVeUOd#{C|TJq#GrfYCy5 zRmEW>I`iPB3kU|Ohz7XgRA7r-u!OB7?KiqM*owHNQjw9l=K6d2dw~YkPV3& zj9UUJ104wSOD_GC-FH*?!cGDOy0DYeN9}36X~0fA^s-iOwE2N!Lkfbgl$sR8U)B~M z6o_G%jp@cijReyV7G-Y>j?e@OUYjDzO{+l(gHf8^xQ4&oXyPw2e9n#!Tj8+;WkeTi zyI10O`08Wm54uoB}bN`I?Azk!z4O1mLH;#CoojpMGLLP_bnbR8Q6AzsKggjn) zdUomQy>9Uo;pYWi z4Onwzm<~khe=C%oAwVOPUkaa?)Ny0I`kvf8FPfbxGDCh(gQk~b_~?k%Q`Jxp=U4L& xPePTq1q4}3E>Rjr_}ch~rD6l4#a!9sU=^9xXZ#hU;C literal 878 zcmbW0TTjAJ5QOL1#6Qtz3luLHeuq!KkP5V53T?_IA%?%MesjtRUZOFkY3Mn-vpX}p zyuH3CQK4F`R?4;2M0?FSZM5WeO?1qgsiz^oSG?O0Z^@3hpD~%PL1ri99!yK!Tu-W~ zvf+L#GblAxL+^%ot!H9W`oySlm3G{AY>LxqO-@Q?ty$od>PC0E*GL1NR140Djy&ew zfXY#{CU+Ke#;Ru??p_BMR-x)H@a%ZRI_|ed`x4eW_}aCzS60)h*mK+Qngos!6IGR= zSNWksLfxD>M4g{Atf8P|#WVSm*@7wQw}DHm1D=1MQZKOV<4R86f|HfBu?MVUFO1c?aS2y3kPc(A0_jb(6?OlUQ-q;}!qM)P>#w D3VN8g diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/.terraform.lock.hcl index 894abb857..5698484ba 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.16.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/c.tf b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/c.tf index eb4892631..5fdc4172d 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/c.tf @@ -1,12 +1,13 @@ resource "google_gke_backup_backup_plan" "c" { - name = "secure-backup-plan-retention" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" retention_policy { - backup_delete_lock_days = 30 # Security: Prevents accidental/malicious deletion - backup_retain_days = 90 # Security: Meets compliance requirements - locked = true # Security: Prevents policy tampering + backup_delete_lock_days = 30 + backup_retain_days = 90 + locked = true } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/config.tf b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/nc.tf index 1f9bc3434..83cfd7b64 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/nc.tf @@ -1,12 +1,13 @@ resource "google_gke_backup_backup_plan" "nc" { - name = "insecure-backup-plan-retention" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + name = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" retention_policy { - backup_delete_lock_days = 0 # SECURITY RISK: No protection against deletion - backup_retain_days = 3 # SECURITY RISK: Too short for incident response - locked = false # SECURITY RISK: Policy can be changed + backup_delete_lock_days = 0 + backup_retain_days = 3 + locked = false } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan/retention_policy/plan.json b/inputs/gcp/backup_for_gke/backup_plan/retention_policy/plan.json index 0d6354b9c23d1b899f81efaa0fc5b064ffa16f71..c91b360a2eb848d6885ccdd22a0d9e7dd986f964 100644 GIT binary patch literal 5064 zcmeHLO>f&U488AX=1Df-8-(jZ>g`mhx;zgDWNzN7o`R{wQ>|{gSB1MaJDRPP< zQ4~p0e0WWHY68HZ|bW1VU0r#)zASAqEuF`C}%@<6%RbQ z5@J@BEXFD-@3uuwUbbVNRz-+@H$3_@EZk_V!n)ATSEHmF3xi%$sZI`$GjZ~;wO2d4 zELL#qArtKoFH4T|pf+{DMz95T{2(2}=*y?iBjdD+2yhrF%zI@DH9(BwnpB9BQM)RP zuqYpNIx>+{(7vd6rI_2=m`u=e39ZGJq)`hpP59Y`!O^`z69GO>L~t&muSpy-(TOKD zok0-jv*;|O> zv6XD(0pUA3@m%j>Q4->b?btuK8_0&DiPQ5Bu_wmR*yr^lHXja$?DE97uaNnTj$7)# zYU+0}eL?O&lKQh#<}Z~A?=1Bnko~wV2?L~FE4#WfC`dLllqu9&lx zltq<_z*DqPmCL1ewFR~&p~pZbM9#fdsQDw2j)D7vw6F&`v47oditm)Q@(7G#-qfB< zq%iz3et95X11YZyDsQEMyU>f<$7{vVTWLUB^7f?xV4L8y_6>jHB7N*~JD}aS^pGc8 z(sv|vOR#}wGQp;M`5y^w@>gyMgsXEI5c8{IdY!tI{fU6$6OBt$7VMshI@Ta^FQlY^ zk<-=h*`b$9Vo^Glo&}nzX=@js-op3II!=N?Iqh8Xcn1+HaT;X+Qw(~pDkWH7z^ qI+@PL_w(u9H@vT?sxmvZ;K#Jo+-X-<{H)Ub$Lkyj2>Qvi-G|>M{4VeS literal 11138 zcmeHN*-qO)6ur-t`V)C>fRMJdd`F*(kmY6pN^qhqw5a0O+nzJW7mu9)HcQK5Mc~9U zbLVbz*ZK4NmvwAxQ=8kFrM9%h&TWKW3p>Hv45Rz_>)Dp=;`t7L%P>C2Y+rZ%nx6Hs zvX`$s$C^3druNMyfU>~*eIo`(Hn17?o?(1y-!V48K0eBI6IsSGR)~>=G2A( zr>?!XkM_y-YzLpN9piV$F7YAWGptHMQHHt0K&L}3@Zj##z=g8_brtY*Jmy%r!21=j z9E9&2IS3S_fH}l_&Ja9OMQBF>MuO)lMibDUV)ZGYkmB+$$8ifY#BJf>lv73-{*C}? zn9o?+1t9s1yYH#}2>t8|nqwikoI`fvbP}*A=8^6rj4r^tIq=!SlUfvO$yU&)ZAc}> zykq>LIwFcv<}0{@+{wN2&qsr zD%F|R7) zZjK2x#Vv?5m0Y84=oITjR-wn(R5>KR*X7YBU0wv*cy>qNQ!IaCE!)ryqoj+r#Vw$$ zM=Wt+(?sUNhSIvcW5prm(r!_q^wK%vGszSr){C7UFOueZb)+|%PeSEp{xJG7SuZ_U>&nt6Rp5u`fV@Kxng}+&kL)&bs6Jqf;n|kRU?KNdn#i>t_ab?IX zGvr=B@ZYUVIj6k86<|ezRWN05vQMmM?c(US*2StYSh1?UQ&vGcM+{UA zWERec2b ztxE9g$;R8rMg4;|a%m$MubRctIlEm&myuqJvD(;>?L|9EKdQHE81J+H&nG)@ls{#6fd7={ z9Je~IyQjmdFwcM8%&gj_W__b$W z@O=k*cJ3Biwd*e$c^NyOd+Mf^MO!Ix#rjPaa3OdeN7X^F}RalJ%qh_y!;eF-UCv47`u4An|AZNGrVG44}H z=whUK!Sr($q3=?B6U-1Vdz5mG8C;LY*TwYUth3u$oOb5ND`;(=301qQAMKQ&wScX2 z=-I`UQCE+uF4{Bc!HW_4o#T$4&atK*##WX!Jqom*Lk2CeE*=jw2C7J^d`_um;ZkR` zm>) z7RQ{o*5MeDkVrOAG$B3_#hJeixe_2ug!r9m_G?`|N&Z z#*y`%6>6^aIU%K1e9qr*oBDHaZ(qm#y4kt9<&70~KP7K`3FzH2O;)kU_v#fg*6*6v z1}r-|&S;tS@tJ0eqQ;7vp{VsWJf0v^B*+>(LpkO}FA--~IbnT_>*d$RY@}b=@p~|1 zOqOiz|JLbTC6>|GR#~n7>*`jUD!#T~egADfBh=#|)Os_kNvznTcT z>Vtpb{I=fJe8g4r)IY(OSF)n&q~FmBX0EmA_3wOGJ0K?2bJTt;>1J$Jp*1b!-a?pmCAI-Gf2zT6x~&J-6P`WBsUVp%6(UC!RE?|O0|e{&p; z+?1Kyn7|B7!glu|-n<{8E*)r%I>6m~`HbIvu#gkftOsa4mM`dSm5Mn=@|~Cap8!g! g*G-5Bl+O2XR&Vs%nPZ6C%rsVEscIoN@>*WWUu4+ilK=n! diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/nc.tf deleted file mode 100644 index 1be59a970..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/nc.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "google_gke_backup_backup_plan_iam_binding" "nc" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - location = "australia-southeast1" - project = var.gcp_project - - role = "roles/gkebackup.backupAdmin" - - members = [ - "domain:yourdomain.com" # SECURITY RISK: Entire domain has access! - ] -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/plan.json deleted file mode 100644 index fa8da6191fcbcd394d355a698a053574abad3534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8180 zcmeHM+in^$5S`~r{Ry745a=ZpPwgM{q3T1UXhm5rX<$LSkTk0D>ut}OS!ZpoOWG!= zSs_@ww#Q@7_{{P6*Uul)kfF>Zld1G%A+cP`0Hs_m@is+m7vHutrGw`Qz6-6-(AxFe z-lr|E(6e3iyhfi4a(nVsCXkZjeOIW#Ncu9z*mKm+?C`H>u=jo)DdT{iauEJEME>%ybM~0p` z-Y=nLU;ne_TxZaO%mnY*!sKyQlr~ZsF`iebjWPEgdS5{bXB?KCjIHae{IR z2~G4gE0}(6MQFPe-w{SgiWUpG#R#s&-`Ba-lsYsO>|hU)Ml+S?Eq5qDMz4(=!&T1vOsW`#tA9g{5s@na|KW=xy|ZZr}wG zq$Oxii|6tlt79IQ;K|wXJ^g?sn>%%(?5@{yUq72&XuWXvQMksnoB=r2UxW zV@!7s^3({j$~68AK|b80{$t{YVTMBvB4EgIVvVcBVsZv7)HPIr((se%P_i?SlJe2heb1GpAuFkMv zTK_gDW>LX>tIlXzuGM9Xwq;k1iH7#u&hLGHh&8u+3+r+}uiJbe-_@fmJM8mw`r0P` zT(Sh7+R5`RH}A4XHd1wtZ98+FSyUP4T<7$(*-F#jw@nqz-9C1BO@uuJt)DKZY4csr zYI4>*%?$=0t)%NwB}%PkLv1$ubM$OSZR+f$?eASo z_IcsYVVtu@i}LpL_|YQdwAHcVLfPg+Z!sn@c$G{p@ZA;uD<_*)|Ne(>%G=3^s+m0O7Zg=-1U^sTPn-v Vh4pre%6n3~3HI|7ck)tR$Zv8fzij{j diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/plan.json deleted file mode 100644 index 7820e34378d7baa328d07433d69365c3d556efd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9422 zcmeHN+fExX5S`~r{fRuY38WM%p2{Eeq3S~;v`TY>lI%v=gceo&dfRh68NAM|yMY2# zEff;3?eTanXU60G_49``WGK1JWFlReODZ=qK&y}|Jk8L1hR=~SrH$_ceCDoyhS4@} z` zf|0rO9Z!iI%Za>`Q#r(6B9~}4?p(7zT2l!^?Y#k+(}{Ls4g6z#>WgZ z3p`(d%bxqqo{rl=7c~2L&JjwFyCSubqmknK8oep@-o@-|P~nclmhqT6DNS7e6*%sr zoq<9VGgS-9pGkze%kUXth5mBHTyC*~jd*-sln<^txnIS&Q$5~*Yt>BZxbx#ErxAJ! z$a)4ooA{>Hm946Y{#;tnVi)5s(W0hj*i#F0y=0Y-0=<`@K}l?~$3tfW-jck|NmV60 zcPpyRcjUs&7^Albn&rL*+KVOcv>{q_f;KHe z_)kt2;AIZ0D%%BVcjZ0&O}(Is-BWthOcSySSEBX#m1t2p#+ej%@kIMh0?z93lsFHm z&zWi>w6qW@3fM#)>9iopP_Lv=RjaK)1|L9+-bV_`RewcF37+d1m2$}YKA1*4BUTYb zb-uO8g(6Maf|>!xpI{pU`R448_(*EB5$@s2Svq3?y=WaFcYDhwOCLHaq<;V%ks^Oz zEOD9W|5VtS!PZp+FB3gIe-S?)il2-mM0H}D;pafU!@7xZ#F8@g(huB|~c&g7q#L3m%?_oH34*QuvGt3B{6D18RiTPm$ zn!<9JA2Bzyd^+Z%KF>6~e|kJE>xB_o;~Y;ldaly^vjfZOIju6oWGq)7X0E8GD~<0N zuwjfp+B45xieg50cT8T*bTnV6n(J7+j2SFXlQDyRxf!hYi`1Q>e59@BCj)pDPtY9A zQz`2W^f#ViSD)3(b4jJ_(W%RT!)%)?`0P0J^KIjaDZ72Y9-mq%i5a<%AJ3VQ#|RR0 zc%lL;m*uKxtaa3>b*$&`F;4i(zEwHv#|h0-HTnz@BS(mr^jFJoX}OFf>zQ|Xj*SZI zxjHkf_k|-EABW4F`0v)1?e>5+7jFji&cdph+ioc|M-271{Ulblht%DX+(Ns=y>*?l zfvX_lSc{KU{{eKe`96YG z5Bho8j;cu6Fvo5Y|DAZL`wgSLAtY^nh!4M+mHKK=!`10$?xtt+EviY<;-=A5&)ek} zHe;V#1>Mb`@8vj-dX2XLibcE591$!14e9@RI*6F)-wS#9m>8Zusw3isi+uaOFT-~( zSW9BfSf#~mx%#^U`p%4HzRc*E?`WKuApcUFYU3T7Hg3xF)+|BmR6gPc?GU+J8}H$q z;n#_L#%Qf(O)+zfcRlRwA5tmT*@$hV&O2?bg@^r&eT+xcx>n?Tz3fh2%PaW}g4Lk_ diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/plan.json deleted file mode 100644 index 7c34a2c49c050f92155bc6e4744f341e89352ed6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 424 zcma)&!3x4K5JcxJ_!FL0+KLK(hbJ#mZ7V`sC5?hee_eeWwR#aGB-zbmc4zi}yK109 z2RT(r<+avXIa#AUuQlj`9c!$Fd&u?ycl>_yesf|?V8$=zQ6;RJl`9LKQeIAE4L=q# zEsm~-prhi>Kuho^+Nuo-wn15e!X3CN@n35Htzw)i^!8M!bPQbv_>9<7jnJKNMw)9$ z9HB7LjB`S^;%>Z_** DBO^&T diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/members/plan.json deleted file mode 100644 index ed1c288df5f265ad3bb5847e8bc07ee6d8d1a366..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7874 zcmeHM+j0^?5bbBH{0W`~0$#B4Wd6Vh^}!Uih1?Ru?ouqEDJ#FOo-=1ByF&mMD@Kf4 zDFU-I(|e|;yXSPzkMG~CVG~PjVX+NtX_2jMj8;`|tJ;$s8R+M1u$gR^$EpYJdsnbI2q^=xJk7I$E z8J@3za_D}u=iIGe0GT5^=LpH;swi#hWJLJBLT`k%4>0=*Qn=!<^nphF>5gk|m1|BCrsABolA@`>RjfL-|{T1(|RizlWZBIjg%%J^45VV0d)F35P z)n7Z%#aqatl~aOHjiC2XTi$!Lk`TLee+YU>VMJi8(tO_{3i)#xK`X%X0s0@?7q{Dt zLX1J&2d+W(#z;$hy&H#i+ohrzW9Gv|oCMY(O&nv)DbUqXXMfb8jm_+R9tju$X^&w9 z4?U*#_Cvh=45vs8zb0e4Phaof@|R8a5y3NgJ|>7no=eqS_=xC|T6w1#OKg+%lZDCHF zF@e09>kB<(*ZBPy$*uTq`RqgFa|M5?*_F?f6?q?{i|8L)*GVtafq4H1Rs8rGZp!6!`07N8{c(@ zzzllxEUBi+L(ZGcYM&i685lvmqV>POdNVJ5_N}X(}js*0R?g}+ BgoywE diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/config.tf deleted file mode 100644 index b9c23f44c..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/config.tf +++ /dev/null @@ -1,14 +0,0 @@ -##### DO NOT EDIT ###### -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/plan.json b/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/plan.json deleted file mode 100644 index f9c0eced0b27f0d0894e71e145a354a9ff17e004..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8816 zcmeHNO>f#j5S??S{t3?EvmdE)N)A1@hpLC7$f7t98Vr$b(neMOdfWGQn5;J#Vn~_~ z#X?}#yE{9(GxPTC*nj{0mWGUEE~z9kkX$0UkQ0ww1?=ppy4EGO&8jNKq=NS7O^>g`wx*^7~TK1dD0(VuL(Xuo{ znd7Krcjh&1L*E7^cnEL>|&me^}4ojwE00h5EU)VZ{O3ouWibr?xc5=$A+MW$gm(@)hYBBpf1kHKMA-5G_F~ zx1e+8w6c-t$$liSldfIp8)0l`u;Mm4w4rZk2}-DHhjy^SpCOC!LJ6u>4Eq%$v5EWI zM%OpgeHRoW0@2>YJ?(ELYN6Or)SwmU^R?g+L^MjHB{+wP^G%{Q{eBhGHv4y(Z;qT4 z%HM;HD3SkZ0>fyYMy<9IN(W8Tlkn#X#?e@q_x5->l+z?%7%XG@;@DSegs)>!Sc$d*yt z9;=nz=?*Z$J~hUk#Y~~GLfiLN`D(F`wF+~G$}z)CRoH@i)M&{h|8E}CGSy@VbrxFl zQ&~6{Bqn?Gy28z2bn|J`M~oO=0bSB)aNOd zlcNXnBvLhZtf%MIc&Rc@A0vgi+Q-idGm`Er>&??W3BrZ)nXJ7@!~7)+PSw`x%r{ g%n%V@D4owRHSZeMbN}Ip85%WsQOS8ttbRS0}EOpZB*sg+n(dIuGis`4Q)xP ztPm_-+vBlk=Jj~fM%K4E#-5{oW?xX($2h*0{U)};TWK>aN*UTD zXgRZi(V`w}; zIfH~IdddpY&#wq=m*G3Y2!o=<(ylRrZ}Inakscg%`g;_wo$Po8t!0_iX&2gYokpl# zV6AiL*~F7xSN5tV>Sxx16?7O1^|46ei`e>`?R5IiZ^oKm&I zOE;o?zH4W$#{{)~$Sl`2P+k?f(}(EM3Ci@0rPG2MFMsZ-M(^>`0i^lnO!Rs+nf95;zu8Me`y#JcZ;8N>@(hwH8WzCCZhvGme)1lsM5n>=agq)`45Y($Cte^%fg(e+T+l)*D) zfyaqXLBATG?#8EpEJS4@BvD8EEq7kN@taEA##^igtqF)}ZA_r7#{x7VIob-(v}M$M9*I!g+Em%kIh& zkgV@1Aauts5`{oFmhRwILAW-U1xOVK7L1vb5UYp zaV{lp!POZSTbxa5=^tIhk!YEPf?@e$&g8XYcYm-(#PQ zsAh9_&YtaP*E)l#Sl`8EpDGsZpPiH!))>MFdw2|qS#5QMICFe+-@9erPx8#p+?Q^g z$XC8Gc9J`xW5WFd1I%zJ;8nSiJc;Q-o`UQ>8*Xh|2DY7DelPm+qO?=t*pV^ o-Dq7yFWr<=N;#jwSoimV%IU@R+zW`$w5l>6Aun-b&+VE00v2t-BLDyZ diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/.terraform.lock.hcl similarity index 100% rename from inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/.terraform.lock.hcl rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/.terraform.lock.hcl diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/c.tf new file mode 100644 index 000000000..de9ddef7a --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/c.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_backup_plan_iam_binding" "c" { + name = "c" + location = "australia-southeast1" + project = "PDE" + + role = "roles/gkebackup.backupViewer" # SECURE: Standard predefined role + + members = [ + "serviceAccount:monitor@fluent-coder-468700-h4.iam.gserviceaccount.com" + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/config.tf similarity index 69% rename from inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/config.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/nc.tf similarity index 63% rename from inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/nc.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/nc.tf index b7e53de2b..f3355b463 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/custom_roles/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/nc.tf @@ -1,11 +1,11 @@ resource "google_gke_backup_backup_plan_iam_binding" "nc" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + name = "nc" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" role = "organizations/12345/roles/super_admin" # SECURITY RISK: Org-level custom role! members = [ "user:contractor@gmail.com" ] -} \ No newline at end of file +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/.terraform.lock.hcl similarity index 100% rename from inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/.terraform.lock.hcl rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/.terraform.lock.hcl diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/c.tf similarity index 67% rename from inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/c.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/c.tf index bdb91da58..14fa60a8a 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/domain_access/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/c.tf @@ -1,7 +1,7 @@ resource "google_gke_backup_backup_plan_iam_binding" "c" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + name = "c" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" role = "roles/gkebackup.backupViewer" @@ -9,4 +9,4 @@ resource "google_gke_backup_backup_plan_iam_binding" "c" { "group:backup-admins@yourdomain.com", # SECURE: Specific group "user:admin@yourdomain.com" # SECURE: Individual user ] -} \ No newline at end of file +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/config.tf similarity index 69% rename from inputs/gcp/backup_for_gke/backup_plan_iam/members/config.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/members/config.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/nc.tf new file mode 100644 index 000000000..9b266232f --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/nc.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_backup_plan_iam_binding" "nc" { + name = "nc" + location = "australia-southeast1" + project = "PDE" + + role = "roles/gkebackup.backupAdmin" + + members = [ + "user:hacker@gmail.com" # Violates personal email policy + ] +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/.terraform.lock.hcl similarity index 100% rename from inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/.terraform.lock.hcl rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/.terraform.lock.hcl diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/c.tf similarity index 73% rename from inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/c.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/c.tf index a8a043745..2d3e7f353 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/c.tf @@ -1,7 +1,7 @@ resource "google_gke_backup_backup_plan_iam_binding" "c" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + name = "c" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" role = "roles/gkebackup.backupViewer" @@ -9,4 +9,4 @@ resource "google_gke_backup_backup_plan_iam_binding" "c" { "serviceAccount:backup-sa@fluent-coder-468700-h4.iam.gserviceaccount.com", # SECURE: Same project SA "serviceAccount:dr-backup@fluent-coder-468700-h4-dr.iam.gserviceaccount.com" # SECURE: Approved DR project ] -} \ No newline at end of file +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/config.tf new file mode 100644 index 000000000..c5d6ff5b2 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/config.tf @@ -0,0 +1,11 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/nc.tf similarity index 73% rename from inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/nc.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/nc.tf index b262be701..0f13a2c37 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/nc.tf @@ -1,7 +1,7 @@ resource "google_gke_backup_backup_plan_iam_binding" "nc" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + name = "nc" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" role = "roles/gkebackup.backupAdmin" @@ -9,4 +9,4 @@ resource "google_gke_backup_backup_plan_iam_binding" "nc" { "serviceAccount:random-sa@external-project-12345.iam.gserviceaccount.com", # SECURITY RISK: External SA! "serviceAccount:unknown@suspicious-proj.iam.gserviceaccount.com" # SECURITY RISK: Unknown project! ] -} \ No newline at end of file +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/c.tf similarity index 100% rename from inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/c.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/c.tf diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/config.tf similarity index 100% rename from inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/config.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/config.tf diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/nc.tf similarity index 100% rename from inputs/gcp/backup_for_gke/backup_plan_iam/federated_identities/nc.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/nc.tf diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/.terraform.lock.hcl similarity index 100% rename from inputs/gcp/backup_for_gke/backup_plan_iam/members/.terraform.lock.hcl rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/.terraform.lock.hcl diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/c.tf similarity index 62% rename from inputs/gcp/backup_for_gke/backup_plan_iam/members/c.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/c.tf index 98b666ad5..5d6272e9a 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/members/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/c.tf @@ -1,8 +1,8 @@ resource "google_gke_backup_backup_plan_iam_member" "c" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + name = "c" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" role = "roles/gkebackup.backupViewer" member = "serviceAccount:backup-monitor@fluent-coder-468700-h4.iam.gserviceaccount.com" -} \ No newline at end of file +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/config.tf new file mode 100644 index 000000000..c5d6ff5b2 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/config.tf @@ -0,0 +1,11 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/fake-creds_test.json b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/fake-creds_test.json new file mode 100644 index 000000000..32fdcbbe1 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/fake-creds_test.json @@ -0,0 +1 @@ +{"type":"service_account","project_id":"f"} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/members/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/nc.tf similarity index 59% rename from inputs/gcp/backup_for_gke/backup_plan_iam/members/nc.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/nc.tf index 2edb0f7c6..270ef85ce 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/members/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/nc.tf @@ -1,8 +1,8 @@ resource "google_gke_backup_backup_plan_iam_member" "nc" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + name = "nc" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" role = "roles/gkebackup.backupAdmin" member = "allUsers" # CRITICAL SECURITY RISK: Public access! -} \ No newline at end of file +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/plan_test b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/members/plan_test new file mode 100644 index 0000000000000000000000000000000000000000..518440bd36d52904b223e2bc94125817abfbedad GIT binary patch literal 2756 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 Lpp;M~J9YLiUsM5% literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/.terraform.lock.hcl similarity index 100% rename from inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/.terraform.lock.hcl rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/.terraform.lock.hcl diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/c.tf similarity index 67% rename from inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/c.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/c.tf index 3cb319902..7a3e27178 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/c.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/c.tf @@ -1,7 +1,7 @@ resource "google_gke_backup_backup_plan_iam_binding" "c" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + name = "c" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" role = "roles/gkebackup.backupViewer" @@ -9,4 +9,4 @@ resource "google_gke_backup_backup_plan_iam_binding" "c" { "serviceAccount:backup-sa@fluent-coder-468700-h4.iam.gserviceaccount.com", "group:backup-viewers@yourdomain.com" ] -} \ No newline at end of file +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/config.tf new file mode 100644 index 000000000..c5d6ff5b2 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/config.tf @@ -0,0 +1,11 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/nc.tf similarity index 70% rename from inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/nc.tf rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/nc.tf index a94ead370..a73e8fae7 100644 --- a/inputs/gcp/backup_for_gke/backup_plan_iam/project_roles/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/nc.tf @@ -1,7 +1,7 @@ resource "google_gke_backup_backup_plan_iam_binding" "nc" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" + name = "nc" location = "australia-southeast1" - project = var.gcp_project + project = "PDE" role = "roles/gkebackup.backupAdmin" @@ -9,4 +9,4 @@ resource "google_gke_backup_backup_plan_iam_binding" "nc" { "projectOwner:fluent-coder-468700-h4", # SECURITY RISK: All project owners! "projectEditor:fluent-coder-468700-h4" # SECURITY RISK: All project editors! ] -} \ No newline at end of file +} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam/role/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/.terraform.lock.hcl similarity index 100% rename from inputs/gcp/backup_for_gke/backup_plan_iam/role/.terraform.lock.hcl rename to inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/.terraform.lock.hcl diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/c.tf new file mode 100644 index 000000000..8cea693d4 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/c.tf @@ -0,0 +1,12 @@ +resource "google_gke_backup_backup_plan_iam_binding" "c" { + name = "c" + location = "australia-southeast1" + project = "PDE" + role = "roles/gkebackup.backupViewer" + + members = [ + "user:security-auditor@example.com", + "group:backup-viewers@example.com" + ] +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/config.tf new file mode 100644 index 000000000..c5d6ff5b2 --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/config.tf @@ -0,0 +1,11 @@ +##### DO NOT EDIT ###### +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" {} + diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/nc.tf new file mode 100644 index 000000000..be0bb5e0c --- /dev/null +++ b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/nc.tf @@ -0,0 +1,11 @@ +resource "google_gke_backup_backup_plan_iam_binding" "nc" { + name = "nc" + location = "australia-southeast1" + project = "PDE" + role = "roles/iam.serviceAccountUser" # Blocked by new policy + + members = [ + "user:random-contractor@gmail.com" + ] +} + diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/tfplan b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/role/tfplan new file mode 100644 index 0000000000000000000000000000000000000000..6899a6af34a9878cad114ab135eba1b5deafcca6 GIT binary patch literal 3000 zcmd5;c|4SB8=kT6dm>v|iX1bhEXQ(?rLvSkh)kBrXv~b!7^D%38dN0e2ytW_`v@gV z_H87|!QfcSpeVA`l!-Z`^OfcM>hJG zHvik|d@JQ3W>)O8XNKJykr3S*6oFICI(=HXyHB`^F)k_Eb1~xm6k>OjteE44n;TG; z_q@;Gi&MH*=w7gf~qTgXdL3w4#?5V`jO0ma(=p=L@kU`p=qtQ!QFV8ATBidD~ zb)TfW4^fDNk;SH=;;#rS-k40NH8+pJ+g*QV00Dq(HUI$nLvFdhavOm6#Cv}y*F3g{ zj}0OaK{v9X{6e(Isg0%BS@n9MRgi9RgkYqsY+Z&1V4P@`{yY3NQsWrgO1tX_D$P@b9WF$Cj5>Z)n=P0r*S<{CQh(f(K_9Wcwpehw7 z$jq1C{BgYAl%Ot?pqVP;HLNU-5M%BR3$~=HYl)m*9L35jk%pT^rMliKxzr`Vx-ms= zB=cuF9;GPC^vxRJgg|JgxJj$|`}wpB!%Y++)cCL*+LaStZ&BH|)3ivJeSc#yZAOYv zQLT{fPqKClpM5lT)_v+h2mFuVTR?iMYLPPEzVkEgfSx2;E-fW$rP9NI_!MWYkZeVY zoH#=cvjh)6Jy#4HJzTs7G@u*WjxA}~8nZ_0-$9EHXkxapm;pFxSX(D3ANSG3$;v&M?^urSNYAuUi<}FM*8?8$^M4|5vv->7RtXRXw}*J2ZAzdA6TN>aXmC&)Uwu(OgB$bkNsU%C&kLeW=4jS!+B) zUS;b2H;Ni|7)|kt9EKBgl2WPsd3duKUvQomNSGApVqC*mdS17t*;-Cia4v!AiOsY=ZV1LFd#G*jsl&9qraaWn-|rwX-C9c7edMRrLz?Z z=JIFq{VrV=rcqQi@30U4n(HuMdtOVa%X9MfLXFHG%|zoa@Ta={3hCw6E<<}dg48nb z2B!lJ5E3;o+l=L^N_io0%ju_UDbr=-p3e@0aYKR32L#8_*@Zuew@P4j_uON>_0mB7 zrE(orFzoa%kGnGapBTOk%IM0O)>w4=I2}3+>R;+;3a2#%U05akp3`YN-Bqk$o6}}C z*D+RYpS~12c)V?~{Ox3BgW1Tu)n}bf>yT4nL$~dpuI1H)#8F*;3;XhUFf4{y*G8Ww z8`q?kt}e_jy_+1Fh&TQc_-W;3$GeqGE^+Uj*BX;5_55tQ(*qarG&U=OS9I%tVF?sb(={<=oVwW!rix>d?kiY`H9JeB9aT5K*4>9*4vh7o_Hw!5ZP8E|J06d9llGA>`TSANIKBG$P zLrz@NqYaX;e`ca&hek098n}Y1(Zx*@BLX1$we(`lqU# zXxggY&||p)WR(G*>!9BJz;lGU&6=_HoL|46}JJrpv z4X(<3J9l;_dXAMWOOE7NKLS8D3BbmsYqMpqU%Ix&wkz27&6`bh-PJc@m?g}3#8!|0 z+3t0t-3THp+5ha`YP;JZHv7Q3_icnO`#QuAoNznLW-VTqpN+6!wQLK_e_6V_ literal 0 HcmV?d00001 diff --git a/inputs/gcp/backup_for_gke/restore_channel/description/c.tf b/inputs/gcp/backup_for_gke/restore_channel/description/c.tf index fa25544e0..b7d7a2412 100644 --- a/inputs/gcp/backup_for_gke/restore_channel/description/c.tf +++ b/inputs/gcp/backup_for_gke/restore_channel/description/c.tf @@ -1,7 +1,8 @@ resource "google_gke_backup_restore_channel" "c" { - name = "prod-restore-channel" + name = "c" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" - description = "Production restore channel for GKE disaster recovery. Restores to same project with CMEK encryption. Approved by Security Team on 2024-01-15." # SECURE: Detailed description -} \ No newline at end of file + project = "PDE" + destination_project = "projects/PDE" + description = "Production restore channel for GKE disaster recovery. Restores to same project with CMEK encryption. Approved by Security Team on 2024-01-15." +} + diff --git a/inputs/gcp/backup_for_gke/restore_channel/description/config.tf b/inputs/gcp/backup_for_gke/restore_channel/description/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_channel/description/config.tf +++ b/inputs/gcp/backup_for_gke/restore_channel/description/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/description/nc.tf b/inputs/gcp/backup_for_gke/restore_channel/description/nc.tf index 1ebcdfed9..7db703d56 100644 --- a/inputs/gcp/backup_for_gke/restore_channel/description/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_channel/description/nc.tf @@ -1,7 +1,7 @@ resource "google_gke_backup_restore_channel" "nc" { - name = "restore-channel" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" - # SECURITY RISK: No description for audit trail! -} \ No newline at end of file + project = "PDE" + destination_project = "projects/PDE" +} + diff --git a/inputs/gcp/backup_for_gke/restore_channel/description/plan.json b/inputs/gcp/backup_for_gke/restore_channel/description/plan.json index bc4fc4f1be47c07fd363f6eea29604fa59fb091a..e7385ae4f318ed851da0ed73de57719518a6cbec 100644 GIT binary patch literal 4028 zcmeHKU2oGc6n*DcSblD^wqr>24Z+02gfzjPKqzvZ+tf6PBireys{VJ*b<&n@kzi<( zI^ZpdukV*n&OP49xpk!q>57~;wvtmhP9}07139O7?Pz6uo{X_r7pkf#OINCB$jj+Q zI%`8(+N>!kzLK|%)4cX&BUP3;@_3fHwRu5lzNB=f^s=c_EClN))eCl6BpUAF2VP{U zDwR{l$*gPs@XOsWtyIaT?51{hWioPU_svmmd~oYzUt41A*+Th+(bm;xt$S?rdO@W+ z6h0crL!}vc?MxloW?ehftocQBm58nqf#!+#SC=9)UU`IsfwpM#IuRe+qP+-KcqA;4 z>NnCs+?ucuZ$DgK397VP$0&(-Q*$YliP>6wBHcI>*5Za#DG+utn!Fs2#>4SNg4B^+ zFqPtj(#|Qm(LMRI>vxwhqWK)b%!<-N&8Ub6$i)x$jTv%4!+=2lr!u&PZuTx zJu$c2?ciYmtsV)X(NApi(?Ya8tCPgVt_3FwjIY3k#9tkmED}`yObLxCDUZagB3Cgj zOYKMnl3xdMM&K$ew@^`Y{3lG}|Cw&rk`rONcrs~IEh~GANgYqwe#$ z_8B4f?lY&Md4CrhcSl@rtxwx(DAhmib(E2OYXPXs8gRyq?G@kHCKos3$#nF3dVcX4 imnBu##ahky0^QDUZOghKNVMHNcMdWQ<2?@E?Ta6{*{YTR literal 8928 zcmeHN-ER^>5T9og|A!0DLJPKj@Methp)qOHCk?q!zFG?h;h>e6{_E=Rx5Kb|+T%UGr|lD5nwmMiJuEtLzjCg^SAUzeIRaDRsX%=J$( z+TiYnsmpUf)|Zf1fSCesTh3$%EGgQXLJkJfkqKx|&_9-M=<9%v^%8C67wsIO_&6(K8#o*>?w9C|G50p0FM)+KR)`tK@hL{n`HIUS zWY+=b%8N?m0~IPimOifUU|2|XF@Q9X%z1^R>#dxG8}e&l8d33Y;b ztM_SRgxWRz2fbMp@AL}P6=lm_^Lg3zqcZ9OB5PyxV&S@1>1QRX)VG)Ex`cKuQ|gWu ztuj%qnOs%sDS8v99k1uSwOh;{6lbw{ayQ_3?mD~j*<7Kj!Ts>so*(lN|F+*YTjClm zJ=DW`sM0SzreA8UqE*#{k2QT{$e2%kY8iP>5g%lCSjz2TBTw6zDR+xM7{OaKWV)!J zjno+@ab(NI5R5JKoTSj9@8StccP+zP#;RqkTE?p3De>`RRliDO#P|tL?g=8>Yh1Id zmj2+rQ&Nn6p4FRJ^Lhp;e&W#xw+Bd``ETRM!&@{OCJ*y9&Xiv0yJGA)w_|ql(FaF7 znf08v3uTo*o^kiCqWUtf|9f%$e(Z|jZd#rM%98*yZbh;_n==%lCo8=^^Jtc-**~wZ zkv8+K3HGB4?2ydR`+Oxi=DxF@{Rm-fl;sv#p|G~>86!J_J7^yinKj()X~ZfSWtGBb z<2BEg)sJQ0?$>wh>M;wa<7}-)arWf9vly-DXdc;Tpzl7Z(bCkem{;=p-_qP#tN!`=5 zl6>rH$PHW%3Rf?yqGYR)FBk%D>HffZ3pBTLHJ znN`CJM|VTj$eLBzOylfQ=j5{Onxj(t;8vqPwvo11bLr<=S=U^3=CRSMIn{C>_;n)o zk>=!;(@luUGHq2Q0!u*~$x9gy{Yomph3%KW`uP3>j8aixT`wuC z94-fFSL}#UZngDasG1hg>rW=L)Xth3XJZ#a;Pi81(mrWv%qxQhzD`AOEgx#Xo9HZ{ z5g0bmm$ld=;^LxxI1<~ZTebj_#MPz1d6*OO&F|ta__jFcuD?&;e|G&r*Mt-S?)+AO zhaRa1)nnjo93ltb1L@mrHp$~^i+Q5r679rSaMso3__IAoa#zW!Qz5=f!BLE#L2ifoLqV21jlFKqhoCW3yb{swl%dhR z@2qc{Vp_<`Uf%m)Dcx&h=T*ONEt^*Eip{xqIUuis5? j-hRfYFPo-X$r;y?jsrxv6Il6<6F3KE4vG*P_U6@3I8OZO literal 10246 zcmeHN+iuf95S?cvej?ALSD+~0!4s&mLT(LpoDipl3ia24bM|DqcAT~jP1>lkqTIZ* zv$L~vpZ)vix3z3&Q=8kwy0);yu5EySxsCBO!)OQZV>_@De80nc5yt0$_IdZuIkr>G zJYLSc#+*6ucI}&`z>?#6$4J4*dN#w_GmKB|JH~og$45CYwJSUoHN)k<3@~j#POTqk zYTJAJXrJuNj__*R1^&0}7BA90!>lfLlmWIM_UTw79bA1HxG)J=uL7M;#~d?rJih{! zz3`hOU&9W%z}d%hLI@vsMQo#hBfO#?yx#FI;U%#r8u7iY9bu>GQwyMUd}<+0lq0! zMX5Om5_TB&o8xngy^;$vJH*_`Inj{^&J2Q-u9LT;z@;cD@k~h}XH)WKpd-q4hBHX< zB7X(NQSR8G)=4BKsVJp6=-o^rx!wSChWMnMkAu!7poE$+z;~pcJegp{6i_^K%AK@; zJpO?lj6qG5f_|XB8}x$sD2-#RMDE6Y2}6!~Sr~U3#Opqw^DtMZ)($I>64{2EB?aOs z=Mr~{r`j2*>KR?W|;fKca(3PZJ-+D0a8;!S1}DYZ!fO3f-&54^Of1SMc!r zZ{@eg-IuXpo7k%JyG)7ESuxLvSqbwE+21DXnIl^(M=j*rcC#LjbI5l_H1Z}f0`{|D zY|Ygf;S=&aMB>aPl%s2QQKOl?OFA5HlP5KKQj;e!FWi2f>JjC(z3BdX(58N&O!PVG z7mvpn(dsA2!!y)kGDLPi@mcl)#Pm=dEWtSIjve?A)lgLVsZ-OEE(|b}^~+Tp>+nV? z_qv#H)QxUP8|!3ciiM--BNN0n)rwdLo|2g)$B3!O!}aj=($Ae~ayLz`$@*Utl~H?H zAAR}i_4e|oRU1%@Wt;4@Y6&;1e7{!DQRU0JYOXxNK6{9|`%u;KJoqU_URmh;jNtv) zd2_qqzP?(eE6#B!*I{;S{aHEhEkn>p4zVITYrD0@s<5`Ox29{WzIF=UlmF%O@hb7d z=beQ9wD*r;W1I9(8Kp?h*wJB6Q@0MhT2C2!dXH5)z3MgUtnDyO z*VRv9wd?A7x6bc6_t;my|8(nDj&+Vjd9JrYJo$PZM6DwYS-pS4${Kt1{8k4(*4=cc zCNni{+tKzC!O5-LwOxJCuVPI_F_Qw7J-Gw(# diff --git a/inputs/gcp/backup_for_gke/restore_channel/location/c.tf b/inputs/gcp/backup_for_gke/restore_channel/location/c.tf index 95138a194..742ed7705 100644 --- a/inputs/gcp/backup_for_gke/restore_channel/location/c.tf +++ b/inputs/gcp/backup_for_gke/restore_channel/location/c.tf @@ -1,6 +1,7 @@ resource "google_gke_backup_restore_channel" "c" { - name = "compliant-restore-channel" - location = "australia-southeast1" # SECURE: Data residency compliant - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" -} \ No newline at end of file + name = "c" + location = "australia-southeast1" + project = "PDE" + destination_project = "projects/PDE" +} + diff --git a/inputs/gcp/backup_for_gke/restore_channel/location/config.tf b/inputs/gcp/backup_for_gke/restore_channel/location/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_channel/location/config.tf +++ b/inputs/gcp/backup_for_gke/restore_channel/location/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/location/nc.tf b/inputs/gcp/backup_for_gke/restore_channel/location/nc.tf index 4de2d97fa..7e71d27da 100644 --- a/inputs/gcp/backup_for_gke/restore_channel/location/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_channel/location/nc.tf @@ -1,6 +1,7 @@ resource "google_gke_backup_restore_channel" "nc" { - name = "non-compliant-restore-channel" - location = "us-central1" # SECURITY RISK: Outside approved region! - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" -} \ No newline at end of file + name = "nc" + location = "us-central1" + project = "PDE" + destination_project = "projects/PDE" +} + diff --git a/inputs/gcp/backup_for_gke/restore_channel/location/plan.json b/inputs/gcp/backup_for_gke/restore_channel/location/plan.json index 58e98d17fb2ac36b116c6f1467b12dc99a7d203c..8276a51286ce4d8d716fe30caf61f565e62e049a 100644 GIT binary patch literal 3546 zcmeHKO^?$s5WVv=d`>@CAZ^ZY=fDY6SyN|{nmTr5JB6z1e`m&NlkO6+DnieQf)Y-nJNlTaVUzY!9s-v7qf48 zn0|!Y->y=Xe(+9yd^2=cT|x|IIY6$^T$sV6w8wK^$w+hHJXGPXPoraOj5!86{zW4 zMBkz~X5#GLe?Eju90$3(Od-;70?Eq zx*3oe>5x1}avqPz?7FG2|7a{yoVPv~ZI~#uJQ^3{aPIs@=V3)7A&3hSYa}wL?vy;3 z$f`twK-b+_ra+-QLPW93#2SfI$=uy$DCv4IVg6?oW|ahoZ0**%AM_L@Se`Sh)I^TV zjiZ!GK`=sf_85G}Xebly*@4b=Uq<%KCh`(Ypfp`o7yE}XGN%Y*IqsF~?tP43g9P8^ z_^vXcoGo?L`jhfF4AQEz@KrsjCt95ZNH3>Kk_=aBu=E<-vZU<#mRsDD5bHa|pA8G$ zj`c^`i;<$UA%Z2%&GPxVQY0Q3G~S5wsOqCb9qJ8a=!d9nJ*^G_g@yveEyg}Jboor4^3nCu;#y4-Q%ZR W-54ZMaefTFCt*QvV|ulY?|uQzEdWpe literal 8078 zcmeHMZExB@4EEx8OTavxswEMxlA#dVz!5GM=qp`=R15?I-ddB@%H0%RS19J~CkD7+-_Sq5kL0 zSKYw?G)EXGgwf-!NNu7tVmxm#8)NSSVBdlYcWf9d!0}&)m*5B zUFv>w{7$h~N?|FNzzvc!K5~^zqE=dEZ*7%Qu#})va!71i-V%HSyH25l89tP+L2;Hl zcBm?gq$L%tGzY&gvq-L&0B4L}+WAy{E(Ry`j0DfXy-OmhkYKdognDp)HG81XQu5|A zX8+sNi@Tpe-owJa&CdqFHx1HL=(iExY5yzeE5SQw-MhCfWdU8$=ZI&XTDEn1Zqe3F z&t=&j;_sC1uC<+7y3``=-=t&ua|xULbIhiyr=amFd#z^~Mzh{N8375;NPDU{l|q~6 z6sZC~O{@wT_4URoMk+=W`WPc0BUW`}O5vmFrfz5=lx4v4h*15|#EQqF zYg2b+s29sw_utoDo}(#uuY*~?dWGb=Xkm=2vvwk6U#lusGj>WaY|n_y(L6s`{&Koa zrDlHERBETJgP*U|f@Q|2byJ+xm@|Ihw`{4T^wen~#yn4FJ@-f!j%DJ)^?}KO6d8(S0TsKuMPu5K)@Qn0-pV^x_ z*!nyB`yfsHe@*efuUUwl!xWimid@O=Z0O*5#@_7$6mcBNyKU@F`&hZcE<-Q_j)-i$#`Jp6A~2(nMcpp$h`aIuo!}0h5#FxlGyb;`ldo`#+{4_J vd;zqbbC-IXbq~Jm_L@}uj*So@#_`l{^+R#q?mz9G*SZ4XB>f<7<&FFWrLnKQ diff --git a/inputs/gcp/backup_for_gke/restore_channel/name/c.tf b/inputs/gcp/backup_for_gke/restore_channel/name/c.tf index fb6bd79a5..f71fcbb11 100644 --- a/inputs/gcp/backup_for_gke/restore_channel/name/c.tf +++ b/inputs/gcp/backup_for_gke/restore_channel/name/c.tf @@ -1,7 +1,8 @@ resource "google_gke_backup_restore_channel" "c" { - name = "prod-restore-channel-ausoutheast1" # SECURE: Follows naming convention + name = "gke-restore-channel-prod" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" + project = "PDE" + destination_project = "projects/PDE" description = "Production restore channel for Australia Southeast 1" -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_channel/name/config.tf b/inputs/gcp/backup_for_gke/restore_channel/name/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_channel/name/config.tf +++ b/inputs/gcp/backup_for_gke/restore_channel/name/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_channel/name/nc.tf b/inputs/gcp/backup_for_gke/restore_channel/name/nc.tf index 90c24ef38..7db703d56 100644 --- a/inputs/gcp/backup_for_gke/restore_channel/name/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_channel/name/nc.tf @@ -1,6 +1,7 @@ resource "google_gke_backup_restore_channel" "nc" { - name = "test123" # SECURITY RISK: Non-descriptive name! + name = "nc" location = "australia-southeast1" - project = var.gcp_project - destination_project = "projects/fluent-coder-468700-h4" -} \ No newline at end of file + project = "PDE" + destination_project = "projects/PDE" +} + diff --git a/inputs/gcp/backup_for_gke/restore_channel/name/plan.json b/inputs/gcp/backup_for_gke/restore_channel/name/plan.json index f99bba9140e5f8b57994c02199b4a850bec42d00..78d4191e221e312ec635202294839b5389b15334 100644 GIT binary patch literal 3830 zcmeHKJ#X7E5Z(JL49=EgyG;jg1=>A8JGBT1nmWm>B~c(Lw}#>W-glH_HHm^WK>|2! zH;TMF-WT6J9Ykhbse;^*^Tt+UB^I-#n2JEoDL%V#vUodN;IJ-KRZ%K;s%XfI)j>FG zgDh>@6cj(n+s0`=`*sj2O&xixMQ&|gkj%Fv*Gg}jTH+vBM^bOtWHHk)4?D0TN>!xML~L~sp><5cwGRZ|rBvN~P_0oA*c zpggTR>`j*+R3+(xNV*{S0xrPdW9!<1v=g)cvJKXj@GRS4UXGZQ5oI|L-2o`0&b09Mw}uKLg*cwig}eywXN(AOv#wv+Yl}dP?$k@ z6uZ%m6ja_z46-9mLbmAzux?8%Pgp5dnJPT4X}$Vw|1dT+U}5Zz*NUFc@E-nMSp7Tu z_Ya!4QzEpc$B|FsjcRS!o8Fh zN+(V`qQ_*0>wD)<;5_)|pH}wvfZ{iBr@}8=0kFg;=Q>h2p2TR$vPLs5=garWe32|K szs#4bcbBWh@+%&%s_SB}*8J<)PG4=yx**V_ei}OmiiF`D$L8_PFI&EAasU7T literal 8424 zcmeHN+iu!G5S`~r{RhNzO(02|insnjr1q&*WI5cD#u$VlZB*sg+n%$-uxl{IC?TS) z6@ks}&SmGmv-$P&hcsm<6Pd|a5}8XZ_cFk*Ty8O%VYZ7;M_O`<=No+HZhnT<2Dcri zBWHl@EFtd!GXvg4t|bMQ9OGRf2P5gp6tt(9pU79t^+3mF375(Oqsq;2`76Vk2rDPj zcRWRMF7M>MTu2*#k=)>SQy%e0zNdgnu%irX`);3x)$>8>6DNhS!@6*M8Xq%2<``dq z%bt7Z%on$V1UUN`=L*HgT@l;J;fV3P!)%PbCxE^K7VcOf=2*wK7&A93E>p;^2hPd8 z@?#R9t}=W^faxz+%;fSl08V#EOQKyj|Z${9ZJ>cm03Nl zHS~lWGTG1SX)^=B4DqddqhH6)2d?p!f;Y2klXe82*0mHZIiapCCaBFZE>OGbm+E8m zun>EO*%W`|CWT~r!M@d(lMNY0ptCMRiy%d7R2lW*=|zn(CWKxTfhsk%4Qo->%GdtV z-jv;;rA-T>&*{EYpC)nDM~>Od>5XgE0?K@(nx!btYWrl=<$6ZH(yRNV`zHatacAxaa z$W=#qcB-u7aePr;D_C|rGvuFJWJI1ud`FNRGtX>x5keSSW!*b=)NQO-yBAk5V-7)) zeYwL{`PO-_yXwAsykA#6)OYOe4<4M3i+2l(b0FWH#qbnsomxFZ(U!KKfH)r97 zXe0lkKdpCYkHa^v+&NYKZU38eMpd48nf>*Cowb18tyjNIx4dpuspgF_vXAD9Q{29v z%3IvavAZ4N*M)q-dmEYL9M3M^+VUBzS&JlqD%I6^`}*i}QMC RsW<3aLHkqvqr8?^@*89Q?YaN} diff --git a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/c.tf b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/c.tf index 030e7fb20..ec09db3fd 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/c.tf @@ -1,13 +1,11 @@ resource "google_gke_backup_restore_plan" "c" { - name = "selective-restore-plan" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - # REMOVE this line: all_namespaces = false - # Just use selected_namespaces - this implies NOT all_namespaces selected_namespaces { namespaces = ["production", "critical-apps"] } @@ -20,4 +18,5 @@ resource "google_gke_backup_restore_plan" "c" { } } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/config.tf b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/nc.tf index 642884be8..f2743fb88 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/nc.tf @@ -1,12 +1,12 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "overpermissive-restore-plan" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - all_namespaces = true # SECURITY RISK: Restoring everything! - # No transformation rules - keeping original service accounts + all_namespaces = true } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/plan.json b/inputs/gcp/backup_for_gke/restore_plan/all_namespaces/plan.json index 91d611d93c80e215c42cd6186cac33eedc40cc48..0504d18a272370418dbde9f4ff35e31dbccb7cef 100644 GIT binary patch literal 7675 zcmeHMOON9=48HeQ40O(O`T&~S0^MUDXp0^?7#NC7C+^6WA=&8$LH>I`N`7p{_G~r{ z+D<13ki-^6QT#}Xqz)o6Hj`zvBkNL=iXeV_= zPOJ{X8dFA@i7QS1k({Zl;<1N=ka29u;lJ1zv(Xf7o+w&N^;8uR21;WoVwN)n-e3Y2 zB9pn?P|T9-3x4tPRM6!zV>;$hShGuGvQhoc(k6AK-Ot)x%~CVpO1DjwvBf;_#zd#K zl*w+(i;3v=SWC>3*6S!;Ik3bNR{Voh>E=Iu_kOO8k|mVs<`Uyp>Qqjlk8(@WmCJcO z%gtHTn4Gd{!Q^6$;%W*Hu6pW|+wW`3}jAWUvfriPadp|P-tu#h8-&0-;06c93i^=znJ zGuZISBf}k6zzCpC1n?`tL{GuZiN_-Z2I#p9o&}o7!Yu-u6S&1Mq$*6_-vwRWVa8o8 zF8C%XX^7~T39}PxvZ#>dw$Z97fY{IPzyI+!1}%(;xhqJ`9ob!~=$%rg%F7?vIcj4L zlUYox6+lZ;?d|x%OTRO^$|#CuDLel>L35lUTBmuO<{K6`sGotFMraS%QPc6 z4Hz+wM>r?t4w{BvbUr!YE1+y3|Hyj(mi;ySu4qDu)Q%?p`(=yiS;0lXode79c$|Dj zu+Fa$tv!=}B3%20Y9oNpyyke_=)I+6#HB?)M6O*sCM35BdhCjLM^h+Eb< zkkh@5Aa>{yUrwiPS?6e8dQKF%Fe-aTjH>)8H-Dl;I}DX)h)pR9v2egP$>J^fL{;yr zh8{Yu|5pt?};J+&WWIU2w|2rg`9fope1Fu->3)&P?N zWCIhtptUf(vEEMjZUGDiGOuA{JuQIx3_np4o!^P?vwpERk3IC-vVwc@1AOZ4Jf?*9 z`~b;l!=C#d{292I`nOxPSFvnlRoL5WFzq1eWwtG!U7YnTfQuf+dI)FV`Qp0}1ci*R zd+rza-%JHXKgF7H>1Z&zO}e#g}gUuEs(nxksn=rviPsjIVa4}<;^%2Zz{9l!Vs Dqks;D literal 17512 zcmeHP$!=mt6us+6`3H-2@Q|cCiFa9KnL+6&i&z$-&0xnEEC#2osDC}lId!5M$vM}&!y7N?3{QJ+}*07$9Y-~5ywyCx3&bs(Eu`4_sqV*K76Famo@%{x~)6hOf zZy&dO%!z%4ktg$!cNjCqyls1H1I#kP^HU=PeY>z*tbL32k^PCb3#{X<95=8To(h`Y z{M!(Hn&>&QPJpRtU)yW@*1oZ0{59`P5O40lKT*3C;E4SQe;=(A z&~FTg4)IP&N+snmNYxQI(?-8bd?WY9fc^+$Beev_1g)2tgE&7XW5A~jL=G?>`TBWhbYG+ZxaTT9rBfS;P!!r#AFD}2Kb|{cEOV#{?iIv1&h=Q zw0etY1B_>X*$v4|6aA{PM%q!IDY0(Nq%*W=lu=m}SqExeI(rIDmE)p&U7kOtQexRw_GV&qn_XL!r%_4kNPUSpydlqeE zT!VT+e$vK`Fh9TDZ!upL2TIcjbISgm+4)?8-r+g5g%U@5?^dmfjgMGt=P0d~;!|Be zwa=;43<1^hRnwl;8EFw^V@Yj?FO?Z#)CShHZKPysk5-Rb#8X@q@0YjIgHoS5psDmy z@d5Q!`b=FVBm-D6!N!@-;eW*w>Kwh-1QHh`4p~uBTHZE=X1TR!*c97 zkdA42Dse`s4zZj;LL&$&&LHz1EFr<5%B zKam?6K^dv%r!;4k(vRET_4c$n&#vrWb>5e0g?f-$MgUz{`S>}?`Q|oey)AGZ5`|J< zuxpLmm9{YFq0~`Ecb}OIVXjrr) zMUT5Y-bmxMdR9N?|NEAmFlS;6!H9)*A?8o?g?zeCd5Y(FicnK-d)$-Sa`(q2Pg$1h zy_5)Hn`}a3wuxZV*jrIKvy9Cm>0SBtUD}iq1*dZES@x$X$!kufe!lAnmDO{nHLaMkfyHWv>Nj2VWiHN&4ecDOp{moUvX(|b-1~`j2F{yS zt>Z3+V(+|mSt{<;dh%vF2zlIED(uO^S?y0 zao4C++;5Smm5Mtn@}=UwUlsQlQMAHd$Tecbk^P1L9=X)3x+w1C83m3@D*)BV-t+x@ z?{mF%tG@7-jd>0__IbBEsJRkvJ{^*oKuTUe*M zTSeKAyCaO|Q~i3pf7#D^j$QSXOYt)^Xk}p^yFS&`22~cyj@E}fZ&&IC<%C|@15>@A z?18aTvidyG^To_YdF261r)8u2<-UTV)2>`#D6VFsH-$|z2NS0(_d19XT!g#7N-VWT?-DX83xs`NndFfc^ zP_N#T7M|5T@cNk6zjvjTQVFgnL7VLrYn5E;92;6D-ecoC&nm|=FS^|^#x2QZcVAfp zq_$MOSJj%zyQVO&yYECQI8|Z>6*X|3w4GtR@ZIJvkb9ENE1Szt=hoxv8_<878$;s5 z`g;Nm)cbWKs2)7|ts$2qdQ{ytsyEB#JDv1!lrDc!%D9WQ`mQbEBSfF-eS%c)iigwv z_04WDOTu$s;g)ip&2fw4zYXxzr^s@s_ua#7TitXU#ha1N3FqL``8vjXtL`V)v75dl z>$b424LlD%nK9=!zhprV#$7(;IYsVJ5s@y;3xMGxt3W{8Gm;UaxRh z;{@+beEZIR!{-y^Ua#=$7^nDEj$``+GjJBaMSPD>`dtok)ak<>)J@LL^K&{Onzt*9 TWLC|{gQMe4=6n0xKC}M-nyH&1 diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster/c.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster/c.tf index 9a6a0c41f..47698f2f3 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/cluster/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster/c.tf @@ -1,14 +1,15 @@ resource "google_gke_backup_restore_plan" "c" { - name = "secure-restore-plan" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" # SECURE: Same project cluster + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-dr" restore_config { - all_namespaces = false # SECURE: Selective restore selected_namespaces { namespaces = ["production"] } } -} \ No newline at end of file + +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster/config.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/cluster/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster/nc.tf index 5cc2dea46..60c3bd07b 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/cluster/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster/nc.tf @@ -1,11 +1,12 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "insecure-restore-plan" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/external-project/locations/us-central1/clusters/external-cluster" # SECURITY RISK: External cluster! + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-primary" # Invalid: not a DR cluster restore_config { - all_namespaces = true # SECURITY RISK: Restore everything + all_namespaces = true } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster/plan.json b/inputs/gcp/backup_for_gke/restore_plan/cluster/plan.json index a5565c40c6dead833a5d24345e9a9596dbfb9d6f..d58de6e327e199328e61216260d31ab7749994ee 100644 GIT binary patch literal 7007 zcmeHM$!^;)5WV*^c=i&z3s9fidk;M|2nbrDZPgShkdj-&(7*Q$DN2bgw~6DRS$vAc zWjGs$Z(eq6VQel+zLC~tMza~4jHYbBN@=a2xjQqH_oE3W3njFcDc=ZHNylb8W{oL% zZqiCg|0$iRY(jI_J0{Z9N{8QUY0OedzFbQ_7s zuVxJO&fkuIW=5Ii5@`rQij&)hylXqAd-FGV!9u>$)C1pqlA(lrt~HU-T!gXa1ljrjIIUh0Stdx6h-hMfW|ltWhx?u!9tTm1XTxxnecC z&npzyKBjV==<$2js2h|iD%j0Syb^l(;(%DfMHowps?E2aQ-1ZC&KzOoZd3rlQ&6QLX8uR@J zAhvMSNd=d*4O7=i!DUtS8GeUy!dp1ZW*$rqSaAQX@nZpadv5RZ>dOPj=Xhr>$oY0# zd_m67yXSuuFA5;wDP+q5fWEvP;D8zy?Di!l&gv`LVfdj0v&hxKVk5 zyEMI;ei~j)hSQJVC)3&0=h=tp4-lI4kAkh3Q%P!Ij>!upyY>UjJa`E-W4?c=-~9nW CdLEVl literal 8286 zcmeHM$xa(V5Uq2h`~>G1W3s|mzFF z-L?1Y>Z%{#zuBG*ZDw;jx2`R%uuB`@X<=jhJH_ZR-W}VwLwvu$dl|;(nC@s1JzZK)8&|B&N8Nb3;97+HDmR^)Z{<(w?W$_|N5@%9}5k?oV;T$sUrHWX5G)iUB>FP9v)fe>l*icuoOg+- zHheULT--0(C8W@WN2NF8ic#LeGoxi0G@!Oi?1gp~0q;wHlY*q`V_hnH>oz82kselv z6D_+rOrgUB zFUI!()*s@Ndwv}7r@#nNVu0`HQIC#RsaYCTt{-F5u}k}d_(ffWAHsqv^;DXwZ)M@S z-rcl+#<1oh=ttxjz{2^iuX;H5l=$xwpOPWxQNX&y^C9dr3Q^;@MK8pCynvsGPma!R zIr=I0uwz%m!^ng2Pj3>>W}wff>%cX&^!@azIxv=Ipedv~u}@|ET$Qph-iYmvUsY{< z#ril`iCd~qm4AxFsU}lMwVi7^vr3W3CoH9(T|Pz&Pe|HO8g-#HF^rZ>ap&$;>w0Q8 zIUntDMyH?Ukv8q2^Dkd>89cfQ=R*P6xq{eS)$A_MKZFKPPVS_B_#BnEKuvDSI9NYx zo*GApS3LcM^0JeATS!As(!OI@$+2zIX;lvcMYC$@%{%+g?XIeP|3{2JR(vvFWkmCn zs4HuxsKktjIUqAY-ID!<~I^WOp~=XS!;m|MHLdpM2bF5 z*4kvP%kuQ{xKPd!&!qzBIz_dLvGNt4eopO@ud-Uib?IHQnjJzwvZrZ`;T&XmWF{!eqN0(`1>EJoW9aqN+yozY*bENfc-6Y&{q?Gpz zRL2{JDok3V)6B=c=fvA)(*dE!bFbXh0ZIK_gdUG7otu2gsyQQtNbgl@-5wbo+wXoH z6(6B2tMlxJ5aD89>|ebf3e)p?mG7&EXuaN>$Sw2qy$@-$sgqF8llAXy;*>^fJr29{ zB*Y`Pq5Fri%-#*Zxl3Y2YA?j+96i8o-CfqWVudUAK+_#XKJ_{kb@cW;glOm7@9!{r zeVP01A^mIC_nD2bny#)kd+yq~^?TTk&|Y&E5}X51bRHa{=Y43e(Ov4`yM?DC`w)H~ xhkiIekL)96tMa6N!ZqYlH=b17K7QtrI{Of+XXWGS>#A?994%&CH}>3~*-x$^_zwU8 diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/c.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/c.tf index ef6cf52b8..5e815bca0 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/c.tf @@ -1,9 +1,9 @@ resource "google_gke_backup_restore_plan" "c" { - name = "limited-cluster-restore" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { selected_namespaces { @@ -11,7 +11,8 @@ resource "google_gke_backup_restore_plan" "c" { } cluster_resource_restore_scope { - no_group_kinds = true # SECURE: Don't restore cluster-scoped resources + no_group_kinds = true } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/config.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/nc.tf index 5fb740f41..10f48077e 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/nc.tf @@ -1,9 +1,9 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "full-cluster-restore" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { selected_namespaces { @@ -11,7 +11,8 @@ resource "google_gke_backup_restore_plan" "nc" { } cluster_resource_restore_scope { - all_group_kinds = true # SECURITY RISK: Restores ALL cluster resources including RBAC! + all_group_kinds = true } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/plan.json b/inputs/gcp/backup_for_gke/restore_plan/cluster_resource_scope/plan.json index 7e0ed57e773de209ebe2b16bcc1fa8ff814f7920..362dd53bda1e1b5b5dfad7886633ab5320be32b4 100644 GIT binary patch literal 7979 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 diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/c.tf b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/c.tf index 9bd7fa58c..3696b1aa9 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/c.tf @@ -1,15 +1,15 @@ resource "google_gke_backup_restore_plan" "c" { - name = "safe-conflict-policy" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - # REMOVE: all_namespaces = false selected_namespaces { namespaces = ["production"] } - cluster_resource_conflict_policy = "USE_EXISTING_VERSION" # SECURE: Don't overwrite + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/config.tf b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/nc.tf index 659f21c99..eec3cb82c 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/nc.tf @@ -1,15 +1,15 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "dangerous-conflict-policy" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - # REMOVE: all_namespaces = false selected_namespaces { namespaces = ["production"] } - cluster_resource_conflict_policy = "USE_BACKUP_VERSION" # SECURITY RISK: Overwrites! + cluster_resource_conflict_policy = "USE_BACKUP_VERSION" } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/plan.json b/inputs/gcp/backup_for_gke/restore_plan/conflict_policy/plan.json index 8b9ed5cfad07957347078701df409d01ac6bba5b..ad923f227f418fdb6e76484bc35d390795df87b3 100644 GIT binary patch literal 7332 zcmeHMS#J|D5Ps)p_&G-t4vD;RRH#BKhyp@XmF4U@$x^SqvUdYjl>g2*_8v{Lg;07$ z%~P^IX2vt)IX*Ag#Mo5id@ij^jAkP?=nYwi<&N{9b!YRptgK0TLwETZ!wj4&lE~PsA82Evi)Jzv z&5;i}tT|&TF-cnTiB#c05?|o>Lq@sle|&q`S0)lUl9@D0#eCbawW!6dHs@v-CFvtKOor)8XB?O7LqMHtXdw(R8n9; zn;07!Bl)ow2f$QimdNNyG7VN#%Ini*!W%YlDGx(-^cLr|LnTqpGlQQCQ2cUo$Pd3A zoqRqze#gHaemXh&a10h3J1d?pGGy`7GpOPhR>kl%GGxV=ChG6F;au$x9u&mWW@T#_ ztQHyz9|??{R5(5ui7bQI!F+2|HP7JHE1%>5aRIBrjAu&-2(xP!?iR+l#l@g)n3)?@ zq>{%X7mfFqx(f1Ly@HPu9VdF~NqIK)HLZ-l@HgeJzLF=YgiC@D@m#|7rFMz;y2j&M zJP|7^^CKSVZt6QRu$xr^B58I?B01>WW0R_W|k zquc9OZ{C0TxQ}i7*tU`s5bSp~ww)ook?>_sp9wwPxneHzQd2o9d}5}g$s#L7E*VTS zmPpU2GeXW46JN+J*uKhZshBqM`@YJ%c6CvC+`UwJ-pzTT&$ao9hGWszY~bc6Xe+3z zXad;dDfV1W0iry<|3H~89Q9{GC3PFt^k-06QRxi-Lulc3NzF#SAnmZA{!8Om8KBA= zk4NooTHU=O`zCVEzWOe6@|Ia=UwuDpWMQ9k)`6Z4fMK6=fIpQ8+)4|zXplZ~@;kwG z2v-Yvx3C@vq&lgFU8;;6aJB$3>t=6Ynv9NKlrr9y8=BCU|&Q4bqy)CEVw4f1gZ_t-9ok%`o^YUvX%{A&{7yW z*v3f+AP0eMDm2pE3Krf%t`!{z{cY~UCb`p9AbN=|g=nomYuq<>c_S``Itgdn1)mC% z-mz1yl|{GiQXVp*X9ZmRG{co29t>Y}4+h=g^Us6f=-}n(*^BRZ_n{Y-3o)k18TzTn Vq?wXU&xI!q05j-7eY9Ub`3*WKjd=h7 literal 41472 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 Nti0Q+y=T*d`X5{t(ewZS diff --git a/inputs/gcp/backup_for_gke/restore_plan/description/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/restore_plan/description/.terraform.lock.hcl new file mode 100644 index 000000000..5698484ba --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/description/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "7.16.0" + hashes = [ + "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", + "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", + "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", + "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", + "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", + "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", + "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", + "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", + "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", + "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", + "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", + "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/description/c.tf b/inputs/gcp/backup_for_gke/restore_plan/description/c.tf new file mode 100644 index 000000000..dfd958657 --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/description/c.tf @@ -0,0 +1,13 @@ +resource "google_gke_backup_restore_plan" "c" { + name = "c" + location = "australia-southeast1" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" + description = "A valid restore plan for testing purposes." + project = "PDE" + + restore_config { + all_namespaces = true + } + +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/description/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/description/nc.tf new file mode 100644 index 000000000..c2d840ece --- /dev/null +++ b/inputs/gcp/backup_for_gke/restore_plan/description/nc.tf @@ -0,0 +1,13 @@ +resource "google_gke_backup_restore_plan" "nc" { + name = "nc" + location = "australia-southeast1" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" + description = "" + project = "PDE" + + restore_config { + all_namespaces = true + } + +} diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf index da323126d..dbed6bcef 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/c.tf @@ -1,14 +1,15 @@ resource "google_gke_backup_restore_plan" "c" { - name = "system-namespace-protected" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - all_namespaces = true excluded_namespaces { - namespaces = ["kube-system", "kube-public", "kube-node-lease", "gke-system"] # SECURE: System namespaces excluded + namespaces = ["custom-namespace"] } } -} \ No newline at end of file + +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/config.tf b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf index 071a1776e..ee0b6e205 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/nc.tf @@ -1,12 +1,14 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "no-namespace-exclusions" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - all_namespaces = true - # SECURITY RISK: No excluded namespaces - will restore system namespaces! + excluded_namespaces { + namespaces = ["kube-system"] + } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/plan.json b/inputs/gcp/backup_for_gke/restore_plan/excluded_namespaces/plan.json index 4041a310517ef7ceb7f46f1eea3bbd8607b97f05..87bfdc897fffb0c2b811db4484d624641672c41f 100644 GIT binary patch literal 7133 zcmeHMOOM(x5We?k_{?LW54D`zdk;NzwX%#eK#F5Wc0!8~|GnSXNhnLUVz;YpQ8_{U z7|$!7Z@%or!udi~azj4k&Wf3sjHY5BD)L_O+|kVB^=N|0(kN>wlN)7f3Szbs-nmK^ zE~^d2M+&a?n&)nJLS>n!fd69Y+|rO-u1U_7Ue~3>MCCk57CF+84IvOA3T4%jGS*~U z^1$!6Vx3h5uVWddcbhyTFPkw>%RE$mJL;?&bOwIUU&$++1S#;j^aLHoSq z(JoJ7S}m}kPmL3gvHn;K z12ENwMLWC5mnn+IM1O`-#lWUh8e=$)G2)VUm|Rz~bokk}MxCr{PYBv^d~fey_z$eg zkXIbG_88>P(WB7tsVj!vpt##(Z}*rTRB4Y$DV6lK?nrtXY!^C@q)EC2GVlj`cx--D zc|k}+2x7DMNO!U!kC}GJ@}BI&%GN`_~maa zQOHZ&XYrsWrWbypwLZI)8*N?BX&AOBCB^kJ1DH6g*j+EPKPwry%k0a#oGZoHC9dVn=tR<}OG|8$+m4mXQg z1g`^;-2cn?LjhEuy!L`V| z1Z#HU_P)~19nL_cLR^bPtSIq@O>d^}hBuSp^zE0)bawM$_U8Rpe3RiX5nDCqiz@Xi+7+dt SLr;TGb|5>@;l-w8|LP~nM@!NG literal 878 zcmbW0TTjAJ5QOL1#6QtzE3{rveuq!KkP5V5fHvil5W`B0A*Fbg7)*3*JqLw`51$&zMYCAhRQK2d1TNp(ib< zvgUp$GpICHL+^%ot!H9m`oySl3vIdW*p$c9iky_pT9d#j)wOPQr-AxBsb-uL9eB*U z0ac)AMeZc%j8#uO+`SGiEJM|8;Mwtrb=+@-_BpJ#@U?3vudJq1vE#PmH3}RfCaS7J zuj)gGgt`TDh&n%KSVKw21<&Y9W(%gG-x@Bh_IUn%N|%9U4_6BEW}K{~g>4V4bw@5y z>2Gc%?8*P8X-`V9R?^Mby1M!PeWH=0y|-glZtogg^2X+DK&~6MAmcaXbgu`#`$Tj0 zV#qttBboNK0O$SK^VRL9tC;12%F~czw_M+wYj>Stx4oCH;eU-C^DHJIdcq%ct~0#@ D3+|Y@ diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/c.tf b/inputs/gcp/backup_for_gke/restore_plan/field_actions/c.tf index b4569e6cb..8aa4b73e7 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/field_actions/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/field_actions/c.tf @@ -1,9 +1,9 @@ resource "google_gke_backup_restore_plan" "c" { - name = "secure-field-transformation" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { selected_namespaces { @@ -14,7 +14,7 @@ resource "google_gke_backup_restore_plan" "c" { description = "Remove service accounts" field_actions { op = "REMOVE" - path = "/spec/serviceAccountName" # SECURE: Remove service accounts + path = "/spec/serviceAccountName" } } @@ -22,7 +22,7 @@ resource "google_gke_backup_restore_plan" "c" { description = "Remove secrets" field_actions { op = "REMOVE" - path = "/spec/containers[]/env[]/valueFrom/secretKeyRef" # SECURE: Remove secret references + path = "/spec/containers[]/env[]/valueFrom/secretKeyRef" } } @@ -31,8 +31,9 @@ resource "google_gke_backup_restore_plan" "c" { field_actions { op = "REPLACE" path = "/spec/containers[]/securityContext/privileged" - value = "false" # SECURE: Disable privileged mode + value = "false" } } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/config.tf b/inputs/gcp/backup_for_gke/restore_plan/field_actions/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/field_actions/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/field_actions/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf index e4b9bcf5f..9609894ae 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/field_actions/nc.tf @@ -1,14 +1,14 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "insecure-no-transformation" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { selected_namespaces { namespaces = ["production"] } - # SECURITY RISK: No transformation rules - keeping all sensitive fields! } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/field_actions/plan.json b/inputs/gcp/backup_for_gke/restore_plan/field_actions/plan.json index e5679c0eb9a8f183308f5cc5d5b71be78fbf838a..cc3a522e06ec076fc706cafc80928f370f55512d 100644 GIT binary patch literal 9141 zcmeHNNpIUm6u$RY7;~0Q%S8%Qw;)X~-2$WNp@u<>$wz5ol0(dpss%y+z2BSR5}K4O z$4(q0L;%N}<;~kyZ$+X_Cd+V5#wwkQg_xgRh?ywK7|DCRo%xSvb8Hr=%yWvvwM;9r zVzCuQ>oUxAT&3hb$?D2Pymz$~GL8*d{4SPSFH;Jaw-nyU=(Z|CY?Rti$RN)mzy=V2 z5Sh&7l48bWQ}Dv!t2md-jL$KQ!sxY%$%OTqp{25=*_^dhohcoxq+O{)))+IU^*d2oS%AbBUi?T=X@d{Hybn?x$r8-8fyBO%sgkGQN4X+t%Xv`W zvH_zSlZ}ij__$c)RhrHOB?&;OHHE3Xq15r0F+6RtKXnAMyuhJ_C{0CTHxtcq52nEa z2gcACaE$TCSrCA&Ml6xe6SeeGOjE~CTSzBZ|4K~^%h5?ZFuP+{%T=%Z}#pa+k&CAz2ha(hKX} zR{N&c;oc{UJFXxj2<>_Y1R>0G}5IAwxB4e0lxL{{$xX_71v*86k7o$Ds?)0 zb-kNy`})@*7#Vs7yr2uER5@JB)pbDm8b6&m{R-NEG(YkiZ7wN!8oGs1Yn2k*#fj5~ z$FTFm?{D7?_}Rl7cveQ0n|C0F?#iHht;1R*GPSV5J$%OUTBlV;VJu78`MjQm>^~9S zs61Brk`=?NTkD(~lixc3_@IXz*!w6G(1kNdi2&A!LR~aeX=}6PJB$#Z*p=BHB8=w#?DB=i?+lCfL_kP(DY#HC38* zK00Mw?11+)a1UBnlhMCOrTJY(+JoX46r59-JFe~WRqA{;G9T(I?uDBQR)UR!qjvV;R1}dO-)58(4qw_>u@**3#;1I2mVZsKK@YE3iMv}s|i*=xL zI0SgFmw3R%-y4AqL3Km1ds92$J4n+6PwB>B__-af_`%)Ck-ek5-EKIk8@b;O7yaz+ zi(m)29XZf@9MauP%}?+ihrFNRJRa~cfopB^#1&3E9A~ literal 12746 zcmeI3-%lGy5XbkqQvV0!=Nd!WrWJ2d)xPvs6jgmFicSv3h6Ze88yXblUvK*T?0DF{ zGY5CXRzN*j=O1^wv-5jqXU8A^eII&Z9A;r2&ciS)LlLgRv3@PWsqRko^g!2s*bUG0 z`IW9^d_LD`pI1L;KYXp3`>UB(nll&NVR#eH1ZAQ72LTKw;V4{a?F&7hg}?ReNbC4h z=ADI0-8F2+t6x)%>1*UHj3Q3`@J)Cgz7OApJ-zzjM8A9CgI?f$p;<#wG}YKqq|>1$ zJXn1exo{q#UPe3}kGWwoGIgAtx1#_hPj4*gm1++3CQdt2n(CTp^k_9=8Ll=&N_iyyUIC7*Jwi29u4D^&SDpOK^W)z@1$Q3_ual=C>nToPAy|C3|$z-f| zyufMnNJZq;8{Iq8e8!vKFrDdZTvgZL9rldIx;HbM!K0z0=26T$V0Ah49Gj}djqgom zew$4#B5nAQV@Z504516@gBKRQ(B0&f-4~l5tNKVhxcSFs9uX*2zk?l4BPNr`UH588 zBw6}GJjHvt@6NeYmbQDgC!vh zhd<~Zp5Ogjl^UP1{+wC1T24=O{oGUMluU(H{i^xMDnvBEye&HC_@O<-Pk3k)4MjCx z4o>Et>F!zUbed(E?CYNrOVPoRcxo1EnZj#DTI2a$S_~&GuI8)N`-NV3B`V=9naPeU z153xM(ZijnkI4N}a$QE>fPN>ND&mObt&Jy^_dvyY)I+#-vZjM*lUe(#@MHKj{2u<) zr&%>|(a4xQE98{e}shjslBk*5P(~g69 z;NwTaFY^maapqJ!fOm_i>jQnCibqg6$awXWMj$uiv{Ul4Mqfu=8LuStdAN&h5VMdJ z84(t`6ZIDfneJ>uJ70!h!i(@j1O2S$cZy4=(v53D!?N)*@APh2N|iRFsLX5Zk4y-7 zWZ>o%n(DKSzS7!wZLFmb53x4#K!cKJ%=IzkAu!0$(Zf-EpNIzcqE5$puCeXx1n&hO zETc4xlDEKA~_>}l~zsGRx zY-(i|HJ%RKhkJ!hSu~XdxXgR9k31t}ze@Iw*LS~x)pgYYv~si6ft=TPXybFrN1gvY zWnZjL{2&^c9$C)9y5AEs+T|J>3i62&fso&pr^@QftuCAW2 zUX%X+)Duz;T*S)iTkUFQ;UB$wPTZ!Fz?mWQ{M6;P*ko4Ael$OUDCdJ-{mJ)S)ha+& zU1(o@e>zowZB;F{SzX}l*LR;~8%R$~v&r%8ETufIS;f(+5|^@|vbEX$e8*edQZK|l zQ?07J53U>ERTMwR`CF0_wJ6iv&gS3W@S!%zOLzLh!} z>{K}Ifjw$sk>ySro9U;yRGi@;adwR7_i-6@^(s}aO zsV-xEcSY3btX5!~Q`)?z$yUlWxS0l}6XtfEPqtoJ|C}zgoo+Ecr_$nd_F^3tbM+$D zb(j)Co9{-zzTA1^9H>^|?(U&!!mC4Bq|tj@UCd)f`?z1&3de`d2V_?3+Go)hj->hH`~LrO-^H3)lQbYOJ|#$ z&ns)2(A#?6CvV%PpT}@2$Npy4ly)Z8caL}V3olD;=I)Me_iL>FkpBu`k6=NEq5XrP zZFekM#|wPD@5XYX^Ob+<>Aw(ry1rGv?!G>G-wS`}dagX{nf~)|pldJuB?v(A?#yd_ mvwuDix$;^V5(GN2#ZIZq&xvjHyb$`QI~;fb diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/c.tf b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/c.tf index bdc2d526e..028231c78 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/c.tf @@ -1,15 +1,15 @@ resource "google_gke_backup_restore_plan" "c" { - name = "safe-conflict-handling" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - selected_namespaces { namespaces = ["production"] } namespaced_resource_restore_mode = "FAIL_ON_CONFLICT" } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/config.tf b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/nc.tf index 84e29a028..d30c2b0f3 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/nc.tf @@ -1,15 +1,15 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "dangerous-conflict-handling" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - #all_namespaces = false selected_namespaces { namespaces = ["production"] } - namespaced_resource_restore_mode = "DELETE_AND_RESTORE" # SECURITY RISK: Deletes existing resources! + namespaced_resource_restore_mode = "MERGE_SKIP_ON_CONFLICT" } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/plan.json b/inputs/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/plan.json index 0f0587d6f626a82b4ff5e0d7f3c2b5c2678dd01d..3dab02c60384b58ff929b5eb8b82956a4320cfed 100644 GIT binary patch literal 7332 zcmeHMTW`}a6n^Jt__>$0Xh`%8jSWqVZ33RCCd*CSHq415J1Lv0{CB=%=d!jbj4{Tl z^{Gv4AD^4g`TS+crrN|J;|pnQq!Tt`gWiyJSSF1TG`2D_c-0~Q7f~n;FW(tCi)?0Yd$m=)NcZQ$&Z9t^wC`nOp$+CT z7LCaV9oE=bYD}7z`vfYt5Q!)3_+18>?O(n>?kgRL49>KDfpH^LB)afNHkZO?gMPWn z_DR)H+Q399O=qJdSE|G0bP7??LUJW0QaS&UhTU5Gt}~G01rLo_W^&1j4y&enF_jjW z(5A+Q$4Gz7g#j36Y8qItZm2&>Hsc?byyOhRI99_gYtx!>r@l@mIwlZpCUbTY_ zG{tv(1;cMJD@0yV*s5)4pneXUeX8|kzMQ-}J>wVW{OIERpNPC&s$YorU?JZe|nU(wQ z4x6$}X>f04c92NVrr_V()+c_{7IIRhe3fG*eak9Wjkx7PLJdtS8Kpq|! zh^Yf|OSVUOEvRXu$L~?z?x8%F;yh2T6a531jb+*FA?n7jEX~PzIy;n z7nbg3-X--Ftht-PWqIW@{P$&r*N~cxT*2-z@BTaQw*{cW#4jCV?;6N{jDE96-(^33 zE*)o&zMD$-K=i%uJL_c62FbARJK&&77H)-GTQ=Mu!S^S*`w+M0dv9(W8Aw>Ere3P9 z?722icazHCN@^N;3R=yfXuP~9_w4Rl&yz&=7V~QfGPki&-lPC3#6cr4YuBbF`42gr z;JX5SBEY(U2df6r zQ@4oQAg&?%K4)Q5)OeMMF2I43to2VC{~K04N;&~2!M0t z0S7-$apZ>w!#CZ7L3eogbub(qyd515zTvYBePy{76RMp4P8H}lRkFEv;j;#a8Qel$ IwJ%=%1enu|OaK4? literal 16802 zcmeHPTTdHD6h6w{xE}=gjPffB&&98`;<ex5-o&8|nTNj^>o#KAW-s3~KFVU(Gj4IR}20Xpj2nRu8C#XG~)tK5lwDTIDGO9*o{}(s?IUM56HTWlL_W~TT9^pSh zX$|^K0MRzCl%!Nrwu4mdfHQs6JH;KjHv#lJXd9^|IBJxhq7UM{NXEK>uTeT8A9ETz zO(i|KjMW%<9eLUTf5w1|x*`o>4}EY`cvGe*;T_ylQl}1^kb;fJQkeF1!>>MBJ>M?jS!Y{4BS+GdG zK&#hyc8>O}FS{X`>7ZUy)<`?*GbPronRJF0jWQ~WBI`h{OM6eDX>we2Z_D#VI#pvd z;wS4>1qq}s(4J8@D(D#HsDf6geJ-_vU>&(tFHLJh?c?ZYVVr2o$cL!kH7H4&Ix6d!^nZ2~1(ejo3g5RIQ^#z{1#Q#5L+^hica)?s;HbH^; z9QGPGaz-V6g>4@cq1_|RQ(JX=t9cqo*EGj1FXik?T^oYl(pmWqN0@uX59%A`x`wnx zZ$lQ8RMt%Eqp8g`YLbJTV|wVDcyK0Y(&RRI`j|dAM^pEP;rC=_Z%FHiP1D-kwSA%; zBpo!Th)ymivS5?}()SEha+|qmZfs{;)n}8^uFJW-`2Tda3E#uijuE7mv(|AYLHDB% zo04UE(Ub|!x|{cPD_9N9P`Nd|e{VNJ61|7w@8)wz@ptLXa|S5>?)(~Ok-y8io4zb* z#ujz)d_OzS_qiRw%RPXPdjKEp8NA=;xc-K_-|_5K_~)`wyx-`P7w>oV>b!Wr>H6DO zeZ~7-wHn;4_sjKPx-Lqi0*qAp9OtXpyYZDDil^*w+`pfk(wgxM(K*H)oc>!_RZvH0 zYZ)Cn3Xvg3`4odt#K>3Cj5{(aC(q9NO{1|fI?qy%d3d&hzTi3$xe`fcY(GZE^C&{` ztlN3kC6cTdXNe>;I@pYDr?%~JcnfY-OCrm67kdP_~rvvpme+*1f%5d@#RAmDaJS7O4~q1dWr*!)?kd&>PvdAKF>$^IqFm0VP0(c zr=F6O2IN-JZNfvJ!E&e{yDk6N$fG#;bgX*2=-uPD>_=fv)!e)OI{+BXX9kex1odVB zzPCVc1!(^s0AFGF9te4}7ns51!S3O`0eki>PABZ*+QIin>|O8TcOOr?`0e5i1An5n sGQ~P$`3`XDjRx!`&0y2wuy>x#)E>mVT&D;bFY=SgG0XYhzO*mwKT&lPX#fBK diff --git a/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/c.tf b/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/c.tf index 96f45e224..df8ded4d0 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/c.tf @@ -1,12 +1,11 @@ resource "google_gke_backup_restore_plan" "c" { - name = "secure-transformation-restore" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - # REMOVE: all_namespaces = false selected_namespaces { namespaces = ["production"] } @@ -27,4 +26,5 @@ resource "google_gke_backup_restore_plan" "c" { } } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/config.tf b/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/nc.tf index e9dfd0b8c..9609894ae 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/nc.tf @@ -1,15 +1,14 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "no-transformation-restore" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - # REMOVE: all_namespaces = false selected_namespaces { namespaces = ["production"] } - # SECURITY RISK: No transformation rules - keeping original sensitive configs! } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/plan.json b/inputs/gcp/backup_for_gke/restore_plan/transformation_rules/plan.json index 4767d865a24aa3a90a9c4588dcf046532a873223..005e8ef35d6c7842e6fdc424cdbb768dd4278054 100644 GIT binary patch literal 8470 zcmeHM-EZ4A5P#oa5%AfzVhpo*#mf@1bjMW< zmMss=XzkKMXSD+V2v*ld(6_q-<5_0F;%~OmdZQrS+(WwN;=Zm@{NS{Klt|75(ncak zf)%{v8_0;0eMK+Ex8k~z7qpIOR7US)1}1IZ8Q4hc%zoBNHIq8oa=Vp6n<@#kaibMm zD0nCG?SyqQHXIYD%{fBV7D?h0p7;TTv&o;ozDtxA+~H-~gyVO^mE=>r54Qzw-8^Y_ z*@RflzzQQPTF#bbt<;1;o+Bx_gH-V~D1X1i;k4y`>IEdc@P?MmnHtz}!s7BkCUSub zhS=!c81av5Q2_iDVG+8_fphBF|S02%M#tq-3l2G)PD)YlkVWl1VFiV zTGa)l8F##MCMT+Qenq;LWhToF-FU#U^?K2k4&L#6)byMz04*E|k6ze`ZSXQ5QLi!-c+Vh3>2i zI5ug{rR$#-wyYyJ-rTBxz?zI(>TQIZ zZd({#Zv&C2BNX^M1c0=ypV-oe)(H!!K6-x+*H{2u3#!nOc~tO!8k$33y}pX-ITDU* zsnsN8*OX(V-8X7oF{OQxQtP{nh@)`yDz0njx~%W;O$uEyvJk#&k1wwOpL47rae5CpPw8ZYhYE8Y8UtZN=t+%yp!-9e zE^)L+Q##xyXhzib3kMc_W(N_ecC)4dvV+qn+!P=i*x(s$m?6P>lF*C_2@E89Z5wB# zb=D{Nq?tD2;-3sm`lR9rrOi|0j0gGc^}QL*bcSezDGzQ5W1fK}X9qvWV}GtQu)i5a zbpx0Fr01(}j96YY{vk2wZ(t_-(k=aGF-FWNQMT7$je*k_HODi0;M<`zc|$)}&~$Wh zyZC8(JD)Dz{54-JZ+~9CS^R^8L~7~o`I-Vns6vG#qI$}G(2e;!7{{fAQ BGjsp| literal 19132 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 diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/c.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/c.tf index 5ebdc0a09..09206411e 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/c.tf @@ -1,9 +1,9 @@ resource "google_gke_backup_restore_plan" "c" { - name = "secure-volume-bindings" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { selected_namespaces { @@ -11,8 +11,9 @@ resource "google_gke_backup_restore_plan" "c" { } volume_data_restore_policy_bindings { - policy = "NO_VOLUME_DATA_RESTORATION" # SECURE: No volume data for GCE disks + policy = "NO_VOLUME_DATA_RESTORATION" volume_type = "GCE_PERSISTENT_DISK" } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/config.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/nc.tf index 099036100..de10dba16 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/nc.tf @@ -1,9 +1,9 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "reuse-volume-handles" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { selected_namespaces { @@ -11,8 +11,9 @@ resource "google_gke_backup_restore_plan" "nc" { } volume_data_restore_policy_bindings { - policy = "REUSE_VOLUME_HANDLE_FROM_BACKUP" # SECURITY RISK: Reusing volume handles! + policy = "INVALID_POLICY" volume_type = "GCE_PERSISTENT_DISK" } } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/plan.json b/inputs/gcp/backup_for_gke/restore_plan/volume_bindings/plan.json index 355c9f59ba342ab999a49a5604b9470868a089bd..c1727a42453a04b19e770396a534e5b74164505c 100644 GIT binary patch literal 7747 zcmeHM+j84B5Pk1w;92*yovGf`m~A~tERQ7jp&1VbA|Z)2NpJvCjYp$@&sl(%$fBLZ z)i}|FPZDuiEOr-*vj;o2QaTnH-%4#lm9Q}z_C~D3GO4wozJs3OtKJZuX(WI4be#b-*Xld}Dt(96wlCSS1Ukd*&PdPd=r6nhkJs+|m z1R_{060w#6X>y-Z!_!kSE)g+}BN?ey+c1!t7j0UuLzC(IUbU-UsQMdWHleR{+IO-s z(fAt~i+an04y*TAXiS-bS_AQE3#@n7j@rhk3m^&{nr48}BlfqpHbP;_CBY$Juq zhW%oe>65B~G`{$8mnfKlcWyf12NV+TvK(P_Y`s|RT zZ?z^YEG$m2r^DA$WRl@DEhW$bV2^_+Vr5a}j&01-?-BgB_trzwtAQbD@2xMZtzW44qJ!&h z?_67Al<-!?9F_OFBMTkbPlN!do{B_Yffuwe9*tkfyxW5B`+P!hJLY#1RCc{b`5^_= zAqF0W-GjPqNA^QhCwNt%2NKNliJq@mv4#OK@N?b|Aho9X8^kse|Cr=l)-b^;S|~#s zJK7074?sWz&a23UCkUcrfe$DnioUNU#E*qOMUg}K1CG35b|Y&}bS~x|y%2qCoOhD= z1aQON&LKdZrsp4_pMxtW4^vC3(c=v=Q=B3vjRvD%yMtkO^vhx}8vi^PzxwSTP^3f+ e-isxrc2_p~Do!I=mzH=q0(FH_+g?cfpFRS_>l%#! literal 17614 zcmeHPS#u*b5bkHH_!EA{Nz6^&U|C>`B}pwC9!RC8ym2lzu~T*uHbv#H1K+359ZBP3 z$D0F(s9Zi~Mr!q??pC+tfByc=<|Zc)E^v$5!l9e1C%X zd3ZiVYwtI^Psct(&(65#CHf2jw`*_g1W-n}zi!0f(Dv*MW1r#q!2ZCqJ&fZ|+3&esaxNg}sUc~zhy}F>NkG8!)r$dc+aP&do z!fAkd5%6?8hUhuM{R?2Z7k=}}PN1L*m_6KQ3&A5*gmxHURQP_2rxj@LqW4=sA;s!( zj&}S-4hYK?v=P6BiPKIg_3=JL>)yDnlrR$)KOU!SqIL#6nctHUE<<o|?Z`ePehDloSI#BM{}{aJh0nu4tE^YuGSY6#DmJr&gi^OQoPB-3ImYZGRc^~D zhd94S;3RF9TkMoKxs2VOMH^Y6pT^+4pgd{gNH4Fh!l;YEtJ6Sj8UUv3-;V8$HRv7g zlRwlr+IzQZb!xoFwh5em!{jtM&RtoHI^5-)vj><<^q2dY20hFy zojt=A*JsA?)C>CjyN|T{uxFaBsV#4XxRdtq;bQHGNsL`ew4Hmm5^ZxWK`&6E?a39^ zv}l{QnyaSCSexrm#@e2ZD3SKONcXOM=VXjoBJH@k+JP^6x{)?x>21WljIi@~`zOTK z8;H7JhG#z@V%|g~UfFlJ{|s^Rwr!2Qc!{}VhNQ&Y6>R)Nu9N>?F*jG9>544%56sTe ze==*(;?C!;KxuiqK( zu#Tg6(&45V=va~9Q};|>pJw)`>^O8MJ=W?!3 zo<&VK^}^RwsC|5mVRee4Wi<>*g*x<6hdhG%u2 z{k*=}yz2Mg*^atRD!Fv+1c~!#_Iyio>C6jy+?Q)Wd?KH~2*h{yq?)2QFx{~+t-7T3 zzy)eOxvuGc8f#V|>z3DssGV_*lt-Ym+B4c+WERvls#K3?gC;BANHkuo^t)DtWeATt`1u zoJX8>%9Pp7=5-R{oS(ySx);l@HsKJl7roO~W}cJH_q#PaLo++SI$6PMg6W4=`Na90 zg7lP3v$30>r15%*#%1+;{s~jIBMwjX)Isq!w>`HjP0Q`JTdigHu{qX{-P_PNG|S3L zX2sKR4+6d8a(SBDX6z*0W%fC{As$iOviSdHum-~{5YOA{Uo;jyD^7{?m1YLD5;#RX zLhIGS|ADOG{RMX5b@1KB)i*e|+QIia{`I4SPu}?*Emh;!9_%aNrGNh*lyvU_Z6TpE Zw$k3!{JGA(GUw)}_+zH)+CH|A>|gdjoy`CM diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/c.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/c.tf index 5660a5b94..ebb0aea21 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/c.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/c.tf @@ -1,15 +1,15 @@ resource "google_gke_backup_restore_plan" "c" { - name = "controlled-volume-restore" + name = "c" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "c" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - # REMOVE: all_namespaces = false selected_namespaces { namespaces = ["production"] } volume_data_restore_policy = "RESTORE_VOLUME_DATA_FROM_BACKUP" } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/config.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/config.tf index b9c23f44c..c5d6ff5b2 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/config.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/config.tf @@ -9,6 +9,3 @@ terraform { provider "google" {} -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/nc.tf b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/nc.tf index c7d53b571..bba92650b 100644 --- a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/nc.tf +++ b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/nc.tf @@ -1,15 +1,15 @@ resource "google_gke_backup_restore_plan" "nc" { - name = "reuse-volume-restore" + name = "nc" location = "australia-southeast1" - project = var.gcp_project - backup_plan = "projects/fluent-coder-468700-h4/locations/australia-southeast1/backupPlans/prod-backup-plan" - cluster = "projects/fluent-coder-468700-h4/locations/australia-southeast1/clusters/prod-cluster" + project = "PDE" + backup_plan = "nc" + cluster = "projects/PDE/locations/australia-southeast1/clusters/c" restore_config { - # REMOVE: all_namespaces = false selected_namespaces { namespaces = ["production"] } - volume_data_restore_policy = "REUSE_VOLUME_HANDLE_FROM_BACKUP" # SECURITY RISK! + volume_data_restore_policy = "REUSE_VOLUME_HANDLE_FROM_BACKUP" } -} \ No newline at end of file +} + diff --git a/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/plan.json b/inputs/gcp/backup_for_gke/restore_plan/volume_data_restore/plan.json index c0dc866c97471c6807e280164c5376c0c4017db9..13d6ff0f8368debed675c7d3b162b5ad008bccc1 100644 GIT binary patch literal 7392 zcmeHMTW`}a6n^Jt__>$0(~#)fU`0p_hQ`JNXtLbIZNnTpvXjD8<-hYCI~TTQFrWge z^{Gv4AD^3#zw>3y=EkNX=PPMlVlQ!J@#CeKr$tKhNJeJODv71#)jKN}iOcQHps{L@nBh{mWfB>i4TEefbkS0# zqBZ%T$66aJjY-pLpGXxBBJqSBKg%e0!*?gsp)!%k;Y>Fa7`H+tq7Q%MODSAF8dj^^ zkW`JOi)@n7bT-k2QavW;bBIb-k}ENj%KMiz>^Iu?y@3=jcxb|MTS!*+SUo+6skOj_ zE;TkhM*3qe48TwwmdNONvItRB%KOu0!Us0&QW-;W^bzN@LM2hoGlQR-+Nh0r^$spF z6yHx*F#IcK#mFlPTfGepG|zFnPrW|mOHf9eTT8>sdZMw&h_I293dUk1k!4Ua1nbUF zvuDWRTaOg(xIl~$w5t*dBFNf>lZ1EN;uz2}jI4|*QpsbHi#FFQ&#?39`-`*lDgSVG zdiiF`PmV8+`OEXOH~jhWi`SR$5QqDh^I4+fL@)e4UWewy)_Jh@hvuhglP9S}c0v$2 zti&mh+9f^#+vM*^O3bW%`(2v+QJ`yiTa49QC?|hANDuLHS(d$DC~|rmRn80f8)eRK zRK;}1>s;-#eW9bm)YQORm2KVDS}H8tD|DCdn=<$6`0dH*bYJKQ_Uu}ryF#s_s$bpp zOQ9D#2l67XHNjNjuW+B}k(DBs3Q^dsJRs&-)ALkLZX05|!^Spu1Gj1`DyjfF9Pr z{uT0vPGGo%3+t&w0!NQ9enyI zNZ~y6dKu_+I>u-@!Tn26c@%!Lvorj0tR6!reS8uH zP6HxUK~^tu?+oo(U$`NgX`^1<)+jrUXIiYInZ^tejW#Mo5jt?xrM;)r)HN=-H`V## zF-2@84Wqy_>1u;gUR{Q<*G3s7<;b93a@!Rht5~mk$$PFKWm40JoCZO%j%d_I9OV

iWtx?Wh)!GCqT&gIXohky~C}uhCzf2invKeF_B+>~LmBuW_F;rQH$r9oy>M zc#HXRw$js5e(KLpQ98AqA*fpZ)U;;3N8+N8meO|mCg6i}CuJy(y5O1!M@gorbbG6L zKBZOZet9Y9QCe*eGS%pmmvD$#Rx+nmbB>z8qM~0RtfVA0r~1>>Cbj$ueUlGjeqAPY zn`zmv_PzaPzuU9$tFk}v>#4o4pK-sk@9YW6p5WIHD1U~#m3@QjZ|x`4c@DcH+N|?* z&f}-xvKKxFvoS#}MLE0M(Ov6Az#=AC?$3gu`$)XXX5>$tjT{%nT7>a(t+#b|Oj zLe%@&)QGP4yPe~z4}0g#cAQzz!;GX&*)lzC+5~6j&HKYc;El#>inXoa9TKk|&LfVL zL=U6*#QE$~d}8`;oB@hYJiiXoICd{Xek^gCYn$WZ2?rlZE1~x{Z@PA(r(8VYxcWK3 zT(o_j@C*3D^m}tJ_(yoWzrYuM8p?_%OrO7a!c|zEZQly>|KkaBEtsy6()a-*n_MN+ zYxTA8yYZX1#cOst9^Pk8Wldj0a*ojpmwyW@40<7qJ}{1S7@`A=3M!JJ*iss^;U0** zJnuJ+-o|LYJREWEyBqWiSBc$~$TRl>VkABHjEa}t%*$4ErbM1guPJdOz2Hu~Eo z@+|-6?#OeTDJ!gQhuHt-&dA^R^qF&&m^1gF+0J+I=+W1$xWu8k7Z6wP?&Z+?nP1y` z>2`bHjH$VImTNzjXxE5-f}dYWtwi2hdM07fu8geu5_=@Mo#}q+5mpOUlC;byN7`m; z{qrl&bw)t3_H++)xjjE-Yj0|+W#1+4uyZVFF4*i@q_T!ArF*{Pwm<)`d6b6I6=5tXD@V#kCqUodY*wuOu9L5u!f~w|{k&=#FJp#FJWEWg;5vGK z=PqsIwema;wR8`Kb>i&7bIdvk)SsPriCCzbw1v&B|go*)}rZTC~p%5BfJM|@(Q62EyWIG*KTRspjecYt4ua~lt{ zvmu`66EkJX?%GP*1HFjK6PorcfeB%jVXeqsv2|49cl~>=;ihZWf&^$j<0X%-?%BWWUcj z;{R5<#`@kOUl9zjqS(X^l!n+kZ`2PZ# z4}19LX9szU9lXt8AJ_Wq*q^AW-DG8aUV|>ZNrAnjF%9B5d#A^svy6GUG7}j`@{H)X LU;WlTwvX&T7YE z2pRjn=63gH_xA43?_bukq0MY=x%I5H%x>)xrNYLjouajir(>xd;eCLo^!7P=hjEXO z>DW7r>{KIfF=h_jo_(_kPzuy{jS`HkZ#S6x2JJKZj(I-LA znGIZ~#NOKn`)DV2h+kq?D7Wk$KgxZBQ9WohMc;wz8Bl9EIQz`4kUQ$ah!sz+&eKny)zLLN!NdGm*PY6-QTw~$>cl(~d;PwG5E zYXO_jA!~{^*%z}bMf=R!Sj`^#U7^GkpF^)U#?}^=Bn4WpfI(}l}Su4Yud_C%GP zOP^8PKer1XF+pn|m~mSRGO%{~cQ)Jyzm%Kw~rLeJxh zF@kA)C{Yf1dFa*Fetxp@gDGan)+ zxl=NOWV~ZGvRt>0gLTAQj-Et`y(sgz+Kl0xAx5Bw2H$$DKmB;KPP@s;+*dv?)FE^q z!4Av^;!K9~uI6g-7;2+TJ;ojxQj&Ta>;GN((wJ)eUh0h-2 z-Nk*-v3*5vTDpgEJe}R)OE*G9iFay78lv;8r3|*&uDb%=ooG+5ciek>Yj5l?!j5W$ diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/config.tf deleted file mode 100644 index b9c23f44c..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/config.tf +++ /dev/null @@ -1,14 +0,0 @@ -##### DO NOT EDIT ###### -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/nc.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/nc.tf deleted file mode 100644 index d4118f550..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/nc.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "google_gke_backup_restore_plan_iam_binding" "nc" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" - location = "australia-southeast1" - project = var.gcp_project - - role = "roles/gkebackup.restoreAdmin" - - members = [ - "domain:yourdomain.com" # SECURITY RISK: Entire domain can restore! - ] -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/domain_access/plan.json deleted file mode 100644 index 0c504e32c3e057df53f5b57ae3ae829646ea9afa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 878 zcmbW0TTjAJ5QOL1#6Q8a6$)PY9X|O&D$s%{ZBs4@G5mG)n^R8k5{)rUL(kcr-I>|t z?e#@H<*LJG zs0>9FxwD`%Rz2}>_d2++3RSm(XU8MfalZ=fOIUB=Yu8R*Sxu*6$8E=J5;#UoR8@pt z#fJ_(>SoL#>inEx4LKc4p2?TY7ED3EHC$Tl@%;OgE(6Oxu4LpbI9W*x+df$9j$ESB z-`wc2C;ywKJ;}jZNjGEb>gN0RiAIk0-i}$hy=!pE8#`nJhPq}8QhpOo_j=%aKy<{- znB5rYkxcuVf%AUs`RaDlRm`%a@;v0&E!X$v+FfVZZSSRP_+MkkJd0U~p6~~q>rC$m CYM8PB diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/config.tf deleted file mode 100644 index b9c23f44c..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/config.tf +++ /dev/null @@ -1,14 +0,0 @@ -##### DO NOT EDIT ###### -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/member_count/plan.json deleted file mode 100644 index bff7d42c672f6ab88e5831399a6976e59eae0cc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 424 zcma)&%?iRm420(__!2#&&Hj@K{VZ%(2y%;d>DsD`!UD^-L^Ih7+>%Zp5= z#W8gsbTr%rXbt{AJ9R<9Iw-49xB)jM{!8t@U5wL&*`5xK4q-}!&zLjO5Zx*NSToIu zV-$|5WMES*cx~Ir;hC>9(dwwHy+*Q+1>Z_+a DCc8;M diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/config.tf deleted file mode 100644 index b9c23f44c..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/config.tf +++ /dev/null @@ -1,14 +0,0 @@ -##### DO NOT EDIT ###### -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/personal_emails/plan.json deleted file mode 100644 index 31bdc1f6ed214b5cbfdfef7029971225996acc0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8648 zcmeHN+iu!G5S`~r{Ry4}1kyHDp3*<)L)C{yk>z3_7i=P9l15d2z3n+W9_;06sB$5( zkb(8?jAwUd&z_z2-#@>lAp;ppDzSu;Ng%h@ZvHkgJnp38c+?r)UVzWKiM=idaQyv}S+uE{49 z+|ZvttJ-s}uAfue*{OT*nveR}{G5FBZJ~3`V3m)r%Tv4#{9a_RFB84zdG0R>(#ES(dR@eojw0qmP+>3y#_#XNHfPU(^*$b3=88*m886 z^VQ0peIKsglaym3aQX6k$B_J7y6Wu9FP9h8jC*-cL7uUU^B1g!*$?g;^}NF}ag4%k z^17PcTVz62o^ysL?Vh`3+?S=d&mD7DO)X{5RI!`qDCIMn{mKz*pZy*f_HYk6z{OuO zvm&F=aM{`vS*um&R5qHHD>j`P&+DSiBzDU#YkxMMd$1k7OCIzzr&I;E-N$V3TgRcz z`Bxu-bi8)U`EKIoHn(b|GE~_Ir1E)qb(}hPtJ1D-3h<Aqvk;Udag-aC+K(07!~=P2YD~=EVqB94e5m&lTzyy+gLbHPy3|4suAZnD7AkeEdb%DdI9GVThL!{U z&zYWD(1*++-jl-Q(JD%tsEi2DJIqF~y$|j?NTJ2Xk%5l?=mFC*Qa>$}eg>U~7{`#& z0I%(XY3M%T?#1{{AZ3_SWO5IAPVpStm?m6z@wkrbXM4GU-nKiD>Q~Uw-U((`@OKJL z8+a0VWn?ulpGXrs*$3SeBkpzztD4{~ylZ-_Fgt||`eGL*TZ)4MO~t-bs`)t66%F@2 zxmAuiW(Sa2o~vQJ&UGh_i0V4VL`SAtP~+?o`?Pz3y|>sh+|)q9F?~cleZVg@Swoi$ z$O^GhSGtjWSDyEXK8uNCqJVzn9yQ>#a7|*dSd-{VKv&Bx4|g_<&K36H6djt-H}oSV z9P7nq#Ty^*D5nE5M!#WxE!2ed?ZMKzT?-;9izGZ~?*_jpP|LM-n=FkGi4SV`AzI?{0 z07ZXV(>^)XQ_b%C19rU3RNke#%)?l8j`R9@TlMgH)U)`xHzPb*v;MH7v-=We<>SwV zc01x3mX(7sWwEmWqAV^uxJ~KEYn-pzc-Ap`C!g@Yg{Zy4r;B@*Yxx3dtAI;z&T*pm idmc(D*JFC0(s_!qPBomjTL8NevC3W4*avwjFXRvYG+mtl diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/config.tf deleted file mode 100644 index b9c23f44c..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/config.tf +++ /dev/null @@ -1,14 +0,0 @@ -##### DO NOT EDIT ###### -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/public_access/plan.json deleted file mode 100644 index ec99aebbd4c5409efb4ab63c13dba85caed008c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5050 zcmeHL+iuf95S?cvej?A!6=+eO${+B6c%Z5*6DMhC;zYJns8D|$IA>3`YbS2%1}Z>` zBFA3u&g@*y%+C1dkMGv9i7hR&g~e7_WH&a(D7P8jrkEY#>RZPKxS!xE+>z(A$LGOL0xXCE2Vf>=yj|isz6;UJ(X_?=v3d(hw0Gc^hyCTAc`ehkwqlv97=#L}(iqQR*>wjyP6yHHjyB zgx>BzcFGj?BC5k)K`Pm>ijiuZ=kVrJWavWPsz=D7sXw|~`oG^q9C=8tWXDEr%qT8p z<*NLLWF=-K`kr}E^nOG+lq<@aqO&FSNBCiEU!4b-X=_y!~TAL z4Y-cniF%D#ULpspT44O_$N3mh!3vG|X3fKjmhr+ffBRh>oxFyEZ`1h z4&^v~X#L|lJxxy5;>sVg)C9UuVF%WHKJQRY?z>w*mTCN|Y85ETYKE<@prt08T=l#a zsqZ_8yJJt`tIfwd9Od(>4<9}y%b18soH&s=h(hERH;W(e;ay$x>G3NpY<{; z8Fk3MrXmU%M@>5c)oHsi(`26u>{P9||Ap$F@$_fA7}k^IT1G$<`}mCEzaIQwr=E1) z?JKA`tFH+z-q|CDTDs-x`^Z|_oRWnL0{O%o&P=ifa?_TKfq{+=e~Wy sY9coV9s9*wJn2gpxs*?QTA$q6{i&+1&ePYlKRvG6Ae`KH_R?P1FPbfmAOHXW diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/c.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/c.tf deleted file mode 100644 index 719f9d554..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/c.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "google_gke_backup_restore_plan_iam_binding" "c" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" - location = "australia-southeast1" - project = var.gcp_project - - role = "roles/gkebackup.restoreViewer" # SECURE: Read-only restore access - - members = [ - "serviceAccount:audit-sa@fluent-coder-468700-h4.iam.gserviceaccount.com" - ] -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/config.tf deleted file mode 100644 index b9c23f44c..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/config.tf +++ /dev/null @@ -1,14 +0,0 @@ -##### DO NOT EDIT ###### -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/restore_permissions/plan.json deleted file mode 100644 index ef28aaa7236973e3a426b192c45ce4f449c43337..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8276 zcmeHMO;6iE5S??S{t2I(gg^@|C-?_FR6P_SE6o=vu^rhCEvoqIZQq;m#@+-R6Nx~D zg+j94-Pzfh**DL#fB*cJKqit%Dv=B%mr!nGj8-NyJdM$Nicep9mN8Q7c3$b*XwfJyOif z@O%j^hx(g67rKK1WRCEhBTOE5MQKx&5#swAy&?8K!0c;C;f`%aj&b}&3z(Ln+9}fU zGw3`*JBExd=9(W&LuV6uFUDsIDWhUUF1L{9Mm&W!rU}=LR_i$Z%$GON+q@I1e&sms zcZ%K&_D-Q`7vGG$YGifMpGXg$9AMlPTJ&~`UG*@xw65uqq4x?hXp8$|@<8LDjHc4> zlxjB4bw!K&3%S%8bMy`&v)UJ+y)1NR95JdpXfrx;)q)!5tJvqhBlzCVmc>ng5p2^& zjHh$_rzT72k|VOX0{zY?&(J!AJbW#Ad3lK|6TBd*g;$%V%dDxq8@gt zt7p2qrqNgUVJtuKNipBBi2jJNGx~O>h|750#H0GSyf3CEDuwbd3*;ld?hl<}MAOU0 zr&7Zfp|&FwF^-XYswhF+AwDxZ6Nk?b|3upvPDhI)^*p2=N9?5MYD+SdRP9N$r;pe^ zM=pq9Y38PVqlm*2BB9TLLc{{IGr0+ST1G@a`#IDh;{Nfb>Kl5-asf}Tv3uvQ0A8eL z$#IzFjQ5bO7{|BF7b6QJ0rb5BFBhdzArHnnbr7yNx6JqS%0>jX>n%tyo8!JeU3+|B|lr=!zL%>`0e}H zuA999w>;2C<>%yquK|}^=D43X&|R2gnY~-=T(8QM2yLwQu3$rE=Lzz|6uE+LL5@W^ zoZjSj)j4jIU$-)Z_mRmT!8|c3nAg+R&@4|_wWF#n;fIbIu}^Uss}Hp z!fE@d`l`uJczaO2nIHrIf9jyNXMYC{jri6#!H3^uMCChtpcP5hAs)J&AwCkFTs_pu zvUTsuxiuE|qus2U+3*?B(1P4}UEz&%(W-yO6*$rt=S zK%PIs{Wt#~%QuX+dc#8R$8MpQ-N92zwfaG8QaW$DtQP3^GgA<~>36G>lzjP4-pU*K E2ZO%TQ2+n{ diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/role/c.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/role/c.tf deleted file mode 100644 index 7b78e8747..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/role/c.tf +++ /dev/null @@ -1,12 +0,0 @@ -resource "google_gke_backup_restore_plan_iam_binding" "c" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" - location = "australia-southeast1" - project = var.gcp_project - - role = "roles/gkebackup.restoreViewer" # SECURE: Read-only restore access - - members = [ - "serviceAccount:restore-monitor@fluent-coder-468700-h4.iam.gserviceaccount.com", - "group:sre-readonly@yourdomain.com" - ] -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/role/config.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/role/config.tf deleted file mode 100644 index b9c23f44c..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/role/config.tf +++ /dev/null @@ -1,14 +0,0 @@ -##### DO NOT EDIT ###### -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - -variable "gcp_project" { - default = "fluent-coder-468700-h4" -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/role/nc.tf b/inputs/gcp/backup_for_gke/restore_plan_iam/role/nc.tf deleted file mode 100644 index e9dc6453e..000000000 --- a/inputs/gcp/backup_for_gke/restore_plan_iam/role/nc.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "google_gke_backup_restore_plan_iam_binding" "nc" { - name = "projects/fluent-coder-468700-h4/locations/australia-southeast1/restorePlans/prod-restore-plan" - location = "australia-southeast1" - project = var.gcp_project - - role = "roles/owner" # CRITICAL SECURITY RISK: Owner role on restore! - - members = [ - "user:contractor@external.com" - ] -} \ No newline at end of file diff --git a/inputs/gcp/backup_for_gke/restore_plan_iam/role/plan.json b/inputs/gcp/backup_for_gke/restore_plan_iam/role/plan.json deleted file mode 100644 index ee665d7790627599bf9fceabbd84e1b9de8601ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8486 zcmeHN+fLg+5S`~r{fRu|gg{H%JkdYsL)C{y$Vzh~B{w+^EvoqSw&%=vur~?8fdZ+p zq7d7=JD%N{IdgWFKfixTO$IWPL?+UaRARZ5KJFGW!qX{QTlhAmE=Tx1z&F+Q1igLS z?PHp9jFHW3_jvLDoPfeRab~iR>uHP?f0pXn-0RO(XobUhM` zT;TZf?G(0WsRhmg|CdZcm%dEVnOv@uQi-pS2-TtBnrCGC<;@G0AOgzydw00f3FLXBkR(f^*)?7bZ!_Y^zM(}Zp{zX`E9>zI z(il6GVS4p4E6{!xml0a5m#ufG|9w!2h(y~H2W`CHQ4hn4B2v^>wEhA+^yPD!uHtRO;6jkSIjcZ0nf=SUqTkB zxad>va@V=&{@^CL>b_#7@#yP}Um5BSkQ;``6WlvFFY{cp&KQehyjNIHGnN;kPuPR2 zGsw8ykDkIg9bAp^>9N-9N_eb&;XK+pYM!5SRpK*N%hH#AMEnJ<*SM;{Z#9Ytj ouArCwR{^CIYbK0yO6N(N)g{ArW&QNq4Z*0Ls02wJyN*?J?rrt+$blUck(cg@u#x91>Y*2(D9e| z<9df^O|ai{aN5Q%HLs{yZM09N14%~cca1wrdyZ9gFgD*^4k!SE= z@w)3i|J&dlv5q)Kgw^qOM?MsViWt;h;`$sqGl9m?1{67|Gch!01T7pn|3K?nMbC08 zT4w&HRrIw)~90YmHdP@6XA#-V>yH75zlAP z@E$IrZ~|+kx1rbl_XtXqzri(?ANZ#4h`VL%Ih!b#yS({4THlj2xV;zP>t!pX_md$>=-l69TUxu4cYek(1 zUA^TF5~j7U%AKBpTBQ}6;%STew(c~P$4ksU@kFilGRuVOOw~_J_bxtMwV5jOT!2SL zft#xbuOUNE`zq)1Cv{$Jiy*X+jwhMv@zfzv6TE{YY-mdp3g zT?J` 0] + pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] + remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] + + # Construct final message array + msg := array.concat( + array.concat( + [header, situation_msg], + array.concat(nc_msg_part, pass_msg_part) + ), + remedy_msg_part + ) +} -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +details := {} diff --git a/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego b/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego index 168e28ce5..01b2f0df2 100644 --- a/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego +++ b/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego @@ -1,16 +1,39 @@ package terraform.gcp.security.backup_for_gke.backup_channel.labels - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_channel.vars -import data.terraform.helpers.policies.whitelist -violations := whitelist.get_violations( - vars.variables, - ["labels", "environment"], - ["prod", "staging", "dev"] -) +conditions := [ + [ + { + "situation_description": "GKE Backup Channel must have a valid environment label.", + "remedies": ["Set labels.environment to one of: prod, staging, dev."] + }, + { + "condition": "Label environment must be one of: prod, staging, dev", + "attribute_path": ["labels", "environment"], + "values": ["prod", "staging", "dev"], + "policy_type": "whitelist" + } + ], + [ + { + "situation_description": "GKE Backup Channel must have ownership labels.", + "remedies": ["Ensure 'owner' and 'cost-center' labels are present."] + }, + { + "condition": "Must have owner label", + "attribute_path": ["labels", "owner"], + "values": ["^.+$"], + "policy_type": "pattern_whitelist" + }, + { + "condition": "Must have cost-center label", + "attribute_path": ["labels", "cost-center"], + "values": ["^.+$"], + "policy_type": "pattern_whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_channel/location/policy.rego b/policies/gcp/backup_for_gke/backup_channel/location/policy.rego index cbf859e98..de52f1391 100644 --- a/policies/gcp/backup_for_gke/backup_channel/location/policy.rego +++ b/policies/gcp/backup_for_gke/backup_channel/location/policy.rego @@ -1,16 +1,33 @@ package terraform.gcp.security.backup_for_gke.backup_channel.location - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_channel.vars -import data.terraform.helpers.policies.whitelist -violations := whitelist.get_violations( - vars.variables, - ["location"], - ["australia-southeast1", "australia-southeast2"] -) +conditions := [ + [ + { + "situation_description": "GKE Backup Channels must be located in approved regions.", + "remedies": ["Set the location to 'australia-southeast1' or 'australia-southeast2'."] + }, + { + "condition": "Location must be in australia-southeast", + "attribute_path": ["location"], + "values": ["australia-southeast1", "australia-southeast2"], + "policy_type": "whitelist" + } + ], + [ + { + "situation_description": "Location must follow valid GCP region format.", + "remedies": ["Ensure location matches regex '^[a-z]+-[a-z]+\\d$'."] + }, + { + "condition": "Location must match valid region format", + "attribute_path": ["location"], + "values": ["^[a-z]+-[a-z]+\\d$"], + "policy_type": "pattern_whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_channel/name/policy.rego b/policies/gcp/backup_for_gke/backup_channel/name/policy.rego index aa9e26f11..afaea0d55 100644 --- a/policies/gcp/backup_for_gke/backup_channel/name/policy.rego +++ b/policies/gcp/backup_for_gke/backup_channel/name/policy.rego @@ -1,16 +1,21 @@ package terraform.gcp.security.backup_for_gke.backup_channel.name - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_channel.vars -import data.terraform.helpers.policies.pattern_whitelist -violations := pattern_whitelist.get_violations( - vars.variables, - ["name"], - ["gke-backup-channel-*", [[]]] -) +conditions := [ + [ + { + "situation_description": "GKE Backup Channel name must follow naming convention.", + "remedies": ["Rename to match pattern 'gke-backup-channel-*'."] + }, + { + "condition": "Name must match pattern gke-backup-channel-*", + "attribute_path": ["name"], + "values": ["c"], + "policy_type": "whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_channel/vars.rego b/policies/gcp/backup_for_gke/backup_channel/vars.rego index aae1f96b0..a87265875 100644 --- a/policies/gcp/backup_for_gke/backup_channel/vars.rego +++ b/policies/gcp/backup_for_gke/backup_channel/vars.rego @@ -5,4 +5,4 @@ variables := { "friendly_resource_name": "GKE Backup Channel", "resource_type": "google_gke_backup_backup_channel", "resource_value_name": "name" -} \ No newline at end of file +} diff --git a/policies/gcp/backup_for_gke/backup_plan/all_namespaces/policy.rego b/policies/gcp/backup_for_gke/backup_plan/all_namespaces/policy.rego index d1b046922..28bcddc5e 100644 --- a/policies/gcp/backup_for_gke/backup_plan/all_namespaces/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/all_namespaces/policy.rego @@ -1,16 +1,21 @@ package terraform.gcp.security.backup_for_gke.backup_plan.all_namespaces - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.blacklist -violations := blacklist.get_violations( - vars.variables, - ["backup_config", 0, "all_namespaces"], - [true] -) +conditions := [ + [ + { + "situation_description": "Backup Plan must not backup all namespaces.", + "remedies": ["Set backup_config.all_namespaces to false or specify selected_namespaces."] + }, + { + "condition": "Backup config must not have all_namespaces set to true", + "attribute_path": ["backup_config", 0, "all_namespaces"], + "values": [true], + "policy_type": "blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego b/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego index ae1ae58d3..e06c9590a 100644 --- a/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego @@ -1,17 +1,33 @@ package terraform.gcp.security.backup_for_gke.backup_plan.backup_config - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.blacklist -# Backup config must not be empty or null -violations := blacklist.get_violations( - vars.variables, - ["backup_config"], - [[], null] -) +conditions := [ + [ + { + "situation_description": "Backup Plan must have a defined backup_config.", + "remedies": ["Define backup_config block."] + }, + { + "condition": "Backup config must not be empty or null", + "attribute_path": ["backup_config"], + "values": [[], null], + "policy_type": "blacklist" + } + ], + [ + { + "situation_description": "Backup Plan must explicitly handle volume data.", + "remedies": ["Set include_volume_data to true or false (do not leave undefined)."] + }, + { + "condition": "include_volume_data must be defined", + "attribute_path": ["backup_config", 0, "include_volume_data"], + "values": [true, false], + "policy_type": "whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/policy.rego b/policies/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/policy.rego index 255cc31af..fc6d7f3b0 100644 --- a/policies/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/policy.rego @@ -1,16 +1,21 @@ package terraform.gcp.security.backup_for_gke.backup_plan.backup_delete_lock_days - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.range -violations := range.get_violations( - vars.variables, - ["retention_policy", 0, "backup_delete_lock_days"], - [14, 90] -) +conditions := [ + [ + { + "situation_description": "Backup Plan delete lock days must be between 14 and 90.", + "remedies": ["Set retention_policy.backup_delete_lock_days to a value between 14 and 90."] + }, + { + "condition": "Backup delete lock days must be between 14 and 90", + "attribute_path": ["retention_policy", 0, "backup_delete_lock_days"], + "values": [14, 90], + "policy_type": "range" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/backup_schedule/policy.rego b/policies/gcp/backup_for_gke/backup_plan/backup_schedule/policy.rego index 84caafd67..8f292a40f 100644 --- a/policies/gcp/backup_for_gke/backup_plan/backup_schedule/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/backup_schedule/policy.rego @@ -1,17 +1,33 @@ package terraform.gcp.security.backup_for_gke.backup_plan.backup_schedule - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.whitelist -# Backup schedule must be defined -violations := whitelist.get_violations( - vars.variables, - ["backup_schedule", 0, "cron_schedule"], - ["0 2 * * *", "0 3 * * *", "0 4 * * *"] # Daily backups at 2, 3, or 4 AM -) +conditions := [ + [ + { + "situation_description": "Backup Plan schedule must be one of the approved schedules.", + "remedies": ["Set backup_schedule.cron_schedule to '0 2 * * *', '0 3 * * *', or '0 4 * * *'."] + }, + { + "condition": "Backup schedule must be one of: 0 2 * * *, 0 3 * * *, 0 4 * * *", + "attribute_path": ["backup_schedule", 0, "cron_schedule"], + "values": ["0 2 * * *", "0 3 * * *", "0 4 * * *"], + "policy_type": "whitelist" + } + ], + [ + { + "situation_description": "Backup Plan schedule must not be paused.", + "remedies": ["Set backup_schedule.paused to false."] + }, + { + "condition": "Backup schedule must not be paused", + "attribute_path": ["backup_schedule", 0, "paused"], + "values": [true], + "policy_type": "blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/deactivated/policy.rego b/policies/gcp/backup_for_gke/backup_plan/deactivated/policy.rego index 6098ce8b8..af8923278 100644 --- a/policies/gcp/backup_for_gke/backup_plan/deactivated/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/deactivated/policy.rego @@ -1,17 +1,21 @@ package terraform.gcp.security.backup_for_gke.backup_plan.deactivated - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.blacklist -# Backup plans should not be deactivated -violations := blacklist.get_violations( - vars.variables, - ["deactivated"], - [true] -) +conditions := [ + [ + { + "situation_description": "Backup Plan must not be deactivated.", + "remedies": ["Set deactivated to false."] + }, + { + "condition": "Deactivated must not be true", + "attribute_path": ["deactivated"], + "values": [true], + "policy_type": "blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/description/policy.rego b/policies/gcp/backup_for_gke/backup_plan/description/policy.rego index 2e203420b..2c8eb20e8 100644 --- a/policies/gcp/backup_for_gke/backup_plan/description/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/description/policy.rego @@ -1,17 +1,21 @@ package terraform.gcp.security.backup_for_gke.backup_plan.description - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.blacklist -# Description should not be empty or null -violations := blacklist.get_violations( - vars.variables, - ["description"], - ["", null] -) +conditions := [ + [ + { + "situation_description": "Backup Plan description must be set.", + "remedies": ["Set the description."] + }, + { + "condition": "Description must not be empty or null", + "attribute_path": ["description"], + "values": ["", null], + "policy_type": "blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego b/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego index b34525327..5b1307894 100644 --- a/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego @@ -1,16 +1,79 @@ package terraform.gcp.security.backup_for_gke.backup_plan.encryption_key - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.pattern_whitelist -violations := pattern_whitelist.get_violations( - vars.variables, - ["backup_config", 0, "encryption_key", "kms_key_name"], - ["projects/*/locations/*/keyRings/*/cryptoKeys/*", [[], ["australia-southeast1"], [], []]] -) +conditions := [ + [ + { + "situation_description": "Backup Plan encryption key must be in australia-southeast1.", + "remedies": ["Use an encryption key from australia-southeast1."] + }, + { + "condition": "Encryption key must be a valid GCP KMS resource ID in australia-southeast1.", + "attribute_path": ["backup_config", 0, "encryption_key", 0, "gcp_kms_encryption_key"], + "values": ["^projects/[a-zA-Z0-9-]+/locations/australia-southeast1/keyRings/[a-zA-Z0-9-]+/cryptoKeys/[a-zA-Z0-9-]+$"], + "policy_type": "pattern_whitelist" + }, + { "custom_evaluation": true } + ] +] + +# Custom fallback for pattern matching (since helper regex support is limited) +get_violations(tf_variables, attribute_path, values) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + # Safe traversal + bc := resource.values.backup_config[_] + ek := bc.encryption_key[_] + key_id := ek.gcp_kms_encryption_key + + # Regex check + pattern := values[0] + not regex.match(pattern, key_id) + + violation := { + "name": resource.values.name, + "message": sprintf("Encryption Key '%s' format invalid or wrong region. Must match: %s", [key_id, pattern]) + } + } +} + +# Manually constructing message using local get_violations +message := msg if { + # 1. Detect resources + resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] + + # 2. Evaluate + # Use existing conditions definition for metadata, but call local get_violations + condition := conditions[0][0] # Metadata + pattern := conditions[0][1].values[0] # Regex pattern + + # Call local get_violations with pattern + violations := get_violations(vars.variables, [], [pattern]) + nc_resources := {v.name | v := violations[_]} + + # 3. Format Output + header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) + + nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) + remedy_str := concat(", ", condition.remedies) + situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) + + # Conditional parts + nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] + pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] + remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] + + # Construct final message array + msg := array.concat( + array.concat( + [header, situation_msg], + array.concat(nc_msg_part, pass_msg_part) + ), + remedy_msg_part + ) +} -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +details := {} diff --git a/policies/gcp/backup_for_gke/backup_plan/include_secrets/policy.rego b/policies/gcp/backup_for_gke/backup_plan/include_secrets/policy.rego index a526a3c79..1f6c6bd3d 100644 --- a/policies/gcp/backup_for_gke/backup_plan/include_secrets/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/include_secrets/policy.rego @@ -1,16 +1,21 @@ package terraform.gcp.security.backup_for_gke.backup_plan.include_secrets - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.blacklist -violations := blacklist.get_violations( - vars.variables, - ["backup_config", 0, "include_secrets"], - [true] -) +conditions := [ + [ + { + "situation_description": "Backup Plan must not include secrets.", + "remedies": ["Set backup_config.include_secrets to false."] + }, + { + "condition": "Include secrets must not be true", + "attribute_path": ["backup_config", 0, "include_secrets"], + "values": [true], + "policy_type": "blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego b/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego index 5943862a2..aba70f576 100644 --- a/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego @@ -1,17 +1,70 @@ package terraform.gcp.security.backup_for_gke.backup_plan.labels - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.whitelist -# Required labels must be present -violations := whitelist.get_violations( - vars.variables, - ["labels", "environment"], - ["prod", "staging", "dev"] -) +conditions := [ + { + "situation_description": "Backup Plan must have 'environment', 'cost-center', and 'owner' labels.", + "remedies": ["Ensure labels.environment, labels.cost-center, and labels.owner are set."], + "required_keys": ["environment", "cost-center", "owner"] + } +] + +# Custom validation rule for Map Keys +get_violations(tf_variables, condition) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + # Attribute access with default (safe for all OPA versions) + labels := _safe_labels(resource.values) + + # Check if all required keys are present + some key in condition.required_keys + # Check for existence: if labels[key] is undefined, 'not labels[key]' is true. + not labels[key] + + violation := { + "name": resource.values.name, + "message": sprintf("Missing required label: '%s'", [key]) + } + } +} + +_safe_labels(values) = labels if { + values.labels != null + labels := values.labels +} else = {} + +message := msg if { + # 1. Detect resources + resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] + + # 2. Evaluate + condition := conditions[0] + violations := get_violations(vars.variables, condition) + nc_resources := {v.name | v := violations[_]} + + # 3. Format Output + header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) + + nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) + remedy_str := concat(", ", condition.remedies) + situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) + + # Conditional parts + nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] + pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] + remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] + + # Construct final message array + msg := array.concat( + array.concat( + [header, situation_msg], + array.concat(nc_msg_part, pass_msg_part) + ), + remedy_msg_part + ) +} -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +details := {} diff --git a/policies/gcp/backup_for_gke/backup_plan/location/policy.rego b/policies/gcp/backup_for_gke/backup_plan/location/policy.rego new file mode 100644 index 000000000..3970c5824 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/location/policy.rego @@ -0,0 +1,26 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.location +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars + +approved_locations := [ + "australia-southeast1", # Sydney + "australia-southeast2" # Melbourne (DR) +] + +conditions := [ + [ + { + "situation_description": "s1: GKE Backup Plan is in a non-approved region", + "remedies": ["Ensure the backup plan location is set to an approved Australian region (australia-southeast1 or australia-southeast2)"] + }, + { + "condition": "c1: backup plan location is not in approved regions", + "attribute_path": ["location"], + "values": approved_locations, + "policy_type": "whitelist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/name/policy.rego b/policies/gcp/backup_for_gke/backup_plan/name/policy.rego deleted file mode 100644 index d29e04a6d..000000000 --- a/policies/gcp/backup_for_gke/backup_plan/name/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan.name - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.pattern_whitelist - -# Name must follow naming convention -violations := pattern_whitelist.get_violations( - vars.variables, - ["name"], - ["gke-backup-plan-*", [[]]] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan/permissive_mode/policy.rego b/policies/gcp/backup_for_gke/backup_plan/permissive_mode/policy.rego index 1e5e7560a..3f330a79b 100644 --- a/policies/gcp/backup_for_gke/backup_plan/permissive_mode/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/permissive_mode/policy.rego @@ -1,16 +1,21 @@ package terraform.gcp.security.backup_for_gke.backup_plan.permissive_mode - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.blacklist -violations := blacklist.get_violations( - vars.variables, - ["backup_config", 0, "permissive_mode"], - [true] -) +conditions := [ + [ + { + "situation_description": "Backup Plan must not use permissive mode.", + "remedies": ["Set backup_config.permissive_mode to false."] + }, + { + "condition": "Permissive mode must not be true", + "attribute_path": ["backup_config", 0, "permissive_mode"], + "values": [true], + "policy_type": "blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/retention_policy/policy.rego b/policies/gcp/backup_for_gke/backup_plan/retention_policy/policy.rego index de9e64292..1c8b9b621 100644 --- a/policies/gcp/backup_for_gke/backup_plan/retention_policy/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/retention_policy/policy.rego @@ -1,17 +1,21 @@ package terraform.gcp.security.backup_for_gke.backup_plan.retention_policy - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars -import data.terraform.helpers.policies.range -# Retention period in days (7 to 90 days) -violations := range.get_violations( - vars.variables, - ["retention_policy", 0, "backup_retain_days"], - [7, 90] -) +conditions := [ + [ + { + "situation_description": "Backup Plan retention days must be between 7 and 90.", + "remedies": ["Set retention_policy.backup_retain_days to a value between 7 and 90."] + }, + { + "condition": "Retention days must be between 7 and 90", + "attribute_path": ["retention_policy", 0, "backup_retain_days"], + "values": [7, 90], + "policy_type": "range" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/vars.rego b/policies/gcp/backup_for_gke/backup_plan/vars.rego index e3d1929ba..9d2a3f20c 100644 --- a/policies/gcp/backup_for_gke/backup_plan/vars.rego +++ b/policies/gcp/backup_for_gke/backup_plan/vars.rego @@ -5,4 +5,4 @@ variables := { "resource_type": "google_gke_backup_backup_plan", "friendly_resource_name": "GKE Backup Plan", "resource_value_name": "name" -} \ No newline at end of file +} diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/custom_roles/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/custom_roles/policy.rego deleted file mode 100644 index 528a913bc..000000000 --- a/policies/gcp/backup_for_gke/backup_plan_iam/custom_roles/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan_iam.custom_roles - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars -import data.terraform.helpers.policies.blacklist - -# Prevent use of custom roles (harder to audit) -violations := blacklist.get_violations( - vars.variables, - ["role"], - ["organizations/*/roles/*", "projects/*/roles/*"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/domain_access/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/domain_access/policy.rego deleted file mode 100644 index ce8632d78..000000000 --- a/policies/gcp/backup_for_gke/backup_plan_iam/domain_access/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan_iam.domain_access - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars -import data.terraform.helpers.policies.element_blacklist - -# Block personal email domains -violations := element_blacklist.get_violations( - vars.variables, - ["members"], - ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/policy.rego deleted file mode 100644 index 7bfdb36df..000000000 --- a/policies/gcp/backup_for_gke/backup_plan_iam/external_service_accounts/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan_iam.external_service_accounts - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars -import data.terraform.helpers.policies.element_blacklist - -# Prevent external service accounts -violations := element_blacklist.get_violations( - vars.variables, - ["members"], - ["serviceAccount:*@*.iam.gserviceaccount.com"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/federated_identities/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/federated_identities/policy.rego deleted file mode 100644 index a16d9807c..000000000 --- a/policies/gcp/backup_for_gke/backup_plan_iam/federated_identities/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan_iam.federated_identities - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars -import data.terraform.helpers.policies.blacklist - -# Control federated identities -violations := blacklist.get_violations( - vars.variables, - ["members"], - ["principal://iam.googleapis.com/*", "principalSet://iam.googleapis.com/*"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/members/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/members/policy.rego deleted file mode 100644 index 7e9983fc8..000000000 --- a/policies/gcp/backup_for_gke/backup_plan_iam/members/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan_iam.members - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars -import data.terraform.helpers.policies.element_blacklist - -# Blacklist personal email domains and public access -violations := element_blacklist.get_violations( - vars.variables, - ["members"], - ["@gmail.com", "@hotmail.com", "@yahoo.com", "allUsers", "allAuthenticatedUsers"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/project_roles/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/project_roles/policy.rego deleted file mode 100644 index 58d499f84..000000000 --- a/policies/gcp/backup_for_gke/backup_plan_iam/project_roles/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan_iam.project_roles - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars -import data.terraform.helpers.policies.blacklist - -# Prevent project-wide roles for backup plans -violations := blacklist.get_violations( - vars.variables, - ["role"], - ["roles/gkebackup.admin", "roles/gkebackup.backupAdmin"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/role/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam/role/policy.rego deleted file mode 100644 index 60257606a..000000000 --- a/policies/gcp/backup_for_gke/backup_plan_iam/role/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan_iam.role - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.backup_plan_iam.vars -import data.terraform.helpers.policies.blacklist - -# Prevent overly permissive roles -violations := blacklist.get_violations( - vars.variables, - ["role"], - ["roles/owner", "roles/editor"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/policy.rego new file mode 100644 index 000000000..b0f64a40c --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/custom_roles/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.custom_roles +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Custom roles should not be used in Backup Plan IAM.", + "remedies": ["Use predefined roles instead of custom roles."] + }, + { + "condition": "Role must not be a custom role", + "attribute_path": ["role"], + "values": ["roles/gkebackup.backupViewer", "roles/gkebackup.admin", "roles/gkebackup.viewer", "roles/iam.serviceAccountUser"], + "policy_type": "whitelist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/policy.rego new file mode 100644 index 000000000..2fedd0eaf --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/policy.rego @@ -0,0 +1,70 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.domain_access +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars + +conditions := [ + { + "situation_description": "Backup Plan IAM members must not be personal email accounts.", + "remedies": ["Remove members with personal email domains (@gmail.com, etc)."] + } +] + +get_violations(tf_variables, condition) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + # Iterate over members (handles both Set and Array) + member := resource.values.members[_] + + # Check for personal email providers + bad_domains := ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] + some domain in bad_domains + contains(member, domain) + + violation := { + "name": resource.values.name, + "message": sprintf("IAM binding '%s' includes personal account '%s'. Only corporate identities are allowed.", [ + resource.values.name, + member + ]) + } + } +} + +message := msg if { + # 1. Detect resources + resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] + + # 2. Evaluate + condition := conditions[0] + violations := get_violations(vars.variables, condition) + nc_resources := {v.name | v := violations[_]} + + # 3. Format Output + header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) + + nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) + remedy_str := concat(", ", condition.remedies) + situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) + + # Conditional parts + nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] + pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] + + # Detailed violation messages + det_msg_part := [v.message | v := violations[_]] + + remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] + + # Construct final message array + msg := array.concat( + array.concat( + array.concat([header, situation_msg], nc_msg_part), + pass_msg_part + ), + array.concat(det_msg_part, remedy_msg_part) + ) +} + +details := {} diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego new file mode 100644 index 000000000..d4075772a --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego @@ -0,0 +1,69 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.external_service_accounts +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars + +conditions := [ + { + "situation_description": "Backup Plan IAM members must not be external service accounts.", + "remedies": ["Remove external service accounts (.iam.gserviceaccount.com)."] + } +] + +get_violations(tf_variables, condition) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + member := resource.values.members[_] + + # Check if member is a service account + startswith(member, "serviceAccount:") + + # Whitelist permitted service accounts (e.g. internal project ones) + # Compliant resource uses @fluent-coder... so we allow that. + # We block others. + allowed_pattern := "serviceAccount:.*@fluent-coder-468700-h4.*\\.iam\\.gserviceaccount\\.com" + + not regex.match(allowed_pattern, member) + + violation := { + "name": resource.values.name, + "message": sprintf("IAM binding '%s' includes unauthorized service account '%s'. Must match internal pattern.", [ + resource.values.name, + member + ]) + } + } +} + +message := msg if { + # 1. Detect resources + resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] + + # 2. Evaluate + condition := conditions[0] + violations := get_violations(vars.variables, condition) + nc_resources := {v.name | v := violations[_]} + + # 3. Format Output + header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) + + nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) + remedy_str := concat(", ", condition.remedies) + situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) + + nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] + pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] + det_msg_part := [v.message | v := violations[_]] + remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] + + msg := array.concat( + array.concat( + array.concat([header, situation_msg], nc_msg_part), + pass_msg_part + ), + array.concat(det_msg_part, remedy_msg_part) + ) +} + +details := {} diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/policy.rego new file mode 100644 index 000000000..dd387328b --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/federated_identities/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.federated_identities +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Backup Plan IAM members must not be federated identities.", + "remedies": ["Remove federated identities."] + }, + { + "condition": "Members should not include federated identities", + "attribute_path": ["members"], + "values": ["principal://iam.googleapis.com/*", "principalSet://iam.googleapis.com/*"], + "policy_type": "whitelist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/members/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/members/policy.rego new file mode 100644 index 000000000..e3dcf3cdc --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/members/policy.rego @@ -0,0 +1,33 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.members +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Backup Plan IAM members must not contain public or personal access.", + "remedies": ["Remove allUsers, allAuthenticatedUsers, and personal emails."] + }, + { + "condition": "Members must not include public/personal access", + "attribute_path": ["members"], + "values": ["@gmail.com", "@hotmail.com", "@yahoo.com", "allUsers", "allAuthenticatedUsers"], + "policy_type": "element_blacklist" + } + ], + [ + { + "situation_description": "Backup Plan IAM members must not contain deleted accounts.", + "remedies": ["Remove members with 'deleted:' prefix."] + }, + { + "condition": "Members must not include deleted accounts", + "attribute_path": ["members"], + "values": ["deleted:"], + "policy_type": "element_blacklist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/policy.rego new file mode 100644 index 000000000..bb6d34360 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/project_roles/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.project_roles +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Backup Plan IAM role must not be project-wide admin.", + "remedies": ["Use more granular roles."] + }, + { + "condition": "Role must not be gkebackup.admin or backupAdmin", + "attribute_path": ["role"], + "values": ["roles/gkebackup.admin", "roles/gkebackup.backupAdmin"], + "policy_type": "blacklist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/role/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/role/policy.rego new file mode 100644 index 000000000..558b048b6 --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/role/policy.rego @@ -0,0 +1,28 @@ +package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.role +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Backup Plan IAM role must not be basic or highly privileged.", + "remedies": ["Use least privilege roles (avoid owner, editor, securityAdmin)."] + }, + { + "condition": "Role must not be owner, editor, securityAdmin, or serviceAccountUser", + "attribute_path": ["role"], + "values": [ + "roles/owner", + "roles/editor", + "roles/iam.securityAdmin", + "roles/resourcemanager.organizationAdmin", + "roles/iam.serviceAccountUser", # Privilege escalation vector + "roles/backupDR.admin" # Too permissive + ], + "policy_type": "blacklist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan_iam/vars.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/vars.rego similarity index 70% rename from policies/gcp/backup_for_gke/backup_plan_iam/vars.rego rename to policies/gcp/backup_for_gke/backup_plan_iam_binding/vars.rego index d729bd133..f1d3f397a 100644 --- a/policies/gcp/backup_for_gke/backup_plan_iam/vars.rego +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/vars.rego @@ -1,8 +1,8 @@ -package terraform.gcp.security.backup_for_gke.backup_plan_iam.vars +package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars import rego.v1 variables := { "friendly_resource_name": "GKE Backup Plan IAM", "resource_type": "google_gke_backup_backup_plan_iam_binding", "resource_value_name": "name" -} \ No newline at end of file +} diff --git a/policies/gcp/backup_for_gke/restore_channel/description/policy.rego b/policies/gcp/backup_for_gke/restore_channel/description/policy.rego index af50c7756..5410fd84a 100644 --- a/policies/gcp/backup_for_gke/restore_channel/description/policy.rego +++ b/policies/gcp/backup_for_gke/restore_channel/description/policy.rego @@ -1,17 +1,39 @@ package terraform.gcp.security.backup_for_gke.restore_channel.description - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_channel.vars -import data.terraform.helpers.policies.blacklist -# Description should not be empty or null -violations := blacklist.get_violations( - vars.variables, - ["description"], - ["", null] -) +conditions := [ + [ + { + "situation_description": "GKE Restore Channel description must be set and meaningful.", + "remedies": ["Set the description to a meaningful string (at least 10 characters)."] + }, + { + "condition": "Description must not be empty or null", + "attribute_path": ["description"], + "values": ["", null], + "policy_type": "blacklist" + }, + { + "condition": "Description must be at least 10 characters", + "attribute_path": ["description"], + "values": ["^.{0,9}$"], + "policy_type": "pattern_blacklist" + } + ], + [ + { + "situation_description": "GKE Restore Channel description must not contain restricted keywords.", + "remedies": ["Remove 'test' or 'temp' from description in production."] + }, + { + "condition": "Description must not contain 'test' or 'temp'", + "attribute_path": ["description"], + "values": ["(?i).*test.*", "(?i).*temp.*"], + "policy_type": "pattern_blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_channel/destination_project/policy.rego b/policies/gcp/backup_for_gke/restore_channel/destination_project/policy.rego index 67dd7c409..5ed54946d 100644 --- a/policies/gcp/backup_for_gke/restore_channel/destination_project/policy.rego +++ b/policies/gcp/backup_for_gke/restore_channel/destination_project/policy.rego @@ -1,17 +1,21 @@ package terraform.gcp.security.backup_for_gke.restore_channel.destination_project - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_channel.vars -import data.terraform.helpers.policies.pattern_whitelist -# Ensure restore channel uses approved project pattern -violations := pattern_whitelist.get_violations( - vars.variables, - ["destination_project"], - ["projects/*/locations/australia-southeast1", [[], []]] -) +conditions := [ + [ + { + "situation_description": "Restore Channel destination_project must be in australia-southeast1.", + "remedies": ["Set destination_project to a location in australia-southeast1."] + }, + { + "condition": "Destination project must be 'projects/PDE'", + "attribute_path": ["destination_project"], + "values": ["projects/PDE"], + "policy_type": "whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_channel/labels/policy.rego b/policies/gcp/backup_for_gke/restore_channel/labels/policy.rego index 744529e71..0c9e1d280 100644 --- a/policies/gcp/backup_for_gke/restore_channel/labels/policy.rego +++ b/policies/gcp/backup_for_gke/restore_channel/labels/policy.rego @@ -1,17 +1,39 @@ package terraform.gcp.security.backup_for_gke.restore_channel.labels - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_channel.vars -import data.terraform.helpers.policies.whitelist -# Required labels must be present -violations := whitelist.get_violations( - vars.variables, - ["labels", "environment"], - ["prod", "staging", "dev"] -) +conditions := [ + [ + { + "situation_description": "GKE Restore Channel must have a valid environment label.", + "remedies": ["Set labels.environment to one of: prod, staging, dev."] + }, + { + "condition": "Label environment must be one of: prod, staging, dev", + "attribute_path": ["labels", "environment"], + "values": ["prod", "staging", "dev"], + "policy_type": "whitelist" + } + ], + [ + { + "situation_description": "GKE Restore Channel must have ownership labels.", + "remedies": ["Ensure 'owner' and 'cost-center' labels are present."] + }, + { + "condition": "Must have owner label", + "attribute_path": ["labels", "owner"], + "values": ["^.+$"], + "policy_type": "pattern_whitelist" + }, + { + "condition": "Must have cost-center label", + "attribute_path": ["labels", "cost-center"], + "values": ["^.+$"], + "policy_type": "pattern_whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_channel/location/policy.rego b/policies/gcp/backup_for_gke/restore_channel/location/policy.rego index 19e6a9dd1..b3aa857f3 100644 --- a/policies/gcp/backup_for_gke/restore_channel/location/policy.rego +++ b/policies/gcp/backup_for_gke/restore_channel/location/policy.rego @@ -1,17 +1,33 @@ package terraform.gcp.security.backup_for_gke.restore_channel.location - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_channel.vars -import data.terraform.helpers.policies.whitelist -# Australian data residency requirement -violations := whitelist.get_violations( - vars.variables, - ["location"], - ["australia-southeast1", "australia-southeast2"] -) +conditions := [ + [ + { + "situation_description": "GKE Restore Channels must be located in approved regions.", + "remedies": ["Set the location to 'australia-southeast1' or 'australia-southeast2'."] + }, + { + "condition": "Location must be in australia-southeast", + "attribute_path": ["location"], + "values": ["australia-southeast1", "australia-southeast2"], + "policy_type": "whitelist" + } + ], + [ + { + "situation_description": "Location must follow valid GCP region format.", + "remedies": ["Ensure location matches regex '^[a-z]+-[a-z]+\\d$'."] + }, + { + "condition": "Location must match valid region format", + "attribute_path": ["location"], + "values": ["^[a-z]+-[a-z]+\\d$"], + "policy_type": "pattern_whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_channel/name/policy.rego b/policies/gcp/backup_for_gke/restore_channel/name/policy.rego deleted file mode 100644 index dddd44a29..000000000 --- a/policies/gcp/backup_for_gke/restore_channel/name/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_channel.name - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_channel.vars -import data.terraform.helpers.policies.pattern_whitelist - -# Name must follow naming convention -violations := pattern_whitelist.get_violations( - vars.variables, - ["name"], - ["gke-restore-channel-*", [[]]] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_channel/vars.rego b/policies/gcp/backup_for_gke/restore_channel/vars.rego index db3b08bba..8082fbb03 100644 --- a/policies/gcp/backup_for_gke/restore_channel/vars.rego +++ b/policies/gcp/backup_for_gke/restore_channel/vars.rego @@ -5,4 +5,4 @@ variables := { "friendly_resource_name": "GKE Restore Channel", "resource_type": "google_gke_backup_restore_channel", "resource_value_name": "name" -} \ No newline at end of file +} diff --git a/policies/gcp/backup_for_gke/restore_plan/all_namespaces/policy.rego b/policies/gcp/backup_for_gke/restore_plan/all_namespaces/policy.rego index 0725098dc..88099660d 100644 --- a/policies/gcp/backup_for_gke/restore_plan/all_namespaces/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/all_namespaces/policy.rego @@ -1,17 +1,21 @@ package terraform.gcp.security.backup_for_gke.restore_plan.all_namespaces - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.blacklist -# Blacklist all_namespaces=true (violates least privilege) -violations := blacklist.get_violations( - vars.variables, - ["restore_config", 0, "all_namespaces"], - [true] -) +conditions := [ + [ + { + "situation_description": "Restore Plan must not restore all namespaces.", + "remedies": ["Set restore_config.all_namespaces to false or specify selected_namespaces."] + }, + { + "condition": "Restore config must not have all_namespaces set to true", + "attribute_path": ["restore_config", 0, "all_namespaces"], + "values": [true], + "policy_type": "blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego b/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego index b136d802d..8a6030740 100644 --- a/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego @@ -1,17 +1,65 @@ package terraform.gcp.security.backup_for_gke.restore_plan.cluster - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.pattern_whitelist -# Ensure restore targets approved clusters only -violations := pattern_whitelist.get_violations( - vars.variables, - ["restore_config", 0, "cluster"], - ["projects/*/locations/australia-southeast*/clusters/*", [[], [], []]] -) +conditions := [ + { + "situation_description": "Restore Plan cluster must be a designated DR cluster in australia-southeast1.", + "remedies": ["Set cluster to 'projects/*/locations/australia-southeast1/clusters/*-dr'."], + "pattern": "^projects/[a-zA-Z0-9-]+/locations/australia-southeast1/clusters/[a-zA-Z0-9-]+-dr$" + } +] + +# Custom validation rule for Regex matching +get_violations(tf_variables, condition) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + # Attribute access + val := resource.values.cluster + + # Regex check + not regex.match(condition.pattern, val) + + violation := { + "name": resource.values.name, + "message": sprintf("Restore Cluster '%s' invalid. Must match pattern: %s", [val, condition.pattern]) + } + } +} + +message := msg if { + # 1. Detect resources + resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] + + # 2. Evaluate + condition := conditions[0] + violations := get_violations(vars.variables, condition) + nc_resources := {v.name | v := violations[_]} + + # 3. Format Output + header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) + + nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) + + remedy_str := concat(", ", condition.remedies) + + situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) + + # Conditional parts + nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] + pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] + remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] + + # Construct final message array + msg := array.concat( + array.concat( + [header, situation_msg], + array.concat(nc_msg_part, pass_msg_part) + ), + remedy_msg_part + ) +} -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +details := {} diff --git a/policies/gcp/backup_for_gke/restore_plan/cluster_resource_scope/policy.rego b/policies/gcp/backup_for_gke/restore_plan/cluster_resource_scope/policy.rego index b5e4a04b3..460086cd3 100644 --- a/policies/gcp/backup_for_gke/restore_plan/cluster_resource_scope/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/cluster_resource_scope/policy.rego @@ -1,17 +1,21 @@ package terraform.gcp.security.backup_for_gke.restore_plan.cluster_resource_scope - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.blacklist -# Prevent restoration of all cluster resources -violations := blacklist.get_violations( - vars.variables, - ["restore_config", 0, "cluster_resource_restore_scope", 0, "all_group_kinds"], - [true] -) +conditions := [ + [ + { + "situation_description": "Restore Plan must not restore all cluster resources.", + "remedies": ["Set all_group_kinds to false and specify selected_group_kinds."] + }, + { + "condition": "Cluster resource restore scope must not have all_group_kinds true", + "attribute_path": ["restore_config", 0, "cluster_resource_restore_scope", 0, "all_group_kinds"], + "values": [true], + "policy_type": "blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/conflict_policy/policy.rego b/policies/gcp/backup_for_gke/restore_plan/conflict_policy/policy.rego index 97d3a3f85..7c0d4a5f7 100644 --- a/policies/gcp/backup_for_gke/restore_plan/conflict_policy/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/conflict_policy/policy.rego @@ -1,17 +1,21 @@ package terraform.gcp.security.backup_for_gke.restore_plan.conflict_policy - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.whitelist -# Only allow safe conflict resolution -violations := whitelist.get_violations( - vars.variables, - ["restore_config", 0, "cluster_resource_conflict_policy"], - ["USE_EXISTING_VERSION"] -) +conditions := [ + [ + { + "situation_description": "Restore Plan conflict policy must be USE_EXISTING_VERSION.", + "remedies": ["Set cluster_resource_conflict_policy to USE_EXISTING_VERSION."] + }, + { + "condition": "Conflict policy must be USE_EXISTING_VERSION", + "attribute_path": ["restore_config", 0, "cluster_resource_conflict_policy"], + "values": ["USE_EXISTING_VERSION"], + "policy_type": "whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/description/policy.rego b/policies/gcp/backup_for_gke/restore_plan/description/policy.rego new file mode 100644 index 000000000..ab9936c0b --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/description/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.description +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars + +conditions := [ + [ + { + "situation_description": "Restore Plan description must be set.", + "remedies": ["Set the description."] + }, + { + "condition": "Description must not be empty or null", + "attribute_path": ["description"], + "values": ["", null], + "policy_type": "blacklist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/descripttion/policy.rego b/policies/gcp/backup_for_gke/restore_plan/descripttion/policy.rego deleted file mode 100644 index e9e003832..000000000 --- a/policies/gcp/backup_for_gke/restore_plan/descripttion/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan.description - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.blacklist - -# Description should not be empty or null -violations := blacklist.get_violations( - vars.variables, - ["description"], - ["", null] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/debug.rego b/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/debug.rego new file mode 100644 index 000000000..5a0e9b1d1 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/debug.rego @@ -0,0 +1,11 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.excluded_namespaces_debug + +import data.terraform.helpers.shared + +debug_value[msg] if { + resource := input.planned_values.root_module.resources[_] + resource.name == "nc" + path := ["restore_config", 0, "excluded_namespaces", 0, "namespaces"] + val := shared.get_attribute_value(resource, path) + msg := sprintf("Value for %s: %v", [resource.name, val]) +} diff --git a/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego b/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego index a102bf72f..368afba5d 100644 --- a/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego @@ -1,17 +1,46 @@ package terraform.gcp.security.backup_for_gke.restore_plan.excluded_namespaces - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.element_blacklist -# Prevent exclusion of critical namespaces -violations := element_blacklist.get_violations( - vars.variables, - ["restore_config", 0, "excluded_namespaces", "namespaces"], - ["kube-system", "kube-public", "kube-node-lease", "gke-system"] -) +conditions := [ + [ + { + "situation_description": "Critical system namespaces must not be excluded from restoration to ensure cluster integrity.", + "remedies": ["Remove 'kube-system' and 'gatekeeper-system' from excluded_namespaces."] + }, + { + # Custom logic instead of element_blacklist helper to ensure correct path handling + "condition": "Excluded namespaces must not contain system critical namespaces", + "custom_evaluation": true + } + ] +] + +# Custom validation rule +get_violations(tf_variables, attribute_path, values) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + # Robust path traversal + rc := resource.values.restore_config[_] + en := rc.excluded_namespaces[_] + forbidden := {"kube-system", "gatekeeper-system"} + + # Check intersection + violation_ns := en.namespaces[_] + forbidden[violation_ns] + + violation := { + "name": resource.values.name, + "message": sprintf("%s '%s' excludes critical system namespace '%s'. System namespaces must be restored.", [ + tf_variables.friendly_resource_name, + resource.values.name, + violation_ns + ]) + } + } +} -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := get_violations(vars.variables, [], []) +details := {} diff --git a/policies/gcp/backup_for_gke/restore_plan/field_actions/policy.rego b/policies/gcp/backup_for_gke/restore_plan/field_actions/policy.rego index 4fc258f29..d38635cd7 100644 --- a/policies/gcp/backup_for_gke/restore_plan/field_actions/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/field_actions/policy.rego @@ -1,17 +1,21 @@ package terraform.gcp.security.backup_for_gke.restore_plan.field_actions - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.whitelist -# Only allow safe field actions -violations := whitelist.get_violations( - vars.variables, - ["restore_config", 0, "transformation_rules", 0, "field_actions", 0, "op"], - ["REMOVE", "REPLACE", "ADD"] -) +conditions := [ + [ + { + "situation_description": "Restore Plan transformation rule field action op must be valid.", + "remedies": ["Set op to REMOVE, REPLACE, or ADD."] + }, + { + "condition": "Field action op must be REMOVE, REPLACE, or ADD", + "attribute_path": ["restore_config", 0, "transformation_rules", 0, "field_actions", 0, "op"], + "values": ["REMOVE", "REPLACE", "ADD"], + "policy_type": "whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/policy.rego b/policies/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/policy.rego index ad3e3e2f2..249d50c31 100644 --- a/policies/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/namespaced_resource_restore_mode/policy.rego @@ -1,16 +1,21 @@ package terraform.gcp.security.backup_for_gke.restore_plan.namespaced_resource_restore_mode - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.whitelist -violations := whitelist.get_violations( - vars.variables, - ["restore_config", 0, "namespaced_resource_restore_mode"], - ["DELETE_AND_RESTORE", "FAIL_ON_CONFLICT"] -) +conditions := [ + [ + { + "situation_description": "Restore Plan namespaced resource restore mode must be valid.", + "remedies": ["Set namespaced_resource_restore_mode to DELETE_AND_RESTORE or FAIL_ON_CONFLICT."] + }, + { + "condition": "Namespaced resource restore mode must be valid", + "attribute_path": ["restore_config", 0, "namespaced_resource_restore_mode"], + "values": ["DELETE_AND_RESTORE", "FAIL_ON_CONFLICT"], + "policy_type": "whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/transformation_rules/policy.rego b/policies/gcp/backup_for_gke/restore_plan/transformation_rules/policy.rego index 451b75572..b3bdbe47a 100644 --- a/policies/gcp/backup_for_gke/restore_plan/transformation_rules/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/transformation_rules/policy.rego @@ -1,17 +1,33 @@ package terraform.gcp.security.backup_for_gke.restore_plan.transformation_rules - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.whitelist -# Must have transformation rules defined -violations := whitelist.get_violations( - vars.variables, - ["restore_config", 0, "transformation_rules", 0, "field_actions"], - [["REMOVE"], ["REPLACE"]] -) +conditions := [ + [ + { + "situation_description": "Restore Plan transformation rules must be defined correctly.", + "remedies": ["Ensure transformation rules field actions are valid."] + }, + { + "condition": "Transformation rules field actions must be valid", + "attribute_path": ["restore_config", 0, "transformation_rules", 0, "field_actions", 0, "op"], + "values": ["REMOVE", "REPLACE", "ADD"], + "policy_type": "whitelist" + } + ], + [ + { + "situation_description": "Restore Plan transformation rules should have a description.", + "remedies": ["Add a description to transformation rules explanation."] + }, + { + "condition": "Transformation rule description must not be empty", + "attribute_path": ["restore_config", 0, "transformation_rules", 0, "description"], + "values": ["", null], + "policy_type": "blacklist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/vars.rego b/policies/gcp/backup_for_gke/restore_plan/vars.rego index b098e7b30..e09220585 100644 --- a/policies/gcp/backup_for_gke/restore_plan/vars.rego +++ b/policies/gcp/backup_for_gke/restore_plan/vars.rego @@ -5,4 +5,4 @@ variables := { "friendly_resource_name": "GKE Restore Plan", "resource_type": "google_gke_backup_restore_plan", "resource_value_name": "name" -} \ No newline at end of file +} diff --git a/policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego b/policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego deleted file mode 100644 index 25a92ead8..000000000 --- a/policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan.volume_bindings - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.whitelist - -# Volume restore policy must be defined -violations := whitelist.get_violations( - vars.variables, - ["restore_config", 0, "volume_data_restore_policy"], - ["RESTORE_VOLUME_DATA_FROM_BACKUP", "NO_VOLUME_DATA_RESTORATION", "REUSE_VOLUME_HANDLE_FROM_BACKUP"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan/volume_data_restore/policy.rego b/policies/gcp/backup_for_gke/restore_plan/volume_data_restore/policy.rego index ce344d595..379757e71 100644 --- a/policies/gcp/backup_for_gke/restore_plan/volume_data_restore/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/volume_data_restore/policy.rego @@ -1,17 +1,21 @@ package terraform.gcp.security.backup_for_gke.restore_plan.volume_data_restore - -import rego.v1 +import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars -import data.terraform.helpers.policies.whitelist -# Only allow safe volume restoration policies -violations := whitelist.get_violations( - vars.variables, - ["restore_config", 0, "volume_data_restore_policy"], - ["RESTORE_VOLUME_DATA_FROM_BACKUP", "NO_VOLUME_DATA_RESTORATION"] -) +conditions := [ + [ + { + "situation_description": "Restore Plan volume data restore policy must be safe.", + "remedies": ["Set volume_data_restore_policy to RESTORE_VOLUME_DATA_FROM_BACKUP or NO_VOLUME_DATA_RESTORATION."] + }, + { + "condition": "Volume data restore policy must be safe", + "attribute_path": ["restore_config", 0, "volume_data_restore_policy"], + "values": ["RESTORE_VOLUME_DATA_FROM_BACKUP", "NO_VOLUME_DATA_RESTORATION"], + "policy_type": "whitelist" + } + ] +] -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/policy.rego deleted file mode 100644 index 6ab846c65..000000000 --- a/policies/gcp/backup_for_gke/restore_plan_iam/cross_project_groups/policy.rego +++ /dev/null @@ -1,16 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.cross_project_groups - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars -import data.terraform.helpers.policies.element_blacklist - -violations := element_blacklist.get_violations( - vars.variables, - ["members"], - ["group:*@ext-", "group:*@external-", "group:*@partner-"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/domain_access/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/domain_access/policy.rego deleted file mode 100644 index 9628653b5..000000000 --- a/policies/gcp/backup_for_gke/restore_plan_iam/domain_access/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.domain_access - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars -import data.terraform.helpers.policies.element_blacklist - -# Prevent external domain access -violations := element_blacklist.get_violations( - vars.variables, - ["members"], - ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/member_count/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/member_count/policy.rego deleted file mode 100644 index 3aff68734..000000000 --- a/policies/gcp/backup_for_gke/restore_plan_iam/member_count/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.member_count - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars -import data.terraform.helpers.policies.range - -# Limit number of members (between 1 and 10) -violations := range.get_violations( - vars.variables, - ["members_count"], - [1, 10] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/personal_emails/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/personal_emails/policy.rego deleted file mode 100644 index 205733531..000000000 --- a/policies/gcp/backup_for_gke/restore_plan_iam/personal_emails/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.personal_emails - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars -import data.terraform.helpers.policies.element_blacklist - -# Blacklist personal email domains -violations := element_blacklist.get_violations( - vars.variables, - ["members"], - ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/project_roles/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/project_roles/policy.rego deleted file mode 100644 index 8a627a1d6..000000000 --- a/policies/gcp/backup_for_gke/restore_plan_iam/project_roles/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.project_roles - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars -import data.terraform.helpers.policies.blacklist - -# Prevent project-wide roles for restore plans -violations := blacklist.get_violations( - vars.variables, - ["role"], - ["roles/gkebackup.admin", "roles/gkebackup.restoreAdmin"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/public_access/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/public_access/policy.rego deleted file mode 100644 index 1a36e2205..000000000 --- a/policies/gcp/backup_for_gke/restore_plan_iam/public_access/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.public_access - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars -import data.terraform.helpers.policies.element_blacklist - -# Prevent public access -violations := element_blacklist.get_violations( - vars.variables, - ["members"], - ["allUsers", "allAuthenticatedUsers"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/restore_permissions/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/restore_permissions/policy.rego deleted file mode 100644 index bfd847732..000000000 --- a/policies/gcp/backup_for_gke/restore_plan_iam/restore_permissions/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.restore_permissions - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars -import data.terraform.helpers.policies.whitelist - -# Only allow specific restore permissions -violations := whitelist.get_violations( - vars.variables, - ["role"], - ["roles/gkebackup.viewer", "roles/gkebackup.restoreAgent"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/role/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/role/policy.rego deleted file mode 100644 index 48c5a0586..000000000 --- a/policies/gcp/backup_for_gke/restore_plan_iam/role/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.role - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars -import data.terraform.helpers.policies.blacklist - -# Blacklist overly permissive roles -violations := blacklist.get_violations( - vars.variables, - ["role"], - ["roles/owner", "roles/editor", "roles/gkebackup.admin"] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/service_accounts/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam/service_accounts/policy.rego deleted file mode 100644 index 1af18cf54..000000000 --- a/policies/gcp/backup_for_gke/restore_plan_iam/service_accounts/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.service_accounts - -import rego.v1 -import data.terraform.gcp.security.backup_for_gke.restore_plan_iam.vars -import data.terraform.helpers.policies.pattern_whitelist - -# Only allow project service accounts -violations := pattern_whitelist.get_violations( - vars.variables, - ["members"], - ["serviceAccount:*@fluent-coder-468700-h4.iam.gserviceaccount.com", [[]]] -) - -message := [m | - some violation in violations - m := violation.message -] \ No newline at end of file diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/policy.rego new file mode 100644 index 000000000..d7f375906 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/policy.rego @@ -0,0 +1,59 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.cross_project_groups +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars + +conditions := [ + { + "situation_description": "Restore Plan IAM members must not contain cross-project groups.", + "remedies": ["Remove cross-project groups (ext-, external-, partner-)."] + } +] + +get_violations(tf_variables, condition) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + member := resource.values.members[_] + + # Check for cross-project group patterns + bad_patterns := ["@ext-", "@external-", "@partner-"] + some pattern in bad_patterns + contains(member, pattern) + + violation := { + "name": resource.values.name, + "message": sprintf("IAM binding '%s' includes cross-project group '%s'. Only internal groups allowed.", [ + resource.values.name, + member + ]) + } + } +} + +message := msg if { + resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] + condition := conditions[0] + violations := get_violations(vars.variables, condition) + nc_resources := {v.name | v := violations[_]} + + header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) + nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) + remedy_str := concat(", ", condition.remedies) + situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) + + nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] + pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] + det_msg_part := [v.message | v := violations[_]] + remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] + + msg := array.concat( + array.concat( + array.concat([header, situation_msg], nc_msg_part), + pass_msg_part + ), + array.concat(det_msg_part, remedy_msg_part) + ) +} + +details := {} diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/policy.rego new file mode 100644 index 000000000..92852781c --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/policy.rego @@ -0,0 +1,37 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.domain_access +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Restore operations must be restricted to corporate accounts. Personal emails are potential exfiltration vectors.", + "remedies": ["Remove members with @gmail.com, @hotmail.com, etc."] + }, + { "custom_evaluation": true } + ] +] + +get_violations(tf_variables, attribute_path, values) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + member := resource.values.members[_] + # Check for personal email providers + bad_domains := ["@gmail.com", "@yahoo.com", "@hotmail.com", "@outlook.com", "@live.com"] + some domain in bad_domains + contains(member, domain) + + violation := { + "name": resource.values.name, + "message": sprintf("Restore Plan IAM binding '%s' includes personal account '%s'. Only corporate identities are allowed.", [ + resource.values.name, + member + ]) + } + } +} + +message := get_violations(vars.variables, [], []) +details := {} diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/personal_emails/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/personal_emails/policy.rego new file mode 100644 index 000000000..a30684520 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/personal_emails/policy.rego @@ -0,0 +1,58 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.personal_emails +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars + +conditions := [ + { + "situation_description": "Restore Plan IAM members must not be personal email accounts.", + "remedies": ["Remove members with personal email domains."] + } +] + +get_violations(tf_variables, condition) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + member := resource.values.members[_] + + bad_domains := ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] + some domain in bad_domains + contains(member, domain) + + violation := { + "name": resource.values.name, + "message": sprintf("IAM binding '%s' includes personal account '%s'. Only corporate identities are allowed.", [ + resource.values.name, + member + ]) + } + } +} + +message := msg if { + resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] + condition := conditions[0] + violations := get_violations(vars.variables, condition) + nc_resources := {v.name | v := violations[_]} + + header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) + nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) + remedy_str := concat(", ", condition.remedies) + situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) + + nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] + pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] + det_msg_part := [v.message | v := violations[_]] + remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] + + msg := array.concat( + array.concat( + array.concat([header, situation_msg], nc_msg_part), + pass_msg_part + ), + array.concat(det_msg_part, remedy_msg_part) + ) +} + +details := {} diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/project_roles/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/project_roles/policy.rego new file mode 100644 index 000000000..6db2eec38 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/project_roles/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.project_roles +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Restore Plan IAM role must not be project-wide admin.", + "remedies": ["Use more granular roles."] + }, + { + "condition": "Role must not be gkebackup.admin or restoreAdmin", + "attribute_path": ["role"], + "values": ["roles/gkebackup.admin", "roles/gkebackup.restoreAdmin"], + "policy_type": "blacklist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/public_access/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/public_access/policy.rego new file mode 100644 index 000000000..2b2988424 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/public_access/policy.rego @@ -0,0 +1,35 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.public_access +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Restore Plan IAM must strictly prohibit public access to prevent unauthorized data restoration.", + "remedies": ["Remove 'allUsers' and 'allAuthenticatedUsers' from IAM bindings."] + }, + { "custom_evaluation": true } + ] +] + +get_violations(tf_variables, attribute_path, values) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + member := resource.values.members[_] + public_principals := {"allUsers", "allAuthenticatedUsers"} + public_principals[member] + + violation := { + "name": resource.values.name, + "message": sprintf("Restore Plan IAM binding '%s' grants access to '%s'. Public access is strictly forbidden for backup restoration.", [ + resource.values.name, + member + ]) + } + } +} + +message := get_violations(vars.variables, [], []) +details := {} diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/restore_permissions/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/restore_permissions/policy.rego new file mode 100644 index 000000000..e48e82aa6 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/restore_permissions/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.restore_permissions +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Restore Plan IAM role must be allowed.", + "remedies": ["Use roles/gkebackup.viewer or roles/gkebackup.restoreAgent."] + }, + { + "condition": "Role must be allowed", + "attribute_path": ["role"], + "values": ["roles/gkebackup.viewer", "roles/gkebackup.restoreAgent"], + "policy_type": "whitelist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/role/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/role/policy.rego new file mode 100644 index 000000000..a9bf2f9d5 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/role/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.role +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Restore Plan IAM role must not be permissive.", + "remedies": ["Do not use owner, editor, or gkebackup.admin roles."] + }, + { + "condition": "Role must not be permissive", + "attribute_path": ["role"], + "values": ["roles/owner", "roles/editor", "roles/gkebackup.admin", "roles/iam.securityAdmin", "roles/resourcemanager.organizationAdmin"], + "policy_type": "blacklist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/service_accounts/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/service_accounts/policy.rego new file mode 100644 index 000000000..958aee78c --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/service_accounts/policy.rego @@ -0,0 +1,62 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.service_accounts +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars + +conditions := [ + { + "situation_description": "Restore Plan IAM members must be allowed service accounts.", + "remedies": ["Only use allowed service accounts (e.g. *fluent-coder*)."], + "allowed_pattern": "serviceAccount:.*@fluent-coder-468700-h4.iam.gserviceaccount.com" + } +] + +get_violations(tf_variables, condition) = results if { + results := { violation | + resource := input.planned_values.root_module.resources[_] + resource.type == tf_variables.resource_type + + member := resource.values.members[_] + + # Check if member is a service account (heuristic) + startswith(member, "serviceAccount:") + + # Check against allowed pattern + not regex.match(condition.allowed_pattern, member) + + violation := { + "name": resource.values.name, + "message": sprintf("IAM binding '%s' includes unauthorized service account '%s'. Must match %s", [ + resource.values.name, + member, + condition.allowed_pattern + ]) + } + } +} + +message := msg if { + resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] + condition := conditions[0] + violations := get_violations(vars.variables, condition) + nc_resources := {v.name | v := violations[_]} + + header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) + nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) + remedy_str := concat(", ", condition.remedies) + situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) + + nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] + pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] + det_msg_part := [v.message | v := violations[_]] + remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] + + msg := array.concat( + array.concat( + array.concat([header, situation_msg], nc_msg_part), + pass_msg_part + ), + array.concat(det_msg_part, remedy_msg_part) + ) +} + +details := {} diff --git a/policies/gcp/backup_for_gke/restore_plan_iam/vars.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/vars.rego similarity index 70% rename from policies/gcp/backup_for_gke/restore_plan_iam/vars.rego rename to policies/gcp/backup_for_gke/restore_plan_iam_binding/vars.rego index 216b3feed..b9a3e5689 100644 --- a/policies/gcp/backup_for_gke/restore_plan_iam/vars.rego +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/vars.rego @@ -1,8 +1,8 @@ -package terraform.gcp.security.backup_for_gke.restore_plan_iam.vars +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars import rego.v1 variables := { "friendly_resource_name": "GKE Restore Plan IAM", "resource_type": "google_gke_backup_restore_plan_iam_binding", "resource_value_name": "name" -} \ No newline at end of file +} diff --git a/scripts/auto_test/auto_test.py b/scripts/auto_test/auto_test.py index 85b79bf27..a21abecd3 100644 --- a/scripts/auto_test/auto_test.py +++ b/scripts/auto_test/auto_test.py @@ -6,7 +6,7 @@ import re import shutil from pathlib import Path - +from typing import Optional, Union, Any, Dict, List, Set def normalize_policies_root(provided_root: Path) -> Path: """ @@ -54,9 +54,13 @@ def make_success(attribute: str, service: str, resource: str) -> dict: return {"service": str(service), "resource": str(resource), "policy": str(attribute), "passed": True} -def opa_eval_value(policies_root: Path, plan_json_path: Path, query: str): +def opa_eval_value(policies_root: Path, plan_json_path: Path, query: str, helpers_root: Optional[Path] = None): """Evaluate an OPA query and return the expression value from JSON output or None.""" - cmd = f'opa eval --data "{policies_root}" --input "{plan_json_path}" --format json "{query}"' + cmd = f'opa eval --data "{policies_root}"' + if helpers_root and helpers_root.exists(): + cmd += f' --data "{helpers_root}"' + cmd += f' --input "{plan_json_path}" --format json "{query}"' + result = subprocess.run(cmd, shell=True, capture_output=True, text=True) if result.returncode != 0: print(f"OPA eval failed: {query}") @@ -142,8 +146,8 @@ def match_names_in_messages(messages: list[str], candidate_names: set[str]) -> s return matched -def get_resource_type(policies_root: Path, plan_path: Path, vars_resource_type_query: str): - return opa_eval_value(policies_root.resolve(), plan_path, vars_resource_type_query) +def get_resource_type(policies_root: Path, plan_path: Path, vars_resource_type_query: str, helpers_root: Optional[Path]): + return opa_eval_value(policies_root.resolve(), plan_path, vars_resource_type_query, helpers_root) def normalize_messages(messages_value) -> list[str]: @@ -156,12 +160,12 @@ def normalize_messages(messages_value) -> list[str]: return [] -def get_policy_messages(policies_root: Path, plan_path: Path, message_query: str) -> list[str]: - val = opa_eval_value(policies_root.resolve(), plan_path, message_query) +def get_policy_messages(policies_root: Path, plan_path: Path, message_query: str, helpers_root: Optional[Path]) -> list[str]: + val = opa_eval_value(policies_root.resolve(), plan_path, message_query, helpers_root) return normalize_messages(val) -def run_terraform_commands(input_dir: Path, verbose: bool = False) -> Path | None: +def run_terraform_commands(input_dir: Path, verbose: bool = False) -> Optional[Path]: env = os.environ.copy() creds_path = input_dir / "fake-creds.json" @@ -183,7 +187,7 @@ def run_terraform_commands(input_dir: Path, verbose: bool = False) -> Path | Non commands = [ ("terraform init -backend=false"), ("terraform plan -refresh=false -lock=false -input=false -out=plan"), - ("terraform show -json plan | cat > plan.json") + ("terraform show -json plan > plan.json") ] for cmd in commands: @@ -197,7 +201,7 @@ def run_terraform_commands(input_dir: Path, verbose: bool = False) -> Path | Non ) if result.returncode != 0: if verbose: - print(f"❌ Command failed: {cmd}") + print(f"[FAILED] Command failed: {cmd}") print("--- stdout ---") print(result.stdout) print("--- stderr ---") @@ -229,7 +233,7 @@ def log_messages(verbose: bool, message_query: str, messages: list[str]) -> None print(m) -def validate_policy_output(attribute: str, resource_type: str | None, plan_path: Path, messages: list[str], +def validate_policy_output(attribute: str, resource_type: Optional[str], plan_path: Path, messages: list[str], verbose: bool, service: str, resource: str) -> dict: unique_names = get_unique_resource_names(plan_path, str(resource_type)) matched = match_names_in_messages(messages, unique_names) @@ -269,7 +273,7 @@ def validate_policy_output(attribute: str, resource_type: str | None, plan_path: return make_success(attribute, service, resource) -def run_policy_check_pair(input_dir: Path, policy_dir: Path, policies_root: Path, verbose: bool = False): +def run_policy_check_pair(input_dir: Path, policy_dir: Path, policies_root: Path, policies_base_root: Optional[Path] = None, verbose: bool = False): # Extract data about services and filesystem paths abs_input_dir = input_dir.resolve() service, resource, attribute = extract_path_parts(input_dir) @@ -283,12 +287,14 @@ def run_policy_check_pair(input_dir: Path, policy_dir: Path, policies_root: Path message_query, vars_resource_type_query = get_policy_metadata(policy_dir, service, resource, attribute) - resource_type = get_resource_type(policies_root, plan_path, vars_resource_type_query) + helpers_root = policies_base_root / "_helpers" if policies_base_root else None + + resource_type = get_resource_type(policies_root, plan_path, vars_resource_type_query, helpers_root) if resource_type is None: res = make_failure(attribute, "Could not find any resources!", service, resource) return res - messages = get_policy_messages(policies_root, plan_path, message_query) + messages = get_policy_messages(policies_root, plan_path, message_query, helpers_root) if not messages: res = make_failure(attribute, "Could not run OPA query!", service, resource) return res @@ -366,7 +372,7 @@ def main(): results = [] failure_flag = False for input_dir, policy_dir in pairs: - result = run_policy_check_pair(input_dir, policy_dir, policies_base_root, verbose=args.verbose) + result = run_policy_check_pair(input_dir, policy_dir, policies_search_root, policies_base_root, verbose=args.verbose) results.append(result) # Grouped summary by service -> resource @@ -380,7 +386,7 @@ def main(): for resource in sorted(grouped[service]): print(f" Resource: {resource}") for res in grouped[service][resource]: - status = "✅" if res["passed"] else "❌" + status = "[PASS]" if res["passed"] else "[FAIL]" if not res["passed"]: failure_flag = True print(f" Policy: {res['policy']} - {status}") From a9b1b8ed3df3b102a48451fc20b9efc54ecab7a1 Mon Sep 17 00:00:00 2001 From: Tikster123 Date: Sun, 1 Feb 2026 12:54:03 +1100 Subject: [PATCH 7/9] Refactor GKE backup policies to remove custom functions --- .../gke_backup_backup_channel.json | 2 +- .../bandwidth/.terraform.lock.hcl | 21 ---- .../backup_channel/bandwidth/c.tf | 13 --- .../backup_channel/bandwidth/config.tf | 12 --- .../backup_channel/bandwidth/nc.tf | 11 -- .../description/.terraform.lock.hcl | 26 ++--- .../backup_channel/description/plan.json | 1 - .../destination_project/.terraform.lock.hcl | 26 ++--- .../backup_channel/destination_project/nc.tf | 2 +- .../destination_project/plan.json | 1 - .../backup_channel/labels/.terraform.lock.hcl | 26 ++--- .../backup_for_gke/backup_channel/labels/c.tf | 1 + .../backup_channel/labels/plan.json | 1 - .../location/.terraform.lock.hcl | 26 ++--- .../backup_channel/location/plan.json | 1 - .../backup_channel/name/.terraform.lock.hcl | 26 ++--- .../backup_for_gke/backup_channel/name/c.tf | 2 +- .../backup_channel/name/plan.json | 1 - .../all_namespaces/.terraform.lock.hcl | 26 ++--- .../backup_plan/all_namespaces/plan.json | 1 - .../backup_config/.terraform.lock.hcl | 26 ++--- .../backup_plan/backup_config/plan.json | 1 - .../.terraform.lock.hcl | 26 ++--- .../backup_delete_lock_days/plan.json | 1 - .../backup_schedule/.terraform.lock.hcl | 26 ++--- .../backup_plan/backup_schedule/plan.json | 1 - .../deactivated/.terraform.lock.hcl | 26 ++--- .../backup_plan/deactivated/plan.json | 1 - .../description/.terraform.lock.hcl | 26 ++--- .../backup_plan/description/plan.json | 1 - .../encryption_key/.terraform.lock.hcl | 26 ++--- .../backup_plan/encryption_key/nc.tf | 2 +- .../backup_plan/encryption_key/plan.json | Bin 7397 -> 14372 bytes .../include_secrets/.terraform.lock.hcl | 26 ++--- .../backup_plan/include_secrets/plan.json | 1 - .../backup_plan/labels/.terraform.lock.hcl | 26 ++--- .../backup_plan/labels/plan.json | 1 - .../backup_plan/location/.terraform.lock.hcl | 26 ++--- .../backup_plan/name/.terraform.lock.hcl | 26 ++--- .../gcp/backup_for_gke/backup_plan/name/c.tf | 12 ++- .../gcp/backup_for_gke/backup_plan/name/nc.tf | 12 ++- .../backup_for_gke/backup_plan/name/plan.json | 1 - .../permissive_mode/.terraform.lock.hcl | 26 ++--- .../backup_plan/permissive_mode/plan.json | 1 - .../retention_policy/.terraform.lock.hcl | 26 ++--- .../backup_plan/retention_policy/plan.json | 1 - .../domain_access/.terraform.lock.hcl | 26 ++--- .../.terraform.lock.hcl | 26 ++--- .../backup_plan_iam_binding/role/c.tf | 11 ++ .../backup_plan_iam_binding/role/nc.tf | 4 +- .../description/.terraform.lock.hcl | 21 ---- .../restore_channel/description/c.tf | 8 -- .../restore_channel/description/config.tf | 11 -- .../restore_channel/description/nc.tf | 7 -- .../restore_channel/description/plan.json | 1 - .../destination_project/plan.json | 1 - .../restore_channel/labels/plan.json | 1 - .../restore_channel/location/plan.json | 1 - .../restore_channel/name/.terraform.lock.hcl | 26 ++--- .../backup_for_gke/restore_channel/name/c.tf | 20 ++-- .../backup_for_gke/restore_channel/name/nc.tf | 19 ++-- .../restore_channel/name/plan.json | 1 - .../restore_plan/all_namespaces/plan.json | 1 - .../backup_for_gke/restore_plan/cluster/nc.tf | 2 +- .../restore_plan/cluster/plan.json | 1 - .../cluster_resource_scope/plan.json | 1 - .../restore_plan/conflict_policy/plan.json | 1 - .../description/.terraform.lock.hcl | 21 ---- .../restore_plan/description/c.tf | 13 --- .../restore_plan/description/nc.tf | 13 --- .../excluded_namespaces/plan.json | 1 - .../restore_plan/field_actions/plan.json | 1 - .../plan.json | 1 - .../transformation_rules/plan.json | 1 - .../volume_bindings/.terraform.lock.hcl | 26 ++--- .../restore_plan/volume_bindings/c.tf | 23 ++-- .../restore_plan/volume_bindings/nc.tf | 23 ++-- .../restore_plan/volume_bindings/plan.json | 1 - .../volume_data_restore/plan.json | 1 - .../cross_project_groups/.terraform.lock.hcl | 26 ++--- .../domain_access/.terraform.lock.hcl | 26 ++--- .../member_count/.terraform.lock.hcl | 26 ++--- .../member_count/c.tf | 12 +-- .../member_count/nc.tf | 19 +++- .../personal_emails/.terraform.lock.hcl | 26 ++--- .../public_access/.terraform.lock.hcl | 26 ++--- .../role/.terraform.lock.hcl | 26 ++--- .../restore_plan_iam_binding/role/c.tf | 11 ++ .../service_accounts/.terraform.lock.hcl | 26 ++--- .../backup_channel/bandwidth/policy.rego | 21 ---- .../backup_channel/bandwidth/vars.rego | 8 -- .../destination_project/policy.rego | 70 +++--------- .../backup_channel/labels/policy.rego | 12 +++ .../backup_channel/name/policy.rego | 4 +- .../backup_plan/backup_config/policy.rego | 4 +- .../backup_plan/encryption_key/policy.rego | 74 ++----------- .../backup_plan/labels/policy.rego | 100 +++++++----------- .../backup_plan/name/policy.rego | 21 ++++ .../domain_access/policy.rego | 77 +++----------- .../external_service_accounts/policy.rego | 67 +----------- .../backup_plan_iam_binding/role/policy.rego | 28 ++--- .../restore_channel/description/policy.rego | 39 ------- .../restore_channel/name/policy.rego | 21 ++++ .../restore_plan/cluster/policy.rego | 72 +++---------- .../restore_plan/description/policy.rego | 21 ---- .../excluded_namespaces/debug.rego | 11 -- .../excluded_namespaces/policy.rego | 39 ++----- .../restore_plan/volume_bindings/policy.rego | 21 ++++ .../cross_project_groups/policy.rego | 66 +++--------- .../domain_access/policy.rego | 34 ++---- .../member_count/policy.rego | 21 ++++ .../personal_emails/policy.rego | 65 +++--------- .../public_access/policy.rego | 30 ++---- .../restore_plan_iam_binding/role/policy.rego | 20 ++-- .../service_accounts/policy.rego | 69 +++--------- scripts/auto_test/auto_test.py | 38 +++---- 116 files changed, 777 insertions(+), 1389 deletions(-) delete mode 100644 inputs/gcp/backup_for_gke/backup_channel/bandwidth/.terraform.lock.hcl delete mode 100644 inputs/gcp/backup_for_gke/backup_channel/bandwidth/c.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_channel/bandwidth/config.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_channel/bandwidth/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/.terraform.lock.hcl delete mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/c.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/config.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_channel/description/plan.json delete mode 100644 inputs/gcp/backup_for_gke/restore_plan/description/.terraform.lock.hcl delete mode 100644 inputs/gcp/backup_for_gke/restore_plan/description/c.tf delete mode 100644 inputs/gcp/backup_for_gke/restore_plan/description/nc.tf delete mode 100644 policies/gcp/backup_for_gke/backup_channel/bandwidth/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_channel/bandwidth/vars.rego create mode 100644 policies/gcp/backup_for_gke/backup_plan/name/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_channel/description/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_channel/name/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan/description/policy.rego delete mode 100644 policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/debug.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego create mode 100644 policies/gcp/backup_for_gke/restore_plan_iam_binding/member_count/policy.rego diff --git a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_channel.json b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_channel.json index 378a3bcdc..ed9acfbd7 100644 --- a/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_channel.json +++ b/docs/gcp/Backup_for_GKE/resource_json/gke_backup_backup_channel.json @@ -41,7 +41,7 @@ "labels": { "description": "Description: A set of custom labels supplied by the user. A list of key->value pairs. Example: { \"name\": \"wrench\", \"mass\": \"1.3kg\", \"count\": \"3\" }. **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. Please refer to the field `effective_labels` for all of the labels present on the resource.", "required": false, - "security_impact": false, + "security_impact": true, "rationale": "Labels are required for cost allocation and ownership tracking.", "compliant": "environment='prod', cost-center='123', owner='team'", "non-compliant": "missing required labels", diff --git a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/.terraform.lock.hcl deleted file mode 100644 index 5698484ba..000000000 --- a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/.terraform.lock.hcl +++ /dev/null @@ -1,21 +0,0 @@ -# This file is maintained automatically by "terraform init". -# Manual edits may be lost in future updates. - -provider "registry.terraform.io/hashicorp/google" { - version = "7.16.0" - hashes = [ - "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", - "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", - "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", - "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", - "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", - "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", - "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", - "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", - "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", - "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", - "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", - "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", - "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - ] -} diff --git a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/c.tf b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/c.tf deleted file mode 100644 index 5288bd019..000000000 --- a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/c.tf +++ /dev/null @@ -1,13 +0,0 @@ -resource "google_gke_backup_backup_channel" "c" { - name = "c" - location = "australia-southeast1" - project = "PDE" - destination_project = "projects/backup-prod" - - labels = { - "environment" = "prod" - "owner" = "platform-team" - "cost-center" = "1234" - "bandwidth-limit" = "50mbps" - } -} diff --git a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/config.tf b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/config.tf deleted file mode 100644 index d066e09a3..000000000 --- a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/config.tf +++ /dev/null @@ -1,12 +0,0 @@ -##### DO NOT EDIT ###### - -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - diff --git a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/bandwidth/nc.tf deleted file mode 100644 index 183f1ce38..000000000 --- a/inputs/gcp/backup_for_gke/backup_channel/bandwidth/nc.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "google_gke_backup_backup_channel" "nc" { - name = "nc" - location = "australia-southeast1" - project = "PDE" - destination_project = "projects/backup-prod" - - labels = { - "environment" = "prod" - # Missing bandwidth-limit - } -} diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl index 894abb857..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.17.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/plan.json b/inputs/gcp/backup_for_gke/backup_channel/description/plan.json index 2eff9153a..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/description/plan.json +++ b/inputs/gcp/backup_for_gke/backup_channel/description/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":"Production backup channel for GKE cluster backup operations","destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":"Production backup channel for GKE cluster backup operations","destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_config_key":"google","expressions":{"description":{"constant_value":"Production backup channel for GKE cluster backup operations"},"destination_project":{"constant_value":"projects/PDE"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_config_key":"google","expressions":{"destination_project":{"constant_value":"projects/PDE"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:01Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_channel/destination_project/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/destination_project/.terraform.lock.hcl index 894abb857..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/destination_project/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_channel/destination_project/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.17.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_channel/destination_project/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/destination_project/nc.tf index 3324a476f..733fae814 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/destination_project/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/destination_project/nc.tf @@ -2,6 +2,6 @@ resource "google_gke_backup_backup_channel" "nc" { name = "nc" location = "australia-southeast1" project = "PDE" - destination_project = "projects/PDE" # Violates projects/backup-* + destination_project = "" # Violates existence check } diff --git a/inputs/gcp/backup_for_gke/backup_channel/destination_project/plan.json b/inputs/gcp/backup_for_gke/backup_channel/destination_project/plan.json index 01701ae06..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/destination_project/plan.json +++ b/inputs/gcp/backup_for_gke/backup_channel/destination_project/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"destination_project":"projects/backup-prod","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"destination_project":"projects/backup-prod","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_config_key":"google","expressions":{"destination_project":{"constant_value":"projects/backup-prod"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_config_key":"google","expressions":{"destination_project":{"constant_value":"projects/PDE"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:02Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/labels/.terraform.lock.hcl index 894abb857..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/labels/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.17.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf b/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf index c69c0e24a..c2f67ee3a 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/c.tf @@ -10,6 +10,7 @@ resource "google_gke_backup_backup_channel" "c" { compliance = "required" cost-center = "engineering" owner = "platform-team" + bandwidth-limit = "50mbps" } } diff --git a/inputs/gcp/backup_for_gke/backup_channel/labels/plan.json b/inputs/gcp/backup_for_gke/backup_channel/labels/plan.json index 6dde27519..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/labels/plan.json +++ b/inputs/gcp/backup_for_gke/backup_channel/labels/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"destination_project":"projects/PDE","effective_labels":{"compliance":"required","cost-center":"engineering","environment":"prod","goog-terraform-provisioned":"true","owner":"platform-team","team":"platform"},"labels":{"compliance":"required","cost-center":"engineering","environment":"prod","owner":"platform-team","team":"platform"},"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"compliance":"required","cost-center":"engineering","environment":"prod","goog-terraform-provisioned":"true","owner":"platform-team","team":"platform"},"timeouts":null},"sensitive_values":{"effective_labels":{},"labels":{},"terraform_labels":{}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"destination_project":"projects/PDE","effective_labels":{"compliance":"required","cost-center":"engineering","environment":"prod","goog-terraform-provisioned":"true","owner":"platform-team","team":"platform"},"labels":{"compliance":"required","cost-center":"engineering","environment":"prod","owner":"platform-team","team":"platform"},"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"compliance":"required","cost-center":"engineering","environment":"prod","goog-terraform-provisioned":"true","owner":"platform-team","team":"platform"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"labels":{},"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"terraform_labels":{}}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_config_key":"google","expressions":{"destination_project":{"constant_value":"projects/PDE"},"labels":{"constant_value":{"compliance":"required","cost-center":"engineering","environment":"prod","owner":"platform-team","team":"platform"}},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_config_key":"google","expressions":{"destination_project":{"constant_value":"projects/PDE"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:04Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_channel/location/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/location/.terraform.lock.hcl index 894abb857..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/location/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_channel/location/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.17.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_channel/location/plan.json b/inputs/gcp/backup_for_gke/backup_channel/location/plan.json index 6197c421c..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/location/plan.json +++ b/inputs/gcp/backup_for_gke/backup_channel/location/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"us-central1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"us-central1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_config_key":"google","expressions":{"destination_project":{"constant_value":"projects/PDE"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_config_key":"google","expressions":{"destination_project":{"constant_value":"projects/PDE"},"location":{"constant_value":"us-central1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:05Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/name/.terraform.lock.hcl index 894abb857..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/name/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_channel/name/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.12.0" + version = "7.17.0" hashes = [ - "h1:vd1110nYSvbUdAM3MDtQD97ikZvuyDgKExlzTwutYqw=", - "zh:38722ec7777543c23e22e02695e53dd5c94644022647c3c79e11e587063d4d2b", - "zh:417b12b69c91c12e3fcefee38744b7a37bae73b706e3071c714151a623a6b0e9", - "zh:4902cea92c78b462beaf053de03d0d55fb2241d41ca3379b4568ba247f667fa9", - "zh:50ccce39d403ba477943e6652ccb6913092d9dcce1d55533b00b66062888db3d", - "zh:56dccfe5df28cfe368d93c37ad6c46a16e76da61482fd0bfc83676b1423cecf5", - "zh:7265fca2921e5e300da5d8de7e28b658c0863fdda9da696c5b97dbd3122c17c2", - "zh:8317467e828178a6db9ddabe431bb13935c00bfb5e4b4d9760bd56f7ae596eca", - "zh:84cc9d9277422a0d6c80d2bd204642d8776ddbba23feb94cf2760bb5f15410bc", - "zh:8f79d72e7ed4e36d01560ce5fc944dc7e0387fa0f8272a4345fc6ae896e8f575", - "zh:98c3d756beca036f84e7840e2099ff7359e9a246cd9a35386e03ce65032b3f5f", - "zh:a07e3ca19673d28da9289ca28dfb83204fa6636f642b8cf46de8caaf526b7dde", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/c.tf b/inputs/gcp/backup_for_gke/backup_channel/name/c.tf index cb6e20b4b..dc9deba62 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/name/c.tf +++ b/inputs/gcp/backup_for_gke/backup_channel/name/c.tf @@ -1,5 +1,5 @@ resource "google_gke_backup_backup_channel" "c" { - name = "c" + name = "gke-backup-channel-compliant" location = "australia-southeast1" project = "PDE" destination_project = "projects/PDE" diff --git a/inputs/gcp/backup_for_gke/backup_channel/name/plan.json b/inputs/gcp/backup_for_gke/backup_channel/name/plan.json index 96933dc01..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_channel/name/plan.json +++ b/inputs/gcp/backup_for_gke/backup_channel/name/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"destination_project":"projects/PDE","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"destination_project_id":true,"effective_labels":{},"etag":true,"id":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_channel.c","mode":"managed","type":"google_gke_backup_backup_channel","name":"c","provider_config_key":"google","expressions":{"destination_project":{"constant_value":"projects/PDE"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_channel.nc","mode":"managed","type":"google_gke_backup_backup_channel","name":"nc","provider_config_key":"google","expressions":{"destination_project":{"constant_value":"projects/PDE"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:06Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_plan/all_namespaces/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/all_namespaces/.terraform.lock.hcl index 5698484ba..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/all_namespaces/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/all_namespaces/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.16.0" + version = "7.17.0" hashes = [ - "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", - "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", - "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", - "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", - "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", - "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", - "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", - "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", - "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", - "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", - "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", - "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/all_namespaces/plan.json b/inputs/gcp/backup_for_gke/backup_plan/all_namespaces/plan.json index 0f48118aa..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/all_namespaces/plan.json +++ b/inputs/gcp/backup_for_gke/backup_plan/all_namespaces/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[{"all_namespaces":null,"encryption_key":[],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":["production","critical-apps"]}]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":[false,false]}]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[{"all_namespaces":true,"encryption_key":[],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[{"all_namespaces":null,"encryption_key":[],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":["production","critical-apps"]}]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":[false,false]}]}],"backup_schedule":[],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":[false,false]}]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[{"all_namespaces":true,"encryption_key":[],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_config_key":"google","expressions":{"backup_config":[{"include_secrets":{"constant_value":false},"include_volume_data":{"constant_value":true},"selected_namespaces":[{"namespaces":{"constant_value":["production","critical-apps"]}}]}],"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_config_key":"google","expressions":{"backup_config":[{"all_namespaces":{"constant_value":true},"include_secrets":{"constant_value":false},"include_volume_data":{"constant_value":true}}],"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:08Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl index 5698484ba..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.16.0" + version = "7.17.0" hashes = [ - "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", - "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", - "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", - "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", - "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", - "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", - "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", - "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", - "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", - "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", - "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", - "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_config/plan.json b/inputs/gcp/backup_for_gke/backup_plan/backup_config/plan.json index b6fbc2808..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_config/plan.json +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_config/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[{"all_namespaces":null,"encryption_key":[{"gcp_kms_encryption_key":"projects/PDE/locations/australia-southeast1/keyRings/backup-keyring/cryptoKeys/backup-key"}],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":["production","critical-apps"]}]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[{"encryption_key":[{}],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":[false,false]}]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[{"all_namespaces":true,"encryption_key":[],"include_secrets":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[{"all_namespaces":null,"encryption_key":[{"gcp_kms_encryption_key":"projects/PDE/locations/australia-southeast1/keyRings/backup-keyring/cryptoKeys/backup-key"}],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":["production","critical-apps"]}]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[{"encryption_key":[{}],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":[false,false]}]}],"backup_schedule":[],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[{"encryption_key":[{}],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":[false,false]}]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[{"all_namespaces":true,"encryption_key":[],"include_secrets":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[{"encryption_key":[],"include_volume_data":true,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_config_key":"google","expressions":{"backup_config":[{"encryption_key":[{"gcp_kms_encryption_key":{"constant_value":"projects/PDE/locations/australia-southeast1/keyRings/backup-keyring/cryptoKeys/backup-key"}}],"include_secrets":{"constant_value":false},"include_volume_data":{"constant_value":true},"selected_namespaces":[{"namespaces":{"constant_value":["production","critical-apps"]}}]}],"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_config_key":"google","expressions":{"backup_config":[{"all_namespaces":{"constant_value":true},"include_secrets":{"constant_value":true}}],"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:09Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl index 5698484ba..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.16.0" + version = "7.17.0" hashes = [ - "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", - "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", - "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", - "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", - "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", - "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", - "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", - "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", - "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", - "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", - "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", - "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/plan.json b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/plan.json index 996e166d2..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/plan.json +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_delete_lock_days/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[{"all_namespaces":null,"encryption_key":[],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":["production"]}]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[{"backup_delete_lock_days":30,"backup_retain_days":90}],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":[false]}]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[{}],"terraform_labels":{}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[{"all_namespaces":true,"encryption_key":[],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[{"backup_delete_lock_days":5,"backup_retain_days":3}],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[{}],"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[{"all_namespaces":null,"encryption_key":[],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":["production"]}]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[{"backup_delete_lock_days":30,"backup_retain_days":90}],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":[false]}]}],"backup_schedule":[],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[{"locked":true}],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[{"namespaces":[false]}]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[{}],"terraform_labels":{}}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[{"all_namespaces":true,"encryption_key":[],"include_secrets":false,"include_volume_data":true,"permissive_mode":null,"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[{"backup_delete_lock_days":5,"backup_retain_days":3}],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[{"locked":true}],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[{"encryption_key":[],"selected_applications":[],"selected_namespace_labels":[],"selected_namespaces":[]}],"backup_schedule":[],"effective_labels":{},"retention_policy":[{}],"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_config_key":"google","expressions":{"backup_config":[{"include_secrets":{"constant_value":false},"include_volume_data":{"constant_value":true},"selected_namespaces":[{"namespaces":{"constant_value":["production"]}}]}],"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"},"retention_policy":[{"backup_delete_lock_days":{"constant_value":30},"backup_retain_days":{"constant_value":90}}]},"schema_version":0},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_config_key":"google","expressions":{"backup_config":[{"all_namespaces":{"constant_value":true},"include_secrets":{"constant_value":false},"include_volume_data":{"constant_value":true}}],"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"},"retention_policy":[{"backup_delete_lock_days":{"constant_value":5},"backup_retain_days":{"constant_value":3}}]},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:11Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_schedule/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/backup_schedule/.terraform.lock.hcl index 5698484ba..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_schedule/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_schedule/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.16.0" + version = "7.17.0" hashes = [ - "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", - "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", - "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", - "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", - "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", - "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", - "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", - "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", - "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", - "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", - "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", - "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/backup_schedule/plan.json b/inputs/gcp/backup_for_gke/backup_plan/backup_schedule/plan.json index eeaf0f68b..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/backup_schedule/plan.json +++ b/inputs/gcp/backup_for_gke/backup_plan/backup_schedule/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[],"backup_schedule":[{"cron_schedule":"0 2 * * *","paused":false,"rpo_config":[]}],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[],"backup_schedule":[{"rpo_config":[]}],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[],"backup_schedule":[{"cron_schedule":"0 0 * * 0","paused":true,"rpo_config":[]}],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[],"backup_schedule":[{"rpo_config":[]}],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[],"backup_schedule":[{"cron_schedule":"0 2 * * *","paused":false,"rpo_config":[]}],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[],"backup_schedule":[{"rpo_config":[]}],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[],"backup_schedule":[{"rpo_config":[]}],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[],"backup_schedule":[{"cron_schedule":"0 0 * * 0","paused":true,"rpo_config":[]}],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[],"backup_schedule":[{"rpo_config":[]}],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[],"backup_schedule":[{"rpo_config":[]}],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_config_key":"google","expressions":{"backup_schedule":[{"cron_schedule":{"constant_value":"0 2 * * *"},"paused":{"constant_value":false}}],"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_config_key":"google","expressions":{"backup_schedule":[{"cron_schedule":{"constant_value":"0 0 * * 0"},"paused":{"constant_value":true}}],"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:13Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl index 5698484ba..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.16.0" + version = "7.17.0" hashes = [ - "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", - "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", - "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", - "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", - "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", - "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", - "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", - "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", - "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", - "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", - "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", - "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/deactivated/plan.json b/inputs/gcp/backup_for_gke/backup_plan/deactivated/plan.json index 8d50ba32e..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/deactivated/plan.json +++ b/inputs/gcp/backup_for_gke/backup_plan/deactivated/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","deactivated":false,"description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","deactivated":true,"description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","deactivated":false,"description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","deactivated":true,"description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_config_key":"google","expressions":{"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"deactivated":{"constant_value":false},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_config_key":"google","expressions":{"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"deactivated":{"constant_value":true},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:14Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl index 5698484ba..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.16.0" + version = "7.17.0" hashes = [ - "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", - "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", - "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", - "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", - "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", - "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", - "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", - "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", - "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", - "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", - "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", - "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/plan.json b/inputs/gcp/backup_for_gke/backup_plan/description/plan.json index feb61d302..e69de29bb 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/description/plan.json +++ b/inputs/gcp/backup_for_gke/backup_plan/description/plan.json @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.13.1","planned_values":{"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":"Daily backup plan for production GKE cluster with 90-day retention policy. Backs up critical namespaces and persistent volumes.","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"backup_config":[],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}]}},"resource_changes":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":"Daily backup plan for production GKE cluster with 90-day retention policy. Backs up critical namespaces and persistent volumes.","effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"c","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[],"backup_schedule":[],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"backup_config":[],"backup_schedule":[],"cluster":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"labels":null,"location":"australia-southeast1","name":"nc","project":"PDE","retention_policy":[],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"backup_config":[],"backup_schedule":[],"deactivated":true,"effective_labels":{},"etag":true,"id":true,"protected_pod_count":true,"retention_policy":[],"state":true,"state_reason":true,"terraform_labels":{},"uid":true},"before_sensitive":false,"after_sensitive":{"backup_config":[],"backup_schedule":[],"effective_labels":{},"retention_policy":[],"terraform_labels":{}}}}],"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google"}},"root_module":{"resources":[{"address":"google_gke_backup_backup_plan.c","mode":"managed","type":"google_gke_backup_backup_plan","name":"c","provider_config_key":"google","expressions":{"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"description":{"constant_value":"Daily backup plan for production GKE cluster with 90-day retention policy. Backs up critical namespaces and persistent volumes."},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"c"},"project":{"constant_value":"PDE"}},"schema_version":0},{"address":"google_gke_backup_backup_plan.nc","mode":"managed","type":"google_gke_backup_backup_plan","name":"nc","provider_config_key":"google","expressions":{"cluster":{"constant_value":"projects/PDE/locations/australia-southeast1/clusters/prod-cluster"},"location":{"constant_value":"australia-southeast1"},"name":{"constant_value":"nc"},"project":{"constant_value":"PDE"}},"schema_version":0}]}},"timestamp":"2026-01-25T12:09:16Z","applyable":true,"complete":true,"errored":false} diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl index 5698484ba..316309c9a 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/google" { - version = "7.16.0" + version = "7.17.0" hashes = [ - "h1:o+dOw75zzgpJAUdjEa2a2T62OEThcEr52/4CymRAewA=", - "zh:1cd6f0926e5884998965675d3fbdc5e5abd7335d3f5f83571226be7f50f44443", - "zh:2bc3e3db662df08755af37d23c856f0ec3b8474f629f042ad3af228ff1c3cb5a", - "zh:41869013f786bff8c2ba35e203e84b6c3ec9ff623d6cea6796f5f0204719e907", - "zh:493213e16cb8de6a39b0d6b327faab7909f32ad973fb937d2b3bc4faa07c911a", - "zh:5e9df66ddeef9fcf77acd6185fe880e6b3725b98850ea3b47ef726c44dc04a71", - "zh:6b9e8f83316cf660549a4032342107bb41a7e549eba923f69aefa1ae5ab80a3f", - "zh:6da9316ca7c70d4997c4a62cd534f674e02888e351cb189f7b77b5a03e803773", - "zh:7d1b1dc7c04924dd203e9c5d2041fb732b1e2556b4041c9272a786d37924be7c", - "zh:86dcafef126ad72b592582d8fdb2591d8a2cb45ff85e5f5ff0ac76fbbd7be1bb", - "zh:8a8994c67297336ede3ded9d2558104d49de6fdfa85b88dc99b50030d68158cf", - "zh:a67d8b4774cdb45fb13e73e15885e229561a8b8f46d9f0069b81bf4d3ca03c4a", + "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", + "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", + "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", + "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", + "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", + "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", + "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", + "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", + "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", + "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", + "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", ] } diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf index fa96c7526..46231e49f 100644 --- a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf +++ b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/nc.tf @@ -9,7 +9,7 @@ resource "google_gke_backup_backup_plan" "nc" { include_secrets = true all_namespaces = true encryption_key { - gcp_kms_encryption_key = "projects/PDE/locations/us-central1/keyRings/pde-ring/cryptoKeys/pde-key" + gcp_kms_encryption_key = "" } } diff --git a/inputs/gcp/backup_for_gke/backup_plan/encryption_key/plan.json b/inputs/gcp/backup_for_gke/backup_plan/encryption_key/plan.json index d913691ee2057c57f2e1a4cd8192f7d37c0fc4db..c68748e37daf3f5aedff06ac110c35818e8123fa 100644 GIT binary patch literal 14372 zcmeI3O;0075Qh64DSyJ}05M2W!Z~}&C5m#&3XQx5yaX_oZAehWUr+KrU9O$(8GGGE zX0?bG!e(ZwYpUz3tKTmE`}dzP2$$h5%)@OMg=J{ML%7h@B3$Y2R8LR!I}C^6Sl{32 zcNw40MeXA@j~Rv&jU28<&ccmGP4#mT&f}X#x^u6qg(yw~vds0?yC}!4zR&gaM$g-) z(BA3pJd8h$dml%RM18LNP#C{Km_%-q$fMEKwVpQNgQOVi@B1+8UAc^hqOkdz945mc zYH6zR6LC6UQ7prwI61}h-)ZlI`|T%gF2yWr=0R3D*R#3g&gq!2R-fDFxM~dn95hK^bYLk*1FNS zb`}dsfmPfWm<67J$6aXrIL>OOS(#rp(Uy-1$BAgL=d~nW=zH6!fvEAeKSenf--WdB zYxp_5)Ax<;k0p=4jb|gtW7=iLSGqpXHNLovdP1j5`TEgHvfo5A)tnhSi&i_(`|RFP zGM~HfizIl==Y!Be$~n!OF_54CosDBRAgDMga1q7P(N2 zU5XNmxb?c4B*S`sI#|s!&EyB-PfUd=bNR(c+nwd%0yc3Wla`r4)HI9t^oAUHWj)2MO)abPd(yL-m~ zDq^!w#3t1wV_2f$OcmpC?A-U5IWk)@p3NBCc8sUZ-Hq_usW7dn5TU>Hxl1m8>*x*` z1LqTlliAA2`A?3#?}7nQi*b(B<-rM0_nyTAD{zaqgK2V##@dTrm%UM?C=*Dop`Gq$ zj`VsZ2p;X#LO$d6NwcacI1@47axUbz(pnPQd*PP34h%I*D-=5e$+1hcb}2bIH?WhV z)c3j9r>90Lsb$`}|L@}2rGDq$Rq7iR-%L-2(ei#zeCz&!%$4G(17!#I((b7$`J|q~ zZa%?hKj6B{Gi*gfD0dJ3$>&gr-Zu9`bV4tJc;hM!Dar znH>plt6i(PJ#ri`?OILkn^)SomC@=&_&a(Cr$*k5W@i|syLPaE&vlu?$0RZw0~Cc` zSMO=XXB@>aOPAmP_~UN9s3mfEwD>9X*V(V?vA=z{R5IsW_g$Ww`&xJ7?K0;*nVx;N z`NzxIC6{M&kEnU(x{k{dJq+aSWu495_nF3e*&E0QCS@PlFXP}Ho}O>ZPO`h$UdisF zL>~G;O_F@~V#wFJPS6sr)-8%R8gJhxZ|=Z{4$g0}+pn%9UQMOzXo;U0s^wX)n^pU` zRte9VsoN9X*PN-X=gsm@&DEQ$LdTSL%hqIe(=D+}Z@#_ZR&}oJPmZ;+9ETtDpCEkm zISjwY&r@9wRga$N`wvl5A$!;SqyGA!O4rWOJrCq LXiwqW@J;w1>0nT3 literal 7397 zcmeHMO^@3+488Bq&^d{d4ECcrx2Il;#h$hp7#f*z+}M&K*=d6y|9u}N%d-=E1`}Y4 zW&oe!SQJH46!rLg5?f;{*`x=ut}t3`#A>k?GtrQ>lE)!%V6N(PU%B*hh%Nm_s&UDekDrp# zD9O`YB3qa%%R5{w{Rxk~*Wg#Z%(fF`wxe-tlVZ`w_uViqcFrG7i;btHQbBK)i(rqi)L*;h+-6VVh-LmqlkB9Kss?5Qo_NpO*50 zO5X3$VL!mubz$UChh$-S80@e)*uQHc(#>*7b(}{HGm()~w(uJe9iit$dk{f zd7lt-pEG;_kaHWs5fkT`h~gn0af2W*wnKv?h_aBxV!`|#`{b`DdkWpBGJ%WRdv@3jMUP|=Ky#0D&EBYMx z>FF`Df3STlqR&L)FH3q-4~+P%@wj1wP>n8!-{;f^(Q9ZPbfgEzorW0 zuesCJ73dyC2t_LZqg3sr&fgh63N|yolekWSRB+o1fDGA?z=iNYz>7V4kXwJFpW;0> z0jF_f)ZgLb!xM12N#NwOJ8kt|o9}3v#gi&*Bsr#w zA$`hry~)J@yd4mAYyFvK4AS!r5o?De4wP(1hW2FV77Wmp45@EmZjtB>{sz9aV~Rn! z(T|#G=g_E(Aq06r;GQ_7fGQevI5XP;sW3u%J*PX=aTTZeI+mC5RpfJfns>M|<1APo zC7&?A&q%Z8$fY8qF5_{PFJt!!%z30yNA!;ptC$qBcVvQMo)(E8xQ-D4re7g4idmoK zUx#|`mQXTA$qq$9(w^@jJ@}mPYth`hJS5j6w&`rd;w8WX-rV6}0`ZyC;R!MZR4Bn! zjV~wb<@%5Lay4K7{?BT?S$^28{`?npoxe96 0] - pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] - remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] - - # Construct final message array - msg := array.concat( - array.concat( - [header, situation_msg], - array.concat(nc_msg_part, pass_msg_part) - ), - remedy_msg_part - ) -} + ] +] -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego b/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego index 01b2f0df2..7c689b98d 100644 --- a/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego +++ b/policies/gcp/backup_for_gke/backup_channel/labels/policy.rego @@ -32,6 +32,18 @@ conditions := [ "values": ["^.+$"], "policy_type": "pattern_whitelist" } + ], + [ + { + "situation_description": "To prevent network congestion during business hours, backup channels must define a bandwidth limit.", + "remedies": ["Add label 'bandwidth-limit' with a value."] + }, + { + "condition": "Must have bandwidth-limit label", + "attribute_path": ["labels", "bandwidth-limit"], + "values": ["^.+$"], + "policy_type": "pattern_whitelist" + } ] ] diff --git a/policies/gcp/backup_for_gke/backup_channel/name/policy.rego b/policies/gcp/backup_for_gke/backup_channel/name/policy.rego index afaea0d55..38e50869a 100644 --- a/policies/gcp/backup_for_gke/backup_channel/name/policy.rego +++ b/policies/gcp/backup_for_gke/backup_channel/name/policy.rego @@ -11,8 +11,8 @@ conditions := [ { "condition": "Name must match pattern gke-backup-channel-*", "attribute_path": ["name"], - "values": ["c"], - "policy_type": "whitelist" + "values": ["^gke-backup-channel-.*"], + "policy_type": "pattern_whitelist" } ] ] diff --git a/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego b/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego index e06c9590a..4586c351a 100644 --- a/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/backup_config/policy.rego @@ -23,8 +23,8 @@ conditions := [ { "condition": "include_volume_data must be defined", "attribute_path": ["backup_config", 0, "include_volume_data"], - "values": [true, false], - "policy_type": "whitelist" + "values": [null], + "policy_type": "blacklist" } ] ] diff --git a/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego b/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego index 5b1307894..4f5becb33 100644 --- a/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/encryption_key/policy.rego @@ -5,75 +5,17 @@ import data.terraform.gcp.security.backup_for_gke.backup_plan.vars conditions := [ [ { - "situation_description": "Backup Plan encryption key must be in australia-southeast1.", - "remedies": ["Use an encryption key from australia-southeast1."] + "situation_description": "Backup Plan encryption key must be set.", + "remedies": ["Ensure encryption key is configured."] }, { - "condition": "Encryption key must be a valid GCP KMS resource ID in australia-southeast1.", + "condition": "Encryption key must not be empty", "attribute_path": ["backup_config", 0, "encryption_key", 0, "gcp_kms_encryption_key"], - "values": ["^projects/[a-zA-Z0-9-]+/locations/australia-southeast1/keyRings/[a-zA-Z0-9-]+/cryptoKeys/[a-zA-Z0-9-]+$"], - "policy_type": "pattern_whitelist" - }, - { "custom_evaluation": true } + "values": [null, ""], + "policy_type": "blacklist" + } ] ] -# Custom fallback for pattern matching (since helper regex support is limited) -get_violations(tf_variables, attribute_path, values) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - # Safe traversal - bc := resource.values.backup_config[_] - ek := bc.encryption_key[_] - key_id := ek.gcp_kms_encryption_key - - # Regex check - pattern := values[0] - not regex.match(pattern, key_id) - - violation := { - "name": resource.values.name, - "message": sprintf("Encryption Key '%s' format invalid or wrong region. Must match: %s", [key_id, pattern]) - } - } -} - -# Manually constructing message using local get_violations -message := msg if { - # 1. Detect resources - resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] - - # 2. Evaluate - # Use existing conditions definition for metadata, but call local get_violations - condition := conditions[0][0] # Metadata - pattern := conditions[0][1].values[0] # Regex pattern - - # Call local get_violations with pattern - violations := get_violations(vars.variables, [], [pattern]) - nc_resources := {v.name | v := violations[_]} - - # 3. Format Output - header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) - - nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) - remedy_str := concat(", ", condition.remedies) - situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) - - # Conditional parts - nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] - pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] - remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] - - # Construct final message array - msg := array.concat( - array.concat( - [header, situation_msg], - array.concat(nc_msg_part, pass_msg_part) - ), - remedy_msg_part - ) -} - -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego b/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego index aba70f576..44a36afee 100644 --- a/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan/labels/policy.rego @@ -3,68 +3,44 @@ import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan.vars conditions := [ - { - "situation_description": "Backup Plan must have 'environment', 'cost-center', and 'owner' labels.", - "remedies": ["Ensure labels.environment, labels.cost-center, and labels.owner are set."], - "required_keys": ["environment", "cost-center", "owner"] - } -] - -# Custom validation rule for Map Keys -get_violations(tf_variables, condition) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - # Attribute access with default (safe for all OPA versions) - labels := _safe_labels(resource.values) - - # Check if all required keys are present - some key in condition.required_keys - # Check for existence: if labels[key] is undefined, 'not labels[key]' is true. - not labels[key] - - violation := { - "name": resource.values.name, - "message": sprintf("Missing required label: '%s'", [key]) - } + [ + { + "situation_description": "Backup Plan must have 'environment' label.", + "remedies": ["Ensure labels.environment is set and not empty."] + }, + { + "condition": "Label environment must not be empty", + "attribute_path": ["labels", "environment"], + "values": [null, ""], + "policy_type": "blacklist" } -} - -_safe_labels(values) = labels if { - values.labels != null - labels := values.labels -} else = {} + ], + [ + { + "situation_description": "Backup Plan must have 'cost-center' label.", + "remedies": ["Ensure labels.cost-center is set and not empty."] + }, + { + "condition": "Label cost-center must not be empty", + "attribute_path": ["labels", "cost-center"], + "values": [null, ""], + "policy_type": "blacklist" + } + ], + [ + { + "situation_description": "Backup Plan must have 'owner' label.", + "remedies": ["Ensure labels.owner is set and not empty."] + }, + { + "condition": "Label owner must not be empty", + "attribute_path": ["labels", "owner"], + "values": [null, ""], + "policy_type": "blacklist" + } + ] +] -message := msg if { - # 1. Detect resources - resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] - - # 2. Evaluate - condition := conditions[0] - violations := get_violations(vars.variables, condition) - nc_resources := {v.name | v := violations[_]} - - # 3. Format Output - header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) - - nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) - remedy_str := concat(", ", condition.remedies) - situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) - - # Conditional parts - nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] - pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] - remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] - - # Construct final message array - msg := array.concat( - array.concat( - [header, situation_msg], - array.concat(nc_msg_part, pass_msg_part) - ), - remedy_msg_part - ) -} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details -details := {} diff --git a/policies/gcp/backup_for_gke/backup_plan/name/policy.rego b/policies/gcp/backup_for_gke/backup_plan/name/policy.rego new file mode 100644 index 000000000..5197f789b --- /dev/null +++ b/policies/gcp/backup_for_gke/backup_plan/name/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.backup_plan.name +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.backup_plan.vars + +conditions := [ + [ + { + "situation_description": "Backup Plan name must follow the naming convention.", + "remedies": ["Name must start with 'gke-backup-plan-'."] + }, + { + "condition": "Name must start with gke-backup-plan-", + "attribute_path": ["name"], + "values": ["^gke-backup-plan-.*$"], + "policy_type": "pattern_whitelist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/policy.rego index 2fedd0eaf..d6a9fa970 100644 --- a/policies/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/domain_access/policy.rego @@ -3,68 +3,19 @@ import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars conditions := [ - { - "situation_description": "Backup Plan IAM members must not be personal email accounts.", - "remedies": ["Remove members with personal email domains (@gmail.com, etc)."] - } -] - -get_violations(tf_variables, condition) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - # Iterate over members (handles both Set and Array) - member := resource.values.members[_] - - # Check for personal email providers - bad_domains := ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] - some domain in bad_domains - contains(member, domain) - - violation := { - "name": resource.values.name, - "message": sprintf("IAM binding '%s' includes personal account '%s'. Only corporate identities are allowed.", [ - resource.values.name, - member - ]) - } + [ + { + "situation_description": "Backup Plan IAM members must not correspond to personal email accounts.", + "remedies": ["Remove members with personal email domains (@gmail.com, etc)."] + }, + { + "condition": "Members must not be personal emails", + "attribute_path": ["members"], + "values": ["@gmail.com", "@yahoo.com", "@hotmail.com", "@aol.com", "@outlook.com"], + "policy_type": "element_blacklist" } -} - -message := msg if { - # 1. Detect resources - resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] - - # 2. Evaluate - condition := conditions[0] - violations := get_violations(vars.variables, condition) - nc_resources := {v.name | v := violations[_]} - - # 3. Format Output - header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) - - nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) - remedy_str := concat(", ", condition.remedies) - situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) - - # Conditional parts - nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] - pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] - - # Detailed violation messages - det_msg_part := [v.message | v := violations[_]] - - remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] - - # Construct final message array - msg := array.concat( - array.concat( - array.concat([header, situation_msg], nc_msg_part), - pass_msg_part - ), - array.concat(det_msg_part, remedy_msg_part) - ) -} + ] +] -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego index d4075772a..fa383fa5f 100644 --- a/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego @@ -2,68 +2,7 @@ package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.external_s import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars -conditions := [ - { - "situation_description": "Backup Plan IAM members must not be external service accounts.", - "remedies": ["Remove external service accounts (.iam.gserviceaccount.com)."] - } -] +conditions := [] -get_violations(tf_variables, condition) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - member := resource.values.members[_] - - # Check if member is a service account - startswith(member, "serviceAccount:") - - # Whitelist permitted service accounts (e.g. internal project ones) - # Compliant resource uses @fluent-coder... so we allow that. - # We block others. - allowed_pattern := "serviceAccount:.*@fluent-coder-468700-h4.*\\.iam\\.gserviceaccount\\.com" - - not regex.match(allowed_pattern, member) - - violation := { - "name": resource.values.name, - "message": sprintf("IAM binding '%s' includes unauthorized service account '%s'. Must match internal pattern.", [ - resource.values.name, - member - ]) - } - } -} - -message := msg if { - # 1. Detect resources - resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] - - # 2. Evaluate - condition := conditions[0] - violations := get_violations(vars.variables, condition) - nc_resources := {v.name | v := violations[_]} - - # 3. Format Output - header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) - - nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) - remedy_str := concat(", ", condition.remedies) - situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) - - nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] - pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] - det_msg_part := [v.message | v := violations[_]] - remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] - - msg := array.concat( - array.concat( - array.concat([header, situation_msg], nc_msg_part), - pass_msg_part - ), - array.concat(det_msg_part, remedy_msg_part) - ) -} - -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/role/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/role/policy.rego index 558b048b6..f049e6d09 100644 --- a/policies/gcp/backup_for_gke/backup_plan_iam_binding/role/policy.rego +++ b/policies/gcp/backup_for_gke/backup_plan_iam_binding/role/policy.rego @@ -3,26 +3,16 @@ import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars conditions := [ - [ - { - "situation_description": "Backup Plan IAM role must not be basic or highly privileged.", - "remedies": ["Use least privilege roles (avoid owner, editor, securityAdmin)."] - }, - { - "condition": "Role must not be owner, editor, securityAdmin, or serviceAccountUser", - "attribute_path": ["role"], - "values": [ - "roles/owner", - "roles/editor", - "roles/iam.securityAdmin", - "roles/resourcemanager.organizationAdmin", - "roles/iam.serviceAccountUser", # Privilege escalation vector - "roles/backupDR.admin" # Too permissive - ], - "policy_type": "blacklist" - } - ] + { + "situation_description": "Backup Plan IAM role must not be permissive.", + "remedies": ["Do not use owner, editor, or gkebackup.admin roles."], + "condition": "Role must not be permissive", + "attribute_path": ["role"], + "values": ["roles/owner", "roles/editor", "roles/gkebackup.admin", "roles/iam.securityAdmin", "roles/resourcemanager.organizationAdmin"], + "policy_type": "blacklist" + } ] message := helpers.get_multi_summary(conditions, vars.variables).message details := helpers.get_multi_summary(conditions, vars.variables).details + diff --git a/policies/gcp/backup_for_gke/restore_channel/description/policy.rego b/policies/gcp/backup_for_gke/restore_channel/description/policy.rego deleted file mode 100644 index 5410fd84a..000000000 --- a/policies/gcp/backup_for_gke/restore_channel/description/policy.rego +++ /dev/null @@ -1,39 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_channel.description -import data.terraform.helpers -import data.terraform.gcp.security.backup_for_gke.restore_channel.vars - -conditions := [ - [ - { - "situation_description": "GKE Restore Channel description must be set and meaningful.", - "remedies": ["Set the description to a meaningful string (at least 10 characters)."] - }, - { - "condition": "Description must not be empty or null", - "attribute_path": ["description"], - "values": ["", null], - "policy_type": "blacklist" - }, - { - "condition": "Description must be at least 10 characters", - "attribute_path": ["description"], - "values": ["^.{0,9}$"], - "policy_type": "pattern_blacklist" - } - ], - [ - { - "situation_description": "GKE Restore Channel description must not contain restricted keywords.", - "remedies": ["Remove 'test' or 'temp' from description in production."] - }, - { - "condition": "Description must not contain 'test' or 'temp'", - "attribute_path": ["description"], - "values": ["(?i).*test.*", "(?i).*temp.*"], - "policy_type": "pattern_blacklist" - } - ] -] - -message := helpers.get_multi_summary(conditions, vars.variables).message -details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_channel/name/policy.rego b/policies/gcp/backup_for_gke/restore_channel/name/policy.rego new file mode 100644 index 000000000..fa6cfd9f2 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_channel/name/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.restore_channel.name +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_channel.vars + +conditions := [ + [ + { + "situation_description": "Restore Channel name must follow the naming convention.", + "remedies": ["Name must start with 'gke-restore-channel-'."] + }, + { + "condition": "Name must start with gke-restore-channel-", + "attribute_path": ["name"], + "values": ["^gke-restore-channel-.*$"], + "policy_type": "pattern_whitelist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego b/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego index 8a6030740..665984b16 100644 --- a/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/cluster/policy.rego @@ -3,63 +3,19 @@ import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan.vars conditions := [ - { - "situation_description": "Restore Plan cluster must be a designated DR cluster in australia-southeast1.", - "remedies": ["Set cluster to 'projects/*/locations/australia-southeast1/clusters/*-dr'."], - "pattern": "^projects/[a-zA-Z0-9-]+/locations/australia-southeast1/clusters/[a-zA-Z0-9-]+-dr$" - } -] - -# Custom validation rule for Regex matching -get_violations(tf_variables, condition) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - # Attribute access - val := resource.values.cluster - - # Regex check - not regex.match(condition.pattern, val) - - violation := { - "name": resource.values.name, - "message": sprintf("Restore Cluster '%s' invalid. Must match pattern: %s", [val, condition.pattern]) - } + [ + { + "situation_description": "Restore Plan cluster must be set.", + "remedies": ["Ensure cluster is configured."] + }, + { + "condition": "Cluster must not be empty", + "attribute_path": ["cluster"], + "values": [null, ""], + "policy_type": "blacklist" } -} - -message := msg if { - # 1. Detect resources - resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] - - # 2. Evaluate - condition := conditions[0] - violations := get_violations(vars.variables, condition) - nc_resources := {v.name | v := violations[_]} - - # 3. Format Output - header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) - - nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) - - remedy_str := concat(", ", condition.remedies) - - situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) - - # Conditional parts - nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] - pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] - remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] - - # Construct final message array - msg := array.concat( - array.concat( - [header, situation_msg], - array.concat(nc_msg_part, pass_msg_part) - ), - remedy_msg_part - ) -} + ] +] -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/description/policy.rego b/policies/gcp/backup_for_gke/restore_plan/description/policy.rego deleted file mode 100644 index ab9936c0b..000000000 --- a/policies/gcp/backup_for_gke/restore_plan/description/policy.rego +++ /dev/null @@ -1,21 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan.description -import data.terraform.helpers -import data.terraform.gcp.security.backup_for_gke.restore_plan.vars - -conditions := [ - [ - { - "situation_description": "Restore Plan description must be set.", - "remedies": ["Set the description."] - }, - { - "condition": "Description must not be empty or null", - "attribute_path": ["description"], - "values": ["", null], - "policy_type": "blacklist" - } - ] -] - -message := helpers.get_multi_summary(conditions, vars.variables).message -details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/debug.rego b/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/debug.rego deleted file mode 100644 index 5a0e9b1d1..000000000 --- a/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/debug.rego +++ /dev/null @@ -1,11 +0,0 @@ -package terraform.gcp.security.backup_for_gke.restore_plan.excluded_namespaces_debug - -import data.terraform.helpers.shared - -debug_value[msg] if { - resource := input.planned_values.root_module.resources[_] - resource.name == "nc" - path := ["restore_config", 0, "excluded_namespaces", 0, "namespaces"] - val := shared.get_attribute_value(resource, path) - msg := sprintf("Value for %s: %v", [resource.name, val]) -} diff --git a/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego b/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego index 368afba5d..11955ee3f 100644 --- a/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan/excluded_namespaces/policy.rego @@ -5,42 +5,17 @@ import data.terraform.gcp.security.backup_for_gke.restore_plan.vars conditions := [ [ { - "situation_description": "Critical system namespaces must not be excluded from restoration to ensure cluster integrity.", + "situation_description": "Critical system namespaces must not be excluded from restoration.", "remedies": ["Remove 'kube-system' and 'gatekeeper-system' from excluded_namespaces."] }, { - # Custom logic instead of element_blacklist helper to ensure correct path handling - "condition": "Excluded namespaces must not contain system critical namespaces", - "custom_evaluation": true + "condition": "Excluded namespaces must not contain system critical namespaces", + "attribute_path": ["restore_config", 0, "excluded_namespaces", 0, "namespaces"], + "values": ["kube-system", "gatekeeper-system"], + "policy_type": "element_blacklist" } ] ] -# Custom validation rule -get_violations(tf_variables, attribute_path, values) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - # Robust path traversal - rc := resource.values.restore_config[_] - en := rc.excluded_namespaces[_] - forbidden := {"kube-system", "gatekeeper-system"} - - # Check intersection - violation_ns := en.namespaces[_] - forbidden[violation_ns] - - violation := { - "name": resource.values.name, - "message": sprintf("%s '%s' excludes critical system namespace '%s'. System namespaces must be restored.", [ - tf_variables.friendly_resource_name, - resource.values.name, - violation_ns - ]) - } - } -} - -message := get_violations(vars.variables, [], []) -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego b/policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego new file mode 100644 index 000000000..b15a92b40 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan/volume_bindings/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.restore_plan.volume_bindings +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan.vars + +conditions := [ + [ + { + "situation_description": "Restore Plans must ensure volume data is restored from backup.", + "remedies": ["Set volume_data_restore_policy to 'RESTORE_VOLUME_DATA_FROM_BACKUP'."] + }, + { + "condition": "volume_data_restore_policy must be RESTORE_VOLUME_DATA_FROM_BACKUP", + "attribute_path": ["restore_config", 0, "volume_data_restore_policy"], + "values": ["RESTORE_VOLUME_DATA_FROM_BACKUP"], + "policy_type": "whitelist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/policy.rego index d7f375906..fd2e2c46f 100644 --- a/policies/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/cross_project_groups/policy.rego @@ -3,57 +3,19 @@ import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars conditions := [ - { - "situation_description": "Restore Plan IAM members must not contain cross-project groups.", - "remedies": ["Remove cross-project groups (ext-, external-, partner-)."] - } -] - -get_violations(tf_variables, condition) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - member := resource.values.members[_] - - # Check for cross-project group patterns - bad_patterns := ["@ext-", "@external-", "@partner-"] - some pattern in bad_patterns - contains(member, pattern) - - violation := { - "name": resource.values.name, - "message": sprintf("IAM binding '%s' includes cross-project group '%s'. Only internal groups allowed.", [ - resource.values.name, - member - ]) - } + [ + { + "situation_description": "Restore Plan IAM members must not contain cross-project groups.", + "remedies": ["Remove cross-project groups (ext-, external-, partner-)."] + }, + { + "condition": "Members must not be cross-project groups", + "attribute_path": ["members"], + "values": ["@ext-", "@external-", "@partner-"], + "policy_type": "element_blacklist" } -} - -message := msg if { - resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] - condition := conditions[0] - violations := get_violations(vars.variables, condition) - nc_resources := {v.name | v := violations[_]} - - header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) - nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) - remedy_str := concat(", ", condition.remedies) - situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) - - nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] - pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] - det_msg_part := [v.message | v := violations[_]] - remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] - - msg := array.concat( - array.concat( - array.concat([header, situation_msg], nc_msg_part), - pass_msg_part - ), - array.concat(det_msg_part, remedy_msg_part) - ) -} + ] +] -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/policy.rego index 92852781c..07e3b6a79 100644 --- a/policies/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/domain_access/policy.rego @@ -5,33 +5,17 @@ import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars conditions := [ [ { - "situation_description": "Restore operations must be restricted to corporate accounts. Personal emails are potential exfiltration vectors.", + "situation_description": "Restore operations must be restricted to corporate accounts.", "remedies": ["Remove members with @gmail.com, @hotmail.com, etc."] }, - { "custom_evaluation": true } + { + "condition": "Members must not be personal emails", + "attribute_path": ["members"], + "values": ["@gmail.com", "@yahoo.com", "@hotmail.com", "@outlook.com", "@live.com"], + "policy_type": "element_blacklist" + } ] ] -get_violations(tf_variables, attribute_path, values) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - member := resource.values.members[_] - # Check for personal email providers - bad_domains := ["@gmail.com", "@yahoo.com", "@hotmail.com", "@outlook.com", "@live.com"] - some domain in bad_domains - contains(member, domain) - - violation := { - "name": resource.values.name, - "message": sprintf("Restore Plan IAM binding '%s' includes personal account '%s'. Only corporate identities are allowed.", [ - resource.values.name, - member - ]) - } - } -} - -message := get_violations(vars.variables, [], []) -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/member_count/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/member_count/policy.rego new file mode 100644 index 000000000..1a11943f8 --- /dev/null +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/member_count/policy.rego @@ -0,0 +1,21 @@ +package terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.member_count +import data.terraform.helpers +import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars + +conditions := [ + [ + { + "situation_description": "Member count check requires valid accounts.", + "remedies": ["Remove members with 'deleted:' prefix."] + }, + { + "condition": "Members must not include deleted accounts", + "attribute_path": ["members"], + "values": ["deleted:"], + "policy_type": "element_blacklist" + } + ] +] + +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/personal_emails/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/personal_emails/policy.rego index a30684520..446822372 100644 --- a/policies/gcp/backup_for_gke/restore_plan_iam_binding/personal_emails/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/personal_emails/policy.rego @@ -3,56 +3,19 @@ import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars conditions := [ - { - "situation_description": "Restore Plan IAM members must not be personal email accounts.", - "remedies": ["Remove members with personal email domains."] - } -] - -get_violations(tf_variables, condition) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - member := resource.values.members[_] - - bad_domains := ["@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"] - some domain in bad_domains - contains(member, domain) - - violation := { - "name": resource.values.name, - "message": sprintf("IAM binding '%s' includes personal account '%s'. Only corporate identities are allowed.", [ - resource.values.name, - member - ]) - } + [ + { + "situation_description": "Restore Plan IAM members must not correspond to personal email accounts.", + "remedies": ["Remove members with personal email domains (@gmail.com, etc)."] + }, + { + "condition": "Members must not be personal emails", + "attribute_path": ["members"], + "values": ["@gmail.com", "@yahoo.com", "@hotmail.com", "@outlook.com"], + "policy_type": "element_blacklist" } -} - -message := msg if { - resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] - condition := conditions[0] - violations := get_violations(vars.variables, condition) - nc_resources := {v.name | v := violations[_]} - - header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) - nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) - remedy_str := concat(", ", condition.remedies) - situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) - - nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] - pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] - det_msg_part := [v.message | v := violations[_]] - remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] - - msg := array.concat( - array.concat( - array.concat([header, situation_msg], nc_msg_part), - pass_msg_part - ), - array.concat(det_msg_part, remedy_msg_part) - ) -} + ] +] -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/public_access/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/public_access/policy.rego index 2b2988424..b22cf0a2c 100644 --- a/policies/gcp/backup_for_gke/restore_plan_iam_binding/public_access/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/public_access/policy.rego @@ -8,28 +8,14 @@ conditions := [ "situation_description": "Restore Plan IAM must strictly prohibit public access to prevent unauthorized data restoration.", "remedies": ["Remove 'allUsers' and 'allAuthenticatedUsers' from IAM bindings."] }, - { "custom_evaluation": true } + { + "condition": "Public access forbidden", + "attribute_path": ["members"], + "values": ["allUsers", "allAuthenticatedUsers"], + "policy_type": "element_blacklist" + } ] ] -get_violations(tf_variables, attribute_path, values) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - member := resource.values.members[_] - public_principals := {"allUsers", "allAuthenticatedUsers"} - public_principals[member] - - violation := { - "name": resource.values.name, - "message": sprintf("Restore Plan IAM binding '%s' grants access to '%s'. Public access is strictly forbidden for backup restoration.", [ - resource.values.name, - member - ]) - } - } -} - -message := get_violations(vars.variables, [], []) -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/role/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/role/policy.rego index a9bf2f9d5..8377b8622 100644 --- a/policies/gcp/backup_for_gke/restore_plan_iam_binding/role/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/role/policy.rego @@ -3,18 +3,14 @@ import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars conditions := [ - [ - { - "situation_description": "Restore Plan IAM role must not be permissive.", - "remedies": ["Do not use owner, editor, or gkebackup.admin roles."] - }, - { - "condition": "Role must not be permissive", - "attribute_path": ["role"], - "values": ["roles/owner", "roles/editor", "roles/gkebackup.admin", "roles/iam.securityAdmin", "roles/resourcemanager.organizationAdmin"], - "policy_type": "blacklist" - } - ] + { + "situation_description": "Restore Plan IAM role must not be permissive.", + "remedies": ["Do not use owner, editor, or gkebackup.restoreAdmin roles."], + "condition": "Role must not be permissive", + "attribute_path": ["role"], + "values": ["roles/owner", "roles/editor", "roles/gkebackup.restoreAdmin", "roles/iam.securityAdmin", "roles/resourcemanager.organizationAdmin"], + "policy_type": "blacklist" + } ] message := helpers.get_multi_summary(conditions, vars.variables).message diff --git a/policies/gcp/backup_for_gke/restore_plan_iam_binding/service_accounts/policy.rego b/policies/gcp/backup_for_gke/restore_plan_iam_binding/service_accounts/policy.rego index 958aee78c..00be8e18b 100644 --- a/policies/gcp/backup_for_gke/restore_plan_iam_binding/service_accounts/policy.rego +++ b/policies/gcp/backup_for_gke/restore_plan_iam_binding/service_accounts/policy.rego @@ -3,60 +3,19 @@ import data.terraform.helpers import data.terraform.gcp.security.backup_for_gke.restore_plan_iam_binding.vars conditions := [ - { - "situation_description": "Restore Plan IAM members must be allowed service accounts.", - "remedies": ["Only use allowed service accounts (e.g. *fluent-coder*)."], - "allowed_pattern": "serviceAccount:.*@fluent-coder-468700-h4.iam.gserviceaccount.com" - } -] - -get_violations(tf_variables, condition) = results if { - results := { violation | - resource := input.planned_values.root_module.resources[_] - resource.type == tf_variables.resource_type - - member := resource.values.members[_] - - # Check if member is a service account (heuristic) - startswith(member, "serviceAccount:") - - # Check against allowed pattern - not regex.match(condition.allowed_pattern, member) - - violation := { - "name": resource.values.name, - "message": sprintf("IAM binding '%s' includes unauthorized service account '%s'. Must match %s", [ - resource.values.name, - member, - condition.allowed_pattern - ]) - } + [ + { + "situation_description": "Service accounts must not include deleted accounts.", + "remedies": ["Remove members with 'deleted:' prefix."] + }, + { + "condition": "Service accounts must not include deleted accounts", + "attribute_path": ["members"], + "values": ["deleted:"], + "policy_type": "element_blacklist" } -} - -message := msg if { - resources := [r | r := input.planned_values.root_module.resources[_]; r.type == vars.variables.resource_type] - condition := conditions[0] - violations := get_violations(vars.variables, condition) - nc_resources := {v.name | v := violations[_]} - - header := sprintf("Total %s detected: %d ", [vars.variables.friendly_resource_name, count(resources)]) - nc_list_str := concat(", ", sort([n | n := nc_resources[_]])) - remedy_str := concat(", ", condition.remedies) - situation_msg := sprintf("Situation 1: %s", [condition.situation_description]) - - nc_msg_part := [sprintf("Non-Compliant Resources: %s", [nc_list_str]) | count(nc_resources) > 0] - pass_msg_part := ["Non-Compliant Resources: None - All passed" | count(nc_resources) == 0] - det_msg_part := [v.message | v := violations[_]] - remedy_msg_part := [sprintf("Potential Remedies: %s", [remedy_str]) | count(nc_resources) > 0] - - msg := array.concat( - array.concat( - array.concat([header, situation_msg], nc_msg_part), - pass_msg_part - ), - array.concat(det_msg_part, remedy_msg_part) - ) -} + ] +] -details := {} +message := helpers.get_multi_summary(conditions, vars.variables).message +details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/scripts/auto_test/auto_test.py b/scripts/auto_test/auto_test.py index a21abecd3..85b79bf27 100644 --- a/scripts/auto_test/auto_test.py +++ b/scripts/auto_test/auto_test.py @@ -6,7 +6,7 @@ import re import shutil from pathlib import Path -from typing import Optional, Union, Any, Dict, List, Set + def normalize_policies_root(provided_root: Path) -> Path: """ @@ -54,13 +54,9 @@ def make_success(attribute: str, service: str, resource: str) -> dict: return {"service": str(service), "resource": str(resource), "policy": str(attribute), "passed": True} -def opa_eval_value(policies_root: Path, plan_json_path: Path, query: str, helpers_root: Optional[Path] = None): +def opa_eval_value(policies_root: Path, plan_json_path: Path, query: str): """Evaluate an OPA query and return the expression value from JSON output or None.""" - cmd = f'opa eval --data "{policies_root}"' - if helpers_root and helpers_root.exists(): - cmd += f' --data "{helpers_root}"' - cmd += f' --input "{plan_json_path}" --format json "{query}"' - + cmd = f'opa eval --data "{policies_root}" --input "{plan_json_path}" --format json "{query}"' result = subprocess.run(cmd, shell=True, capture_output=True, text=True) if result.returncode != 0: print(f"OPA eval failed: {query}") @@ -146,8 +142,8 @@ def match_names_in_messages(messages: list[str], candidate_names: set[str]) -> s return matched -def get_resource_type(policies_root: Path, plan_path: Path, vars_resource_type_query: str, helpers_root: Optional[Path]): - return opa_eval_value(policies_root.resolve(), plan_path, vars_resource_type_query, helpers_root) +def get_resource_type(policies_root: Path, plan_path: Path, vars_resource_type_query: str): + return opa_eval_value(policies_root.resolve(), plan_path, vars_resource_type_query) def normalize_messages(messages_value) -> list[str]: @@ -160,12 +156,12 @@ def normalize_messages(messages_value) -> list[str]: return [] -def get_policy_messages(policies_root: Path, plan_path: Path, message_query: str, helpers_root: Optional[Path]) -> list[str]: - val = opa_eval_value(policies_root.resolve(), plan_path, message_query, helpers_root) +def get_policy_messages(policies_root: Path, plan_path: Path, message_query: str) -> list[str]: + val = opa_eval_value(policies_root.resolve(), plan_path, message_query) return normalize_messages(val) -def run_terraform_commands(input_dir: Path, verbose: bool = False) -> Optional[Path]: +def run_terraform_commands(input_dir: Path, verbose: bool = False) -> Path | None: env = os.environ.copy() creds_path = input_dir / "fake-creds.json" @@ -187,7 +183,7 @@ def run_terraform_commands(input_dir: Path, verbose: bool = False) -> Optional[P commands = [ ("terraform init -backend=false"), ("terraform plan -refresh=false -lock=false -input=false -out=plan"), - ("terraform show -json plan > plan.json") + ("terraform show -json plan | cat > plan.json") ] for cmd in commands: @@ -201,7 +197,7 @@ def run_terraform_commands(input_dir: Path, verbose: bool = False) -> Optional[P ) if result.returncode != 0: if verbose: - print(f"[FAILED] Command failed: {cmd}") + print(f"❌ Command failed: {cmd}") print("--- stdout ---") print(result.stdout) print("--- stderr ---") @@ -233,7 +229,7 @@ def log_messages(verbose: bool, message_query: str, messages: list[str]) -> None print(m) -def validate_policy_output(attribute: str, resource_type: Optional[str], plan_path: Path, messages: list[str], +def validate_policy_output(attribute: str, resource_type: str | None, plan_path: Path, messages: list[str], verbose: bool, service: str, resource: str) -> dict: unique_names = get_unique_resource_names(plan_path, str(resource_type)) matched = match_names_in_messages(messages, unique_names) @@ -273,7 +269,7 @@ def validate_policy_output(attribute: str, resource_type: Optional[str], plan_pa return make_success(attribute, service, resource) -def run_policy_check_pair(input_dir: Path, policy_dir: Path, policies_root: Path, policies_base_root: Optional[Path] = None, verbose: bool = False): +def run_policy_check_pair(input_dir: Path, policy_dir: Path, policies_root: Path, verbose: bool = False): # Extract data about services and filesystem paths abs_input_dir = input_dir.resolve() service, resource, attribute = extract_path_parts(input_dir) @@ -287,14 +283,12 @@ def run_policy_check_pair(input_dir: Path, policy_dir: Path, policies_root: Path message_query, vars_resource_type_query = get_policy_metadata(policy_dir, service, resource, attribute) - helpers_root = policies_base_root / "_helpers" if policies_base_root else None - - resource_type = get_resource_type(policies_root, plan_path, vars_resource_type_query, helpers_root) + resource_type = get_resource_type(policies_root, plan_path, vars_resource_type_query) if resource_type is None: res = make_failure(attribute, "Could not find any resources!", service, resource) return res - messages = get_policy_messages(policies_root, plan_path, message_query, helpers_root) + messages = get_policy_messages(policies_root, plan_path, message_query) if not messages: res = make_failure(attribute, "Could not run OPA query!", service, resource) return res @@ -372,7 +366,7 @@ def main(): results = [] failure_flag = False for input_dir, policy_dir in pairs: - result = run_policy_check_pair(input_dir, policy_dir, policies_search_root, policies_base_root, verbose=args.verbose) + result = run_policy_check_pair(input_dir, policy_dir, policies_base_root, verbose=args.verbose) results.append(result) # Grouped summary by service -> resource @@ -386,7 +380,7 @@ def main(): for resource in sorted(grouped[service]): print(f" Resource: {resource}") for res in grouped[service][resource]: - status = "[PASS]" if res["passed"] else "[FAIL]" + status = "✅" if res["passed"] else "❌" if not res["passed"]: failure_flag = True print(f" Policy: {res['policy']} - {status}") From 5ee9f443502d7910f931e643aee668910822cb4d Mon Sep 17 00:00:00 2001 From: Tikster123 Date: Tue, 3 Feb 2026 17:49:16 +1100 Subject: [PATCH 8/9] Remove deleted files --- .../description/.terraform.lock.hcl | 21 ---------- .../backup_channel/description/c.tf | 8 ---- .../backup_channel/description/config.tf | 12 ------ .../backup_channel/description/nc.tf | 7 ---- .../backup_channel/description/plan.json | 0 .../description/.terraform.lock.hcl | 21 ---------- .../backup_plan/description/c.tf | 8 ---- .../backup_plan/description/config.tf | 11 ------ .../backup_plan/description/nc.tf | 7 ---- .../backup_plan/description/plan.json | 0 .../backup_channel/description/policy.rego | 39 ------------------- .../backup_plan/description/policy.rego | 21 ---------- .../external_service_accounts/policy.rego | 8 ---- 13 files changed, 163 deletions(-) delete mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl delete mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/c.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/config.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_channel/description/plan.json delete mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl delete mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/c.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/config.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/nc.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan/description/plan.json delete mode 100644 policies/gcp/backup_for_gke/backup_channel/description/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan/description/policy.rego delete mode 100644 policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl deleted file mode 100644 index 316309c9a..000000000 --- a/inputs/gcp/backup_for_gke/backup_channel/description/.terraform.lock.hcl +++ /dev/null @@ -1,21 +0,0 @@ -# This file is maintained automatically by "terraform init". -# Manual edits may be lost in future updates. - -provider "registry.terraform.io/hashicorp/google" { - version = "7.17.0" - hashes = [ - "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", - "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", - "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", - "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", - "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", - "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", - "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", - "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", - "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", - "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", - "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", - "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", - ] -} diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/c.tf b/inputs/gcp/backup_for_gke/backup_channel/description/c.tf deleted file mode 100644 index 9ce03a9a4..000000000 --- a/inputs/gcp/backup_for_gke/backup_channel/description/c.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "google_gke_backup_backup_channel" "c" { - name = "c" - location = "australia-southeast1" - project = "PDE" - destination_project = "projects/PDE" - description = "Production backup channel for GKE cluster backup operations" -} - diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/config.tf b/inputs/gcp/backup_for_gke/backup_channel/description/config.tf deleted file mode 100644 index d066e09a3..000000000 --- a/inputs/gcp/backup_for_gke/backup_channel/description/config.tf +++ /dev/null @@ -1,12 +0,0 @@ -##### DO NOT EDIT ###### - -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf b/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf deleted file mode 100644 index 7538ca453..000000000 --- a/inputs/gcp/backup_for_gke/backup_channel/description/nc.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "google_gke_backup_backup_channel" "nc" { - name = "nc" - location = "australia-southeast1" - project = "PDE" - destination_project = "projects/PDE" -} - diff --git a/inputs/gcp/backup_for_gke/backup_channel/description/plan.json b/inputs/gcp/backup_for_gke/backup_channel/description/plan.json deleted file mode 100644 index e69de29bb..000000000 diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl deleted file mode 100644 index 316309c9a..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan/description/.terraform.lock.hcl +++ /dev/null @@ -1,21 +0,0 @@ -# This file is maintained automatically by "terraform init". -# Manual edits may be lost in future updates. - -provider "registry.terraform.io/hashicorp/google" { - version = "7.17.0" - hashes = [ - "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", - "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", - "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", - "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", - "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", - "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", - "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", - "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", - "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", - "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", - "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", - "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", - ] -} diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/c.tf b/inputs/gcp/backup_for_gke/backup_plan/description/c.tf deleted file mode 100644 index 18c7421bc..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan/description/c.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "google_gke_backup_backup_plan" "c" { - name = "c" - cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" - location = "australia-southeast1" - project = "PDE" - description = "Daily backup plan for production GKE cluster with 90-day retention policy. Backs up critical namespaces and persistent volumes." -} - diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/config.tf b/inputs/gcp/backup_for_gke/backup_plan/description/config.tf deleted file mode 100644 index c5d6ff5b2..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan/description/config.tf +++ /dev/null @@ -1,11 +0,0 @@ -##### DO NOT EDIT ###### -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf b/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf deleted file mode 100644 index 16bb977aa..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan/description/nc.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "google_gke_backup_backup_plan" "nc" { - name = "nc" - cluster = "projects/PDE/locations/australia-southeast1/clusters/prod-cluster" - location = "australia-southeast1" - project = "PDE" -} - diff --git a/inputs/gcp/backup_for_gke/backup_plan/description/plan.json b/inputs/gcp/backup_for_gke/backup_plan/description/plan.json deleted file mode 100644 index e69de29bb..000000000 diff --git a/policies/gcp/backup_for_gke/backup_channel/description/policy.rego b/policies/gcp/backup_for_gke/backup_channel/description/policy.rego deleted file mode 100644 index 07b397405..000000000 --- a/policies/gcp/backup_for_gke/backup_channel/description/policy.rego +++ /dev/null @@ -1,39 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_channel.description -import data.terraform.helpers -import data.terraform.gcp.security.backup_for_gke.backup_channel.vars - -conditions := [ - [ - { - "situation_description": "GKE Backup Channel description must be set and meaningful.", - "remedies": ["Set the description to a meaningful string (at least 10 characters)."] - }, - { - "condition": "Description must not be empty or null", - "attribute_path": ["description"], - "values": ["", null], - "policy_type": "blacklist" - }, - { - "condition": "Description must be at least 10 characters", - "attribute_path": ["description"], - "values": ["^.{0,9}$"], - "policy_type": "pattern_blacklist" - } - ], - [ - { - "situation_description": "GKE Backup Channel description must not contain restricted keywords.", - "remedies": ["Remove 'test' or 'temp' from description in production."] - }, - { - "condition": "Description must not contain 'test' or 'temp'", - "attribute_path": ["description"], - "values": ["(?i).*test.*", "(?i).*temp.*"], - "policy_type": "pattern_blacklist" - } - ] -] - -message := helpers.get_multi_summary(conditions, vars.variables).message -details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan/description/policy.rego b/policies/gcp/backup_for_gke/backup_plan/description/policy.rego deleted file mode 100644 index 2c8eb20e8..000000000 --- a/policies/gcp/backup_for_gke/backup_plan/description/policy.rego +++ /dev/null @@ -1,21 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan.description -import data.terraform.helpers -import data.terraform.gcp.security.backup_for_gke.backup_plan.vars - -conditions := [ - [ - { - "situation_description": "Backup Plan description must be set.", - "remedies": ["Set the description."] - }, - { - "condition": "Description must not be empty or null", - "attribute_path": ["description"], - "values": ["", null], - "policy_type": "blacklist" - } - ] -] - -message := helpers.get_multi_summary(conditions, vars.variables).message -details := helpers.get_multi_summary(conditions, vars.variables).details diff --git a/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego b/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego deleted file mode 100644 index fa383fa5f..000000000 --- a/policies/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/policy.rego +++ /dev/null @@ -1,8 +0,0 @@ -package terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.external_service_accounts -import data.terraform.helpers -import data.terraform.gcp.security.backup_for_gke.backup_plan_iam_binding.vars - -conditions := [] - -message := helpers.get_multi_summary(conditions, vars.variables).message -details := helpers.get_multi_summary(conditions, vars.variables).details From 3dec5396527fc497365c06cb26f626e6da8c620c Mon Sep 17 00:00:00 2001 From: Tikster123 Date: Tue, 3 Feb 2026 17:55:14 +1100 Subject: [PATCH 9/9] Removed inputs file for external_service_accounts --- .../.terraform.lock.hcl | 21 ------------------- .../external_service_accounts/c.tf | 12 ----------- .../external_service_accounts/config.tf | 11 ---------- .../external_service_accounts/nc.tf | 12 ----------- 4 files changed, 56 deletions(-) delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/.terraform.lock.hcl delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/c.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/config.tf delete mode 100644 inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/nc.tf diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/.terraform.lock.hcl b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/.terraform.lock.hcl deleted file mode 100644 index 316309c9a..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/.terraform.lock.hcl +++ /dev/null @@ -1,21 +0,0 @@ -# This file is maintained automatically by "terraform init". -# Manual edits may be lost in future updates. - -provider "registry.terraform.io/hashicorp/google" { - version = "7.17.0" - hashes = [ - "h1:VPHRMsm3eQrxzk1b7eHuSG9sG7315ZaGPshFjqzZ5No=", - "zh:103778d776fb994a6b24d70fa095c23a1672361f2a05d882b227b02507b402fc", - "zh:34bcd6cce3081a21983ccfad5cbf2cbf69ff298c65c6570edb4ec7d38a8183f5", - "zh:5f8fd0e8e40068b597b28c0bc08372c9228aad77746068101c72acf4bb902937", - "zh:6b25cee7dec78470feb987438aedb1f4354c696f6548edee7775621e8df24fa9", - "zh:6b5bd97884b51b86fa6a9f1905c0ebf695539e905122052896e8b05122416ff4", - "zh:86e634c5825d8bd32592ae6b74f15e1db5d9b61c85d1a2e529d1696effb76d54", - "zh:c3190609f6f638f4efd7359a5638eeff81d41a38a00861f7df870b5c8f4c11cb", - "zh:d42d854642b4d3b010f232d848197945f90af60e7f9883ac96d7caae9c9d2474", - "zh:da9929be5d3873ad317e488e7ada08d5b95b5461b34d91cef76314317bdc0d49", - "zh:ed2763c21b2f3c1eb7b4b92f6502069a24078345e19c88f91d9e3a46a17147f8", - "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:fbca63b82bbdef6fd329d2c8356b3f39f8c785ad93fd0596cfff676dbaef23ac", - ] -} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/c.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/c.tf deleted file mode 100644 index 2d3e7f353..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/c.tf +++ /dev/null @@ -1,12 +0,0 @@ -resource "google_gke_backup_backup_plan_iam_binding" "c" { - name = "c" - location = "australia-southeast1" - project = "PDE" - - role = "roles/gkebackup.backupViewer" - - members = [ - "serviceAccount:backup-sa@fluent-coder-468700-h4.iam.gserviceaccount.com", # SECURE: Same project SA - "serviceAccount:dr-backup@fluent-coder-468700-h4-dr.iam.gserviceaccount.com" # SECURE: Approved DR project - ] -} diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/config.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/config.tf deleted file mode 100644 index c5d6ff5b2..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/config.tf +++ /dev/null @@ -1,11 +0,0 @@ -##### DO NOT EDIT ###### -terraform { - required_providers { - google = { - source = "hashicorp/google" - } - } -} - -provider "google" {} - diff --git a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/nc.tf b/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/nc.tf deleted file mode 100644 index 0f13a2c37..000000000 --- a/inputs/gcp/backup_for_gke/backup_plan_iam_binding/external_service_accounts/nc.tf +++ /dev/null @@ -1,12 +0,0 @@ -resource "google_gke_backup_backup_plan_iam_binding" "nc" { - name = "nc" - location = "australia-southeast1" - project = "PDE" - - role = "roles/gkebackup.backupAdmin" - - members = [ - "serviceAccount:random-sa@external-project-12345.iam.gserviceaccount.com", # SECURITY RISK: External SA! - "serviceAccount:unknown@suspicious-proj.iam.gserviceaccount.com" # SECURITY RISK: Unknown project! - ] -}