How to Automate: Manage and delete Google Cloud projects

How to Automate: Manage and delete Google Cloud projects

Sep 7, 2023

Hugo

David

Today, in How to Automate, we will learn how to use Mindflow to automate the process of managing and deleting Google Cloud projects in your organization.

Projects are organizational and administrative units that manage and organize cloud resources and services. They isolate resources by providing logical and physical isolation. Consequently, each project has its resources, ensuring no interference or unauthorized access.

Projects also allow owners to control access to Google resources through IAM policies and fine-grain access control up to the privileges one would have on the set of resources. Each project can be logged and monitored differently, making it easier to track and analyze activities, performances, quotas, and costs associated with the underlying set of resources. Each APIs can be activated per project, and different permissions can be enabled according to the project's needs, reducing the attack surface.

However, without proper monitoring, even when projects' creation is authorized only to admins, projects can multiply and lead to rising overhead, complexity, and security risks. Hence, besides the general organization of the projects (hierarchy, naming conventions, and IAM best practice, for instance), it is recommended that regular reviews and cleanups be performed to decommission projects that are no longer needed.

This can be done through Mindflow, preventing admins from fetching the targeted projects on the Google Cloud console. Automating this process typically divides by more than ten the time needed to perform a process that should be undergone every month.

To do so, we will only have to orchestrate two services: Google Resource Manager and Slack.

Manage and delete Google Cloud projects: the basics

Before getting our hands in the flow building, we must ensure we have the correct permissions. For Google Cloud, we will need either:

  • https://www.googleapis.com/auth/cloud-platform

  • https://www.googleapis.com/auth/cloudplatformprojects

Make sure that the Google Resource Manager API is enabled in the Google Cloud console and that the Mindflow client has the mentioned permissions granted in the Domain Wide Delegation page in the admin console. Then, in the Mindflow Vault, update the credentials in the scope you registered.

For Slack, we have to make sure that we have the chat:write scope granted for our Bot.

We are ready to create the first flow. Proceed and name it as you want!

Manage and delete Google Cloud projects: Listing current projects

We will first configure a scheduler for this flow to be automatically triggered monthly. Do so by clicking the calendar icon on the top left of the canvas. Select "At regular intervals," then "Monthly," and set the day, hour, and minutes you want to trigger the flow. Click "Save." Scheduler is set.

First, we want to set a global variable we need later in the flow. Do so by creating a Transform Data (TD) step named setting variables. Open the configuration panel and click "Add an item." Name this item projects and leave it empty.

Following this, create a new step and, in the Finder, search for Lists projects that are direct children of the specified folder or organization resource / cloudresourcemanager.projects.list. Open the configuration tab and ensure the credentials are selected in the SETTINGS tab. Inside the INPUT tab, we must populate the parameter "Parent" with organizations/YOUR_ORG_ID. You can find the 12-digit long ID in your project lists on the Google Cloud console. Copy and paste it in the field. You can dry-run the step by clicking the "Play" button at the bottom right of the step to generate logs.

Create a For-each loop that you will name For each project. Open the For-each configuration tab and, in "Source," type "/" to open the Data Picker tool. In the newly opened pop-over, select the Google step and its execution log. In the log, select the object projects.

Inside For each project, create a step by searching for Gets IAM policy projects cloudresourcemanager.projects.getIamPolicy. We need to retrieve the owner(s) of the project. To do so, we have to retrieve the IAM policy attached to this project to know who the owner is in case we need to ask questions about it. Open the configuration tab, and, under "Resource", type "/" and click For each projects under FLOW. In the logs, pick the key name.

Before the step' configuration is done, we need to apply a function to the value we just picked. Click the fx button at the right end of the field. Then, click "Add a function" and search for "Slice" in the Finder. Under "Start," type "9." Leave "End" empty. Now, dry run the step to generate logs.

After this step, create a TD named prepare output. In it, add an item named projects. We are calling our global variable to write on it at each iteration. Type "/" and fetch the projects variable. Then, you can add different sets of information, such as projectIdname, project Owner, or project creationTime. Type "/" each time and go inside either the For each project's logs or the cloudresourcemanager.projects.getIamPolicy to pick the keys associated with the values you are looking for. Your message should resemble something like this:

Now, we have to send all the information to Slack on the targeted channel. Do so by opening the Finder and searching for Sends a message to a channel / chat_postMessage. Under "Channel," pick the channel_Id from which you want to send the message. Under "Text," write the message you want to send, followed by the variable projects you will invoke through the Data Picker. Ensure the right Slack credentials are set, and you are ready!

We also want to notify the team that they can choose to delete one of the projects from Slack. Create another Sends a message to a channel / chat_postMessage. Click the "Advanced" icon at the top right of the pop-over to display all the available parameters. We need "Thread ts" to post a new message in reply to the initial message. You will find the key ts by opening the Data Picker and looking in the first Slack step logs inside body. Repeat this process to pick the key channel to populate the field "Channel."

Under the parameter "Text," write down the following: "If you wish to delete a project, please type '/deleteproject + projectId.'" Once configured, run the flow to check that everything ticks green. The first flow is complete! On to the second flow.

Manage and delete Google Cloud projects: Deleting a project.

