1+ /*
2+ This terraform file is intended to enable the GCP APIs needed for CSPM feature within a GCP organization onboarding.
3+ It will create a google_project_service resource per each service enabled within each GCP project.
4+ The APIs needed for the CSPM feature are listed below:
5+ - Security Token Service API
6+ - Cloud Asset API
7+ - Cloud Identity API
8+ - Admin SDK API
9+ In addition, since CSPM is needed for onboard any GCP project these other APIs are also enabled:
10+ - Identity and access management API
11+ - IAM Service Account Credentials API
12+ - Cloud Resource Manager API
13+
14+ * Note: This do not overwrite any other APIs config that your GCP project has, it will only enabled it if isn't yet.
15+ */
16+
17+ # Set local variables for Organization ID and API services to enable
18+ locals {
19+ organizationID = " 933620940614"
20+ services = [
21+ # CSPM specific APIs
22+ " sts.googleapis.com" ,
23+ " cloudasset.googleapis.com" ,
24+ " cloudidentity.googleapis.com" ,
25+ " admin.googleapis.com" ,
26+
27+ # additional APIs
28+ " iam.googleapis.com" ,
29+ " iamcredentials.googleapis.com" ,
30+ " cloudresourcemanager.googleapis.com"
31+ ]
32+ root_projects = [for project in data . google_projects . organization_projects . projects : project . project_id ]
33+ folder_projects = jsondecode (data. local_file . projects_from_folder . content )
34+ all_projects = concat (local. root_projects , local. folder_projects )
35+ project_and_services = flatten ([
36+ for project in local . all_projects : [
37+ for service in local . services : {
38+ project = project
39+ service = service
40+ }
41+ ]
42+ ])
43+ }
44+
45+ # GCP provider
46+ provider "google" {
47+ region = " us-west-1"
48+ }
49+
50+ # Get list of projects under the specified organization
51+ data "google_projects" "organization_projects" {
52+ filter = " parent.type:organization parent.id:${ local . organizationID } "
53+ }
54+
55+ data "local_file" "projects_from_folder" {
56+ filename = " project_ids.json"
57+ depends_on = [null_resource. get_projects_from_folders ]
58+ }
59+
60+ # Enable API services for GCP project
61+ resource "google_project_service" "enable_cspm_apis" {
62+ // create a unique key per project and service to enable each API
63+ for_each = { for item in local . project_and_services : " ${ item . project } -${ item . service } " => item }
64+
65+ project = each. value . project
66+ service = each. value . service
67+ disable_on_destroy = false
68+ }
69+
70+ # Output the projects and APIs enabled
71+ output "enabled_projects" {
72+ value = distinct ([for resource in google_project_service . enable_cspm_apis : resource . project ])
73+ }
74+
75+ output "enabled_services" {
76+ value = distinct ([for service in google_project_service . enable_cspm_apis : service . service ])
77+ }
78+
79+ # Script to get projects from folders recursively and set to a file
80+ resource "null_resource" "get_projects_from_folders" {
81+ provisioner "local-exec" {
82+ command = << EOF
83+ #!/bin/bash
84+ ORG_ID="933620940614"
85+
86+ # array to store project IDs
87+ declare -a FINAL_PROJECT_IDS
88+
89+ list_projects() {
90+ local folder_id=$1
91+
92+ # get projects from folder
93+ local projects_json=$(gcloud projects list --filter="parent.id=$folder_id AND parent.type=folder" --format=json)
94+
95+ # check valid array
96+ if ! echo "$projects_json" | jq empty >/dev/null 2>&1; then
97+ echo "Invalid JSON returned for projects list."
98+ return
99+ fi
100+
101+ # get project ids
102+ local project_ids=$(echo "$projects_json" | jq -r '.[] | .projectId')
103+
104+ # check project ids not empty and add to global variable
105+ if [ -n "$project_ids" ]; then
106+ for project_id in $project_ids; do
107+ FINAL_PROJECT_IDS+=("$project_id")
108+ done
109+ else
110+ echo "No projects found in folder $folder_id"
111+ fi
112+ }
113+
114+ list_folders_recursive() {
115+ local parent_id=$1
116+ local parent_type=$2
117+
118+ # list folders on org or other folders
119+ if [[ "$parent_type" == "organization" ]]; then
120+ folders=$(gcloud resource-manager folders list --organization=$parent_id --format=json)
121+ elif [[ "$parent_type" == "folder" ]]; then
122+ folders=$(gcloud resource-manager folders list --folder=$parent_id --format=json)
123+ fi
124+
125+ # check if there were folders returned
126+ if [ "$(echo "$folders" | jq length)" -eq 0 ]; then
127+ return
128+ fi
129+
130+ # iterate over folder and call functions recursively
131+ for folder in $(echo "$folders" | jq -c '.[]'); do
132+ folder_id=$(echo "$folder" | jq -r '.name' | awk -F'/' '{print $NF}')
133+
134+ list_projects "$folder_id"
135+ list_folders_recursive "$folder_id" "folder"
136+ done
137+ }
138+
139+ echo "Listing all projects in folders for organization: $ORG_ID"
140+ list_folders_recursive "$ORG_ID" "organization"
141+ printf "%s\n" "$${FINAL_PROJECT_IDS[@]}" | jq -R . | jq -s . > "project_ids.json"
142+ echo "Projects listed and saved to local file."
143+ EOF
144+ }
145+ }
0 commit comments