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