Create a new flow and name it as you want. Open it and click the gear icon next to the flow's name. Copy the second webhook URL starting from the bottom. Go to https://api.slack.com/apps/YOUR_WORKSPACE_ID/slash-commands? and create a new command in the "Request URL" field, paste the webhook URL, and fill the other fields as such. Click "Save" once done. On Slack, query this command to trigger the flow and generate logs.

As the first step, you can create a condition to triage who can trigger this flow if needed. So, create the condition and a branch named yes leading to the action Retrieves the Project identified by the specified project_id / cloudresourcemanager.projects.get. Fill in the first field with authorized user IDs, select "Contains," and, in the third field, type "/" and find the key user_id in query

Open the cloudresourcemanager.projects.get configuration panel, and in "Resource," type "/" and pick the key text in query in the Slackbot webhook. Run the step. Create a second step leading to Gets iam policy projects / cloudresourcemanager.projects.getIamPolicy. We repeat these two steps because we want information displayed in the notification preceding the deletion. Dry-run the second step.

Following this, create a chat_postMessage Slack step. We want to confirm the project's deletion on Slack before proceeding. Populate "Channel," then click "Advanced" and find the field "Blocks." Paste the following JSON:

[
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "⚠️ You are about to delete the following project. Please confirm"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "Project number:n["/" and pick projectNumber in the first Google step]"
},
{
"type": "mrkdwn",
"text": "Project ID:n["/" and pick projectId in the first Google step]"
},
{
"type": "mrkdwn",
"text": "Owner:n["/" and pick members[0] in the second Google step]"
}
]
},
{
"type": "actions",
"block_id": "["/" and pick Resume execution ID in Resume]",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Yes"
},
"style": "primary",
"value": "click_me_123"
},
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "No"
},
"style": "danger",
"value": "click_me_123"
}
]
}
]


Once done, create a condition named proceed? and a branch called yes, leading to a TD named Prepare impersonation. Run the whole flow from Slack. This will prompt you back. Click "No." Go back to Mindflow and open proceed? configuration tab. In the first field, open the Data Picker and select the Slack step, then the last execution with "(resume)." Inside, navigate to query/payload/actions/actions[0] and pick style. Then, select the operator "is equal to" and write "primary" in the third field.

Open the Prepare impersonation TD. Inside, create 5 items that you will name: iatsubexpimpersonated_claim_set, and escape. Configure them as such:

  • iat (issued at): Create a Get time function to generate the current Unix time in seconds.

  • sub (the impersonated user): Pick the key members[0] in the second Google step and apply a Slice function starting from "5."

  • exp: invoke iat and apply a Sum function where you will add 3600 seconds to the previous value, which is the current Unix time. This will set the lifetime duration of the JSON Web Token that we will generate later.

  • impersonated_claim_set: Paste and complete the following JSON:

{
"iss": "[YOUR GOOGLE SERVICE ACCOUNT ADDRESS]",
"scope": "https://www.googleapis.com/auth/cloud-platform",
"aud": "https://oauth2.googleapis.com/token",
"iat": [call iat],
"exp": [call exp],
"sub": "[call sub]"
}
  • escape: call impersonated_claim_set and apply an Escape string function configured as such: Escape level * Special chars, Escape quote * Double, JSON Compatible enabled.

Manage and delete Google Cloud projects - 7

You are ready to proceed forward! From there, we will have to create HTTP Requests by hand. Create the first request named Generate impersonated JWT token. Set Method * to POST. In URL * paste https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/[YOUR SERVICE ACCOUNT ADDRESS]:signJwt. Open the Body section and mark it as JSON. Inside write

{ "payload": [Invoke Escape] }

In the SETTINGS panel, make sure you have selected your JWT credential. Run it once to generate a JWT. 

Once done, create another HTTP Request named Generate impersonated access token. Select POST and paste https://oauth2.googleapis.com/token in URL *. In Body as URL-encoded, create grant_type and paste urn:ietf:params:oauth:grant-type:jwt-bearer. Below, create assertion and Pick signedJwt from the first HTTP Request logs. Run it once to generate logs. At this point, the impersonation process is done. We will now configure steps to find and revert the files' visibility to private.

Create one last HTTP Request that you will name Mark a project for deletion. Set Method to DELETE. In the URL, paste https://cloudresourcemanager.googleapis.com/v3/projects/["/" pick projectId]. In Headers, add an item named Authorization , type "Bearer," press space, and pick access_token from Generate impersonated access token's logs.

Manage and delete Google Cloud projects - 8

Finally, we have to create two Slack chat_postMessage steps. One that we will use in the proceed? as the else branch. Create the second branch, click the three dots at the left of the field, and click "use as else." To configure the step, Configure Channel and Thread ts by opening the Data Picker and inspecting the first Slack step logs to pick channel_id and ts. As a text, you can write "Task aborted. Project not submitted for deletion."

Repeat the same process by creating a chat_postMessage step after the HTTP Request but, as a text, write "Project submitted for deletion."

Flow complete!


Automate processes with AI,
amplify Human strategic impact.

Get a demo

Automate processes with AI,
amplify Human strategic impact.

Get a demo