diff --git a/.gitignore b/.gitignore index 96cc1d5..e173d9d 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,8 @@ override.tf.json .envrc **/.envrc +/test/examples/**/**/*.json + *.patch # MacOS diff --git a/test/examples/organization_api_enablement/cdr_ciem/main.tf b/test/examples/organization_api_enablement/cdr_ciem/main.tf new file mode 100644 index 0000000..58e2528 --- /dev/null +++ b/test/examples/organization_api_enablement/cdr_ciem/main.tf @@ -0,0 +1,129 @@ +/* +This terraform file is intended to enable the GCP APIs needed for CDR/CIEM feature within a GCP organization onboarding. +It will create a google_project_service resource per each service enabled within each GCP project. +The APIs needed for the CDR/CIEM feature are listed below: + - Cloud Pub/Sub API + +* Note: This do not overwrite any other APIs config that your GCP project has, it will only enabled it if isn't yet. +*/ + +# Set local variables for Organization ID and API services to enable +locals { + organizationID = "933620940614" + services = [ + "pubsub.googleapis.com" + ] + root_projects = [for project in data.google_projects.organization_projects.projects : project.project_id] + folder_projects = jsondecode(data.local_file.projects_from_folder.content) + all_projects = concat(local.root_projects, local.folder_projects) + project_and_services = flatten([ + for project in local.all_projects : [ + for service in local.services : { + project = project + service = service + } + ] + ]) +} + +# GCP provider +provider "google" { + region = "us-west-1" +} + +# Get list of projects under the specified organization +data "google_projects" "organization_projects" { + filter = "parent.type:organization parent.id:${local.organizationID}" +} + +data "local_file" "projects_from_folder" { + filename = "project_ids.json" + depends_on = [null_resource.get_projects_from_folders] +} + +# Enable API services for GCP project +resource "google_project_service" "enable_cdr_ciem_apis" { + // create a unique key per project and service to enable each API + for_each = { for item in local.project_and_services : "${item.project}-${item.service}" => item } + + project = each.value.project + service = each.value.service + disable_on_destroy = false +} + +# Output the projects and APIs enabled +output "enabled_projects" { + value = distinct([for resource in google_project_service.enable_cdr_ciem_apis : resource.project]) +} + +output "enabled_services" { + value = distinct([for service in google_project_service.enable_cdr_ciem_apis : service.service]) +} + +# Script to get projects from folders recursively and set to a file +resource "null_resource" "get_projects_from_folders" { + provisioner "local-exec" { + command = </dev/null 2>&1; then + echo "Invalid JSON returned for projects list." + return + fi + + # get project ids + local project_ids=$(echo "$projects_json" | jq -r '.[] | .projectId') + + # check project ids not empty and add to global variable + if [ -n "$project_ids" ]; then + for project_id in $project_ids; do + FINAL_PROJECT_IDS+=("$project_id") + done + else + echo "No projects found in folder $folder_id" + fi + } + + list_folders_recursive() { + local parent_id=$1 + local parent_type=$2 + + # list folders on org or other folders + if [[ "$parent_type" == "organization" ]]; then + folders=$(gcloud resource-manager folders list --organization=$parent_id --format=json) + elif [[ "$parent_type" == "folder" ]]; then + folders=$(gcloud resource-manager folders list --folder=$parent_id --format=json) + fi + + # check if there were folders returned + if [ "$(echo "$folders" | jq length)" -eq 0 ]; then + return + fi + + # iterate over folder and call functions recursively + for folder in $(echo "$folders" | jq -c '.[]'); do + folder_id=$(echo "$folder" | jq -r '.name' | awk -F'/' '{print $NF}') + + list_projects "$folder_id" + list_folders_recursive "$folder_id" "folder" + done + } + + echo "Listing all projects in folders for organization: $ORG_ID" + list_folders_recursive "$ORG_ID" "organization" + printf "%s\n" "$${FINAL_PROJECT_IDS[@]}" | jq -R . | jq -s . > "project_ids.json" + echo "Projects listed and saved to local file." + EOF + } +} \ No newline at end of file diff --git a/test/examples/organization_api_enablement/cspm/main.tf b/test/examples/organization_api_enablement/cspm/main.tf new file mode 100644 index 0000000..3b4349c --- /dev/null +++ b/test/examples/organization_api_enablement/cspm/main.tf @@ -0,0 +1,145 @@ +/* +This terraform file is intended to enable the GCP APIs needed for CSPM feature within a GCP organization onboarding. +It will create a google_project_service resource per each service enabled within each GCP project. +The APIs needed for the CSPM feature are listed below: + - Security Token Service API + - Cloud Asset API + - Cloud Identity API + - Admin SDK API +In addition, since CSPM is needed for onboard any GCP project these other APIs are also enabled: + - Identity and access management API + - IAM Service Account Credentials API + - Cloud Resource Manager API + +* Note: This do not overwrite any other APIs config that your GCP project has, it will only enabled it if isn't yet. +*/ + +# Set local variables for Organization ID and API services to enable +locals { + organizationID = "933620940614" + services = [ + # CSPM specific APIs + "sts.googleapis.com", + "cloudasset.googleapis.com", + "cloudidentity.googleapis.com", + "admin.googleapis.com", + + # additional APIs + "iam.googleapis.com", + "iamcredentials.googleapis.com", + "cloudresourcemanager.googleapis.com" + ] + root_projects = [for project in data.google_projects.organization_projects.projects : project.project_id] + folder_projects = jsondecode(data.local_file.projects_from_folder.content) + all_projects = concat(local.root_projects, local.folder_projects) + project_and_services = flatten([ + for project in local.all_projects : [ + for service in local.services : { + project = project + service = service + } + ] + ]) +} + +# GCP provider +provider "google" { + region = "us-west-1" +} + +# Get list of projects under the specified organization +data "google_projects" "organization_projects" { + filter = "parent.type:organization parent.id:${local.organizationID}" +} + +data "local_file" "projects_from_folder" { + filename = "project_ids.json" + depends_on = [null_resource.get_projects_from_folders] +} + +# Enable API services for GCP project +resource "google_project_service" "enable_cspm_apis" { + // create a unique key per project and service to enable each API + for_each = { for item in local.project_and_services : "${item.project}-${item.service}" => item } + + project = each.value.project + service = each.value.service + disable_on_destroy = false +} + +# Output the projects and APIs enabled +output "enabled_projects" { + value = distinct([for resource in google_project_service.enable_cspm_apis : resource.project]) +} + +output "enabled_services" { + value = distinct([for service in google_project_service.enable_cspm_apis : service.service]) +} + +# Script to get projects from folders recursively and set to a file +resource "null_resource" "get_projects_from_folders" { + provisioner "local-exec" { + command = </dev/null 2>&1; then + echo "Invalid JSON returned for projects list." + return + fi + + # get project ids + local project_ids=$(echo "$projects_json" | jq -r '.[] | .projectId') + + # check project ids not empty and add to global variable + if [ -n "$project_ids" ]; then + for project_id in $project_ids; do + FINAL_PROJECT_IDS+=("$project_id") + done + else + echo "No projects found in folder $folder_id" + fi + } + + list_folders_recursive() { + local parent_id=$1 + local parent_type=$2 + + # list folders on org or other folders + if [[ "$parent_type" == "organization" ]]; then + folders=$(gcloud resource-manager folders list --organization=$parent_id --format=json) + elif [[ "$parent_type" == "folder" ]]; then + folders=$(gcloud resource-manager folders list --folder=$parent_id --format=json) + fi + + # check if there were folders returned + if [ "$(echo "$folders" | jq length)" -eq 0 ]; then + return + fi + + # iterate over folder and call functions recursively + for folder in $(echo "$folders" | jq -c '.[]'); do + folder_id=$(echo "$folder" | jq -r '.name' | awk -F'/' '{print $NF}') + + list_projects "$folder_id" + list_folders_recursive "$folder_id" "folder" + done + } + + echo "Listing all projects in folders for organization: $ORG_ID" + list_folders_recursive "$ORG_ID" "organization" + printf "%s\n" "$${FINAL_PROJECT_IDS[@]}" | jq -R . | jq -s . > "project_ids.json" + echo "Projects listed and saved to local file." + EOF + } +} \ No newline at end of file diff --git a/test/examples/organization_api_enablement/vm/main.tf b/test/examples/organization_api_enablement/vm/main.tf new file mode 100644 index 0000000..ae54c1c --- /dev/null +++ b/test/examples/organization_api_enablement/vm/main.tf @@ -0,0 +1,130 @@ +/* +This terraform file is intended to enable the GCP APIs needed for VM feature within a GCP organization onboarding. +It will create a google_project_service resource per each service enabled within each GCP project. +The APIs needed for the VM feature are listed below: + - Compute Engine API + +* Note: This do not overwrite any other APIs config that your GCP project has, it will only enabled it if isn't yet. +*/ + +# Set local variables for Organization ID and API services to enable +locals { + organizationID = "933620940614" + services = [ + "compute.googleapis.com" + ] + root_projects = [for project in data.google_projects.organization_projects.projects : project.project_id] + folder_projects = jsondecode(data.local_file.projects_from_folder.content) + all_projects = concat(local.root_projects, local.folder_projects) + project_and_services = flatten([ + for project in local.all_projects : [ + for service in local.services : { + project = project + service = service + } + ] + ]) +} + +# GCP provider +provider "google" { + region = "us-west-1" +} + +# Get list of projects under the specified organization +data "google_projects" "organization_projects" { + filter = "parent.type:organization parent.id:${local.organizationID}" +} + +data "local_file" "projects_from_folder" { + filename = "project_ids.json" + depends_on = [null_resource.get_projects_from_folders] +} + +# Enable API services for GCP project +resource "google_project_service" "enable_vm_apis" { + // create a unique key per project and service to enable each API + for_each = { for item in local.project_and_services : "${item.project}-${item.service}" => item } + + project = each.value.project + service = each.value.service + disable_on_destroy = false +} + +# Output the projects and APIs enabled +output "enabled_projects" { + value = distinct([for resource in google_project_service.enable_vm_apis : resource.project]) +} + +output "enabled_services" { + value = distinct([for service in google_project_service.enable_vm_apis : service.service]) +} + + +# Script to get projects from folders recursively and set to a file +resource "null_resource" "get_projects_from_folders" { + provisioner "local-exec" { + command = </dev/null 2>&1; then + echo "Invalid JSON returned for projects list." + return + fi + + # get project ids + local project_ids=$(echo "$projects_json" | jq -r '.[] | .projectId') + + # check project ids not empty and add to global variable + if [ -n "$project_ids" ]; then + for project_id in $project_ids; do + FINAL_PROJECT_IDS+=("$project_id") + done + else + echo "No projects found in folder $folder_id" + fi + } + + list_folders_recursive() { + local parent_id=$1 + local parent_type=$2 + + # list folders on org or other folders + if [[ "$parent_type" == "organization" ]]; then + folders=$(gcloud resource-manager folders list --organization=$parent_id --format=json) + elif [[ "$parent_type" == "folder" ]]; then + folders=$(gcloud resource-manager folders list --folder=$parent_id --format=json) + fi + + # check if there were folders returned + if [ "$(echo "$folders" | jq length)" -eq 0 ]; then + return + fi + + # iterate over folder and call functions recursively + for folder in $(echo "$folders" | jq -c '.[]'); do + folder_id=$(echo "$folder" | jq -r '.name' | awk -F'/' '{print $NF}') + + list_projects "$folder_id" + list_folders_recursive "$folder_id" "folder" + done + } + + echo "Listing all projects in folders for organization: $ORG_ID" + list_folders_recursive "$ORG_ID" "organization" + printf "%s\n" "$${FINAL_PROJECT_IDS[@]}" | jq -R . | jq -s . > "project_ids.json" + echo "Projects listed and saved to local file." + EOF + } +} \ No newline at end of file diff --git a/test/examples/single_api_enablement/cdr_ciem/main.tf b/test/examples/single_api_enablement/cdr_ciem/main.tf new file mode 100644 index 0000000..a9421a3 --- /dev/null +++ b/test/examples/single_api_enablement/cdr_ciem/main.tf @@ -0,0 +1,39 @@ +/* +This terraform file is intended to enable the GCP APIs needed for CDR/CIEM feature within a single project onboarding. +It will create a google_project_service resource per each service enabled within the GCP project. +The APIs needed for the CDR/CIEM feature are listed below: + - Cloud Pub/Sub API + +* Note: This do not overwrite any other APIs config that your GCP project has, it will only enabled it if isn't yet. +*/ + +# Set local local variables for Project ID and API services to enable +locals { + project = "org-child-project-1" + services = [ + "pubsub.googleapis.com" + ] +} + +# GCP provider +provider "google" { + project = local.project + region = "us-west-1" +} + +// Enable API services for GCP project +resource "google_project_service" "enable_cdr_ciem_apis" { + project = local.project + + for_each = toset(local.services) + service = each.value + disable_on_destroy = false +} + +# Output the projects and APIs enabled +output "enabled_projects" { + value = distinct([for service in local.services : google_project_service.enable_cdr_ciem_apis[service].project]) +} +output "enabled_services" { + value = [for service in local.services : google_project_service.enable_cdr_ciem_apis[service].service] +} \ No newline at end of file diff --git a/test/examples/single_api_enablement/cspm/main.tf b/test/examples/single_api_enablement/cspm/main.tf new file mode 100644 index 0000000..b09d420 --- /dev/null +++ b/test/examples/single_api_enablement/cspm/main.tf @@ -0,0 +1,55 @@ +/* +This terraform file is intended to enable the GCP APIs needed for CSPM feature within a single project onboarding. +It will create a google_project_service resource per each service enabled within the GCP project. +The APIs needed for the CSPM feature are listed below: + - Security Token Service API + - Cloud Asset API + - Cloud Identity API + - Admin SDK API +In addition, since CSPM is needed for onboard any GCP project these other APIs are also enabled: + - Identity and access management API + - IAM Service Account Credentials API + - Cloud Resource Manager API + +* Note: This do not overwrite any other APIs config that your GCP project has, it will only enabled it if isn't yet. +*/ + +# Set local variables for Project ID and API services to enable +locals { + project = "org-child-project-1" + services = [ + # CSPM specific APIs + "sts.googleapis.com", + "cloudasset.googleapis.com", + "cloudidentity.googleapis.com", + "admin.googleapis.com", + + # additional APIs + "iam.googleapis.com", + "iamcredentials.googleapis.com", + "cloudresourcemanager.googleapis.com" + ] +} + +# GCP provider +provider "google" { + project = local.project + region = "us-west-1" +} + +// Enable API services for GCP project +resource "google_project_service" "enable_cspm_apis" { + project = local.project + + for_each = toset(local.services) + service = each.value + disable_on_destroy = false +} + +# Output the projects and APIs enabled +output "enabled_projects" { + value = distinct([for service in local.services : google_project_service.enable_cspm_apis[service].project]) +} +output "enabled_services" { + value = [for service in local.services : google_project_service.enable_cspm_apis[service].service] +} \ No newline at end of file diff --git a/test/examples/single_api_enablement/vm/main.tf b/test/examples/single_api_enablement/vm/main.tf new file mode 100644 index 0000000..961c9c6 --- /dev/null +++ b/test/examples/single_api_enablement/vm/main.tf @@ -0,0 +1,39 @@ +/* +This terraform file is intended to enable the GCP APIs needed for VM feature within a single project onboarding. +It will create a google_project_service resource per each service enabled within the GCP project. +The APIs needed for the VM feature are listed below: + - Compute Engine API + +* Note: This do not overwrite any other APIs config that your GCP project has, it will only enabled it if isn't yet. +*/ + +# Set local variables for Project ID and API services to enable +locals { + project = "org-child-project-1" + services = [ + "compute.googleapis.com" + ] +} + +# GCP provider +provider "google" { + project = local.project + region = "us-west-1" +} + +// Enable API services for GCP project +resource "google_project_service" "enable_vm_apis" { + project = local.project + + for_each = toset(local.services) + service = each.value + disable_on_destroy = false +} + +# Output the projects and APIs enabled +output "enabled_projects" { + value = distinct([for service in local.services : google_project_service.enable_vm_apis[service].project]) +} +output "enabled_services" { + value = [for service in local.services : google_project_service.enable_vm_apis[service].service] +} \ No newline at end of file