HomeAbout MeBook a Call

Automating GCP Security and Cost Audits with Gemini

By Vo Tu Duc
Published in Cloud Engineering
May 22, 2026
Automating GCP Security and Cost Audits with Gemini

Relying on manual processes to audit your dynamic cloud infrastructure is a losing battle that wastes valuable engineering time and leaves critical security gaps you can’t afford. This broken approach is costing you more than you think.

image 0

The Challenge of Manual Cloud Infrastructure Auditing

In the era of dynamic, ephemeral, and sprawling cloud estates, the traditional approach to infrastructure auditing is not just inefficient—it’s fundamentally broken. The very nature of cloud platforms like Google Cloud, with their rapid release cycles and developer-driven provisioning, means that a static, point-in-time audit is obsolete the moment it’s completed. Relying on manual processes to ensure security, compliance, and cost-efficiency is like trying to map a constantly shifting landscape with a pen and paper. It’s a battle against scale and velocity that human effort alone cannot win.

The High Cost of Manual Audits: Time, Errors, and Security Gaps

The direct and indirect costs of manual auditing are staggering. The most obvious is the immense expenditure of engineering time. Highly skilled engineers, who should be building value-driving features, are instead diverted for days or even weeks to perform painstaking reviews. They manually click through the GCP console, cross-reference IAM policies with spreadsheets, and parse terabytes of billing data, all in a repetitive cycle of compliance theater.

This process is not only slow but also dangerously prone to human error.

image 1

Perhaps the most significant flaw is the “snapshot” problem. A manual audit provides a compliance report that is valid only for a specific moment. The instant a developer deploys a new service or modifies a configuration, a new, unaudited gap can emerge. This window of vulnerability between periodic audits is where threats thrive. In a world of continuous integration and continuous deployment (CI/CD), we need continuous assurance, not periodic spot-checks.

The SRE Mandate for Scalable, Automated Governance

From a Site Reliability Engineering (SRE) perspective, manual auditing is the definition of toil: repetitive, manual work that scales linearly with the size of the system and provides no enduring value. The core tenets of SRE—embracing risk, eliminating toil through [Automated Job Creation in Real Time Jobber and Google Sheets Integration from Gmail](https://votuduc.com/Automated-Job-Creation-in-Jobber-from-Gmail-p115606), and treating operations as a software problem—are in direct opposition to the practice of manual infrastructure reviews.

The SRE mandate is clear: governance must be automated, scalable, and embedded into the engineering lifecycle. We don’t manually check if a server is online; we have automated monitoring and alerting. Likewise, we shouldn’t manually check if an IAM policy adheres to the principle of least privilege; we should have an automated system that does it for us continuously.

As an organization’s GCP footprint grows from a handful of projects to hundreds or thousands, the complexity of managing security and costs explodes exponentially. A process that was merely tedious for a small team becomes impossible for a large enterprise. Scalable governance isn’t a luxury; it’s a prerequisite for maintaining reliability, security, and financial control in a cloud-native world. The only way to achieve this is to treat governance as code and build intelligent, automated systems to enforce it.

Introducing an AI-Powered Solution with Google Cloud and Gemini

This is where traditional Automated Quote Generation and Delivery System for Jobber hits its limits and a new paradigm becomes necessary. While scripts and configuration management tools can check for known, specific misconfigurations—is port 22 open to the world?—they often lack the context to understand nuance and intent. They struggle to interpret complex, natural-language policies or identify novel patterns of risk.

Enter an AI-powered approach using Google Cloud and the Gemini family of models. By leveraging a powerful, multimodal Large Language Model (LLM) that has a deep, intrinsic understanding of GCP services, we can transcend simple rule-based checking. Gemini can reason about your infrastructure holistically. You can provide it with your high-level security policies written in plain English, and it can translate them into concrete checks against your live environment’s configuration.

Imagine an auditor that can not only identify an overly permissive service account but also explain why it’s a risk in the context of the services it’s attached to, analyze its usage patterns to determine if the permissions are ever used, and even generate the gcloud command or Terraform HCL code to remediate the issue. This isn’t just Automated Work Order Processing for UPS; it’s cognitive augmentation for your security and operations teams. By combining the programmatic access of Google Cloud APIs with the reasoning capabilities of Gemini, we can build a proactive, intelligent, and continuously operating audit system that finally keeps pace with the speed of the cloud.

Architecting the Automated Audit Solution

A powerful idea is only as good as its implementation. To transform the raw data stream of your Google Cloud environment into actionable intelligence, we need a robust, scalable, and intelligent architecture. This isn’t about simply connecting a few APIs; it’s about creating a cohesive data pipeline where each component plays a critical role, culminating in an automated analysis that rivals a team of human experts. Let’s dissect the blueprint of our automated audit engine.

Core Components: GCP, IAM, BigQuery, and Gemini Enterprise

The magic of this solution lies in the synergy between four foundational Google Cloud technologies. Each one is a powerhouse in its own right, but together they form a complete, end-to-end auditing platform.

  • Google Cloud Platform (GCP) & Cloud Logging: This is our ground truth. GCP is the environment we are auditing, and its native logging service, Cloud Logging, is the source of all our data. It meticulously records every significant event through Audit Logs, including Admin Activity (who did what, where, and when), Data Access, and System Events. This comprehensive, always-on data collection is the bedrock of our entire process.

  • **Identity and Access Management (IAM): IAM is the control plane for security in GCP and, therefore, the primary subject of our security audit. We aren’t just looking at logs; we are analyzing the implications of those logs on our IAM posture. Our system will scrutinize IAM policies, role bindings, service account permissions, and group memberships to identify misconfigurations, potential privilege escalation paths, and violations of the principle of least privilege.

  • BigQuery: This is our forensic data warehouse. BigQuery is a serverless, highly scalable, and cost-effective analytics data warehouse that allows us to store, process, and analyze petabytes of data using standard SQL. By creating a log sink from Cloud Logging to BigQuery, we transform ephemeral log streams into a permanent, structured, and queryable historical record. This is where raw data becomes organized information, ready for deep analysis.

  • **Gemini Enterprise (via [Building Self Correcting Agentic Workflows with Building Self-Correcting Agentic Workflows with Vertex AI](https://votuduc.com/building-self-correcting-agentic-workflows-with-vertex-ai-p-20260321542526)): This is the brain of the operation. While BigQuery can tell us what happened, Gemini tells us why it matters. We leverage the advanced reasoning capabilities of Google’s flagship multimodal models through the Vertex AI platform. Gemini acts as our AI security and cost analyst, capable of understanding complex queries, correlating disparate data points, identifying subtle anomalies that signature-based tools would miss, and articulating its findings in clear, human-readable language.

Data Flow: From Cloud Logs to Actionable PDF Reports

The architecture operates as a sophisticated, event-driven data pipeline. Here’s a step-by-step breakdown of how data moves from raw event to a polished, executive-ready report.

  1. Ingestion & Aggregation: It begins with Cloud Logging automatically capturing all relevant logs across your GCP organization. We configure a log sink to export these logs directly into dedicated BigQuery datasets. For a holistic view, we also pipe in other critical data sources, such as detailed billing data exports and periodic snapshots from the Cloud Asset Inventory. This creates a single, unified source of truth for all audit-related information.

  2. Scheduled Analysis Trigger: Using Cloud Scheduler, we trigger a serverless process at regular intervals (e.g., daily or weekly). This trigger invokes a Cloud Function or a Cloud Run service, which serves as our orchestration engine for the analysis phase.

  3. Targeted Querying: The orchestration service executes a series of pre-defined, complex SQL queries against our BigQuery datasets. These queries are designed to extract specific, high-signal information. For example:

  • Security Query: “Find all new IAM bindings granting owner or editor roles in the last 24 hours.”

  • Cost Query: “Identify the top 5 SKUs that have increased in cost by more than 20% week-over-week.”

  • Compliance Query: “List all newly created storage buckets that are publicly accessible.”

  1. AI-Powered Synthesis with Gemini: The raw, tabular results from these BigQuery queries are passed as context in a carefully crafted prompt to the Gemini API via Vertex AI. The prompt instructs Gemini to act as an expert cloud auditor. It asks the model to:
  • Analyze the provided data tables.

  • Identify the most critical security risks and cost anomalies.

  • Explain the business impact of each finding in simple terms.

  • Provide concrete, actionable remediation steps for each issue.

  • Summarize the overall health of the environment.

  1. Report Generation and Distribution: Gemini returns its analysis in a structured format, like Markdown or JSON. Our Cloud Function/Run service parses this output and programmatically generates a professional PDF report. This can be done by populating a Google Docs template or using a library like weasyprint. The final report, complete with summaries, detailed findings, and severity ratings, is then saved to a Cloud Storage bucket and an email notification with a secure link is sent to the relevant stakeholders (e.g., CISO, FinOps team, platform engineering leads).

Why This Stack Delivers Forensic-Level Auditing

Combining these specific services isn’t just a matter of convenience; it creates an auditing capability that surpasses traditional methods and many off-the-shelf tools.

  • Completeness and Immutability: By exporting all logs to BigQuery with a proper retention policy, you create a comprehensive and tamper-resistant audit trail. You are not working with sampled data; you have a complete record of every authenticated action, allowing you to investigate incidents with historical depth and precision.

  • Unmatched Scale and Speed: A manual audit of an enterprise-scale GCP organization is practically impossible. The sheer volume of log data is overwhelming. BigQuery was built for this scale, allowing you to run complex analytical queries across years of data and get results in seconds, not days.

  • From Data Points to Narrative Intelligence: This is the most significant advantage. A classic security tool might alert you that a new firewall rule was created. This architecture does more. Gemini can correlate that event with the identity of the user who created it, the time of day, the source IP range they allowed (0.0.0.0/0), and the sensitivity of the resources protected by that firewall. It then synthesizes this into a narrative: “A firewall rule exposing a production database containing PII to the entire internet was created by a non-privileged user outside of business hours. This is a critical-severity finding that requires immediate remediation.” It provides context, impact, and intent analysis that raw data alone cannot.

  • Consistent, Unbiased, and Automated: The process runs like clockwork, removing the potential for human error, fatigue, or bias. The audits are consistent, repeatable, and fully documented, providing a reliable baseline to measure security posture and cost efficiency over time. This frees up your highly skilled engineers from the drudgery of manual checks to focus on strategic initiatives and proactive threat hunting.

Phase 1 Ingesting and Analyzing Cloud Data

The foundation of any effective automation strategy is a centralized, queryable, and historical data source. In Google Cloud, the canonical service for this purpose is BigQuery. Before we can ask Gemini to find insights, we must first collect the raw data from our cloud environment and structure it for analysis. This initial phase involves configuring data exports for critical services and learning how to query that data to establish a baseline for security and cost posture.

Configuring IAM and Billing Exports to BigQuery

Relying on the live state of your GCP environment is insufficient for auditing. You need a historical record to track changes and analyze trends. Exporting IAM policies and detailed billing data to BigQuery provides this persistent, analyzable dataset.

1. Cloud Billing Export:

Exporting your billing data provides a granular, SKU-level breakdown of every charge incurred. The “Detailed usage cost” export is particularly valuable as it includes resource-level information, such as VM names or Cloud Storage bucket names associated with the cost.

To configure the export:

  1. Ensure you have the necessary permissions (Billing Account Administrator).

  2. Navigate to the Billing section in the Google Cloud Console.

  3. Select your billing account and go to Billing export.

  4. Click Edit Settings for the “Detailed usage cost” export.

  5. Select a project and an existing BigQuery dataset as the destination. If you don’t have a dataset, create one first.

  6. Save the configuration. GCP will begin exporting data within a few hours, creating a table named gcp_billing_export_v1_<BILLING_ACCOUNT_ID>.

2. Cloud Asset Inventory and IAM Policy Export:

Cloud Asset Inventory (CAI) provides a point-in-time snapshot of all your GCP resources and their configurations, including IAM policies. A continuous export ensures you have a complete history of your resource and policy landscape.

To configure the export:

  1. Ensure the Cloud Asset API is enabled.

  2. Navigate to Asset Inventory in the Google Cloud Console.

  3. Select your organization, folder, or project scope.

  4. Go to the Exports tab and click Create.

  5. Define a Feed that specifies the export details:

  • Feed name: A descriptive name (e.g., org-iam-and-resource-export).

  • Destination: Choose the BigQuery project, dataset, and provide a table name prefix. CAI will create tables like <prefix>_iam_policy and <prefix>_resource.

  • Content type: Select both Resource and IAM Policy. This is critical for a comprehensive audit.

  • Feed output configuration: Choose Per-type table to get separate, well-structured tables for different asset types.

  1. Create the feed. The initial export will populate the tables, and subsequent changes in your environment will be streamed to BigQuery.

Crafting BigQuery Queries to Detect Anomalies

With data flowing into BigQuery, you can now transition from data collection to insight generation. Standard SQL becomes your primary tool for slicing, dicing, and analyzing this information to uncover potential security risks and cost inefficiencies.

Below are a few foundational queries that demonstrate how to extract meaningful signals from the raw data.

Example 1: Daily Cost Spike Detection

This query identifies services whose daily cost has increased by more than 100% compared to the previous day, flagging potential budget overruns or misconfigurations.


-- Find services with a significant daily cost increase

WITH DailyCosts AS (

SELECT

DATE(usage_start_time) AS usage_date,

service.description AS service_name,

SUM(cost) AS total_cost

FROM

`your-project.your_billing_dataset.gcp_billing_export_v1_XXXXXX_XXXXXX_XXXXXX`

GROUP BY

1, 2

),

CostComparison AS (

SELECT

usage_date,

service_name,

total_cost,

LAG(total_cost, 1, 0) OVER (PARTITION BY service_name ORDER BY usage_date) AS previous_day_cost

FROM

DailyCosts

)

SELECT

usage_date,

service_name,

previous_day_cost,

total_cost

FROM

CostComparison

WHERE

-- Avoid division by zero and filter for significant spikes (e.g., > 100% increase)

previous_day_cost > 0

AND (total_cost - previous_day_cost) / previous_day_cost > 1.0

ORDER BY

usage_date DESC,

total_cost DESC;

Example 2: Identifying External Users with Privileged Roles

This security query scans your IAM policy data to find any user accounts outside of your organization’s domain that have been granted powerful primitive roles like Owner or Editor.


-- Find external users with Owner, Editor, or Viewer roles

SELECT

asset.ancestors[0] as project_id, -- Assumes first ancestor is the project

iam.role,

iam.member

FROM

`your-project.your_asset_dataset.your_prefix_iam_policy`,

UNNEST(policy.bindings) AS iam

WHERE

-- Filter for primitive roles

iam.role IN ('roles/owner', 'roles/editor', 'roles/viewer')

-- Filter for members that are not service accounts or in your domain

AND NOT ENDS_WITH(iam.member, '@your-company.com')

AND NOT ENDS_WITH(iam.member, '.gserviceaccount.com')

ORDER BY

project_id,

iam.role;

Example 3: Finding Publicly Accessible Cloud Storage Buckets

This query inspects the IAM policies of all Cloud Storage buckets to identify any that grant access to allUsers or allAuthenticatedUsers, which represents a potential data exposure risk.


-- Find all publicly accessible GCS buckets

SELECT

name,

asset_type,

iam.member

FROM

`your-project.your_asset_dataset.your_prefix_resource` AS resource,

UNNEST(iam_policy.bindings) AS binding,

UNNEST(binding.members) AS member

WHERE

asset_type = 'storage.googleapis.com/Bucket'

AND member IN ('allUsers', 'allAuthenticatedUsers')

ORDER BY

name;

Identifying Key Security and Cost Metrics to Monitor

The queries above are just the starting point. A comprehensive audit strategy involves monitoring a broader set of key metrics. These metrics serve as the high-level indicators that you will eventually feed into Gemini for summary and interpretation.

Key Cost Metrics:

  • Daily/Weekly Cost by Project: Track spending trends to ensure projects stay within budget.

  • Top 5 Most Expensive SKUs: Identify the specific services and resource types driving the majority of your costs.

  • Unlabeled Resource Costs: Calculate the cost of resources missing key labels (e.g., owner, cost-center), which indicates poor cost governance.

  • Idle Resource Candidates: Identify resources that incur costs but show low utilization, such as unattached Persistent Disks or idle Cloud SQL instances. (Note: This often requires joining billing data with metrics from Cloud Monitoring).

  • Cost Variance from Forecast: Compare actual spend against a historical average or a defined budget.

Key Security Metrics:

  • Count of External IAM Principals: Monitor the number of users outside your domain with any level of access.

  • Primitive Role Usage: Track the number of roles/owner and roles/editor assignments, aiming to reduce them in favor of least-privilege roles.

  • Publicly Exposed Resources: Continuously scan for public Cloud Storage buckets, Compute Engine instances with firewall rules allowing ingress from 0.0.0.0/0, and public load balancers.

  • Service Account Key Age: Identify service account keys that have not been rotated in over 90 days.

  • Non-compliant Resources: Count resources that violate organizational policies, such as VMs created in unapproved regions or without required security software.

Phase 2: Generating Insights with Gemini Enterprise

With our security and cost data neatly aggregated in BigQuery, we move from data collection to intelligence generation. This is where the power of a multimodal, large-context model like Gemini comes into play. We’ll leverage Gemini via Vertex AI to transform raw, tabular data into a human-readable narrative, identify key risks, and flag cost anomalies—tasks that traditionally require hours of manual analysis by a subject matter expert.

Structuring Effective Prompts for Gemini

The quality of your output is directly proportional to the quality of your input. “Garbage in, garbage out” is as true for LLMs as any other system. To get consistent, accurate, and actionable insights from Gemini, we need to structure our prompts meticulously. A well-formed prompt acts as a blueprint for the model, guiding it to the desired outcome.

We recommend a multi-part prompt structure that includes Persona, Context, Task, and Format (PCTF).

  1. Persona: Instruct the model on the role it should adopt. This grounds its responses in a specific domain of expertise, influencing its tone, focus, and the type of recommendations it provides.

  2. Context: This is the core data payload. You will inject the raw data fetched from your BigQuery tables directly into this part of the prompt. For best results, format the data as a string in a common format like CSV or a JSON array.

  3. Task: Be explicit and unambiguous about what you want the model to do. Use action verbs. Instead of “look at this data,” use “Analyze the following firewall rule data to identify critical security misconfigurations.”

  4. Format: Define the exact structure of the desired output. This is critical for automation. Requesting output in Markdown or JSON allows for easy parsing and integration into downstream systems, like report generators or ticketing systems.

Here is a sample system prompt that combines these elements for analyzing GCP firewall rules:


You are an expert Google Cloud Security Architect and FinOps Analyst. Your primary responsibility is to identify security vulnerabilities and cost optimization opportunities from raw GCP audit data. You must be concise, accurate, and provide actionable recommendations.

**CONTEXT:**

The following data represents a subset of firewall rules from a GCP project. The data is in CSV format:

`project_id,firewall_name,direction,priority,source_ranges,destination_ranges,allowed_protocol_ports,denied_protocol_ports,disabled`

{{FIREWALL_DATA_CSV}}

**TASK:**

1.  Analyze the provided firewall rule data.

2.  Identify and list any rules that are overly permissive. Specifically, look for rules that allow ingress from '0.0.0.0/0' on sensitive ports like 'tcp:22' (SSH), 'tcp:3389' (RDP), or 'tcp:3306' (MySQL).

3.  For each identified vulnerability, describe the risk in plain English.

4.  Provide a clear, actionable recommendation for remediation for each identified risk.

5.  If no critical vulnerabilities are found, state "No critical firewall vulnerabilities were detected in the provided data."

**FORMAT:**

Respond using Markdown. Structure your response as follows:

## Firewall Security Analysis

### High-Risk Vulnerabilities

**Vulnerability 1: [Name of Firewall Rule]**

- **Description:** [Detailed description of the misconfiguration]

- **Risk:** [Explanation of the potential security impact]

- **Recommendation:** [Specific steps to remediate the vulnerability]

*(Repeat for each identified vulnerability)*

### Summary

[Provide a one-sentence summary of the findings.]

This structured prompt ensures that every time we run our audit, Gemini’s output will be predictable and machine-readable, forming a reliable foundation for the next stage of our automation pipeline.

Transforming Raw BigQuery Data into Natural Language Insights

Let’s see this process in action. Imagine our Cloud Function has executed the BigQuery query from Phase 1 and retrieved the following data about a publicly exposed development database:


project_id,firewall_name,direction,priority,source_ranges,destination_ranges,allowed_protocol_ports,denied_protocol_ports,disabled

"dev-project-alpha","allow-mysql-from-anywhere","INGRESS",1000,"['0.0.0.0/0']","[]","[{'IPProtocol':'tcp','ports':['3306']}]","[]","False"

"dev-project-alpha","default-allow-ssh","INGRESS",65534,"['0.0.0.0/0']","[]","[{'IPProtocol':'tcp','ports':['22']}]","[]","False"

Our orchestration function would inject this CSV data into the {{FIREWALL_DATA_CSV}} placeholder of the prompt we designed above and send it to the Vertex AI Gemini API.

Within seconds, Gemini processes the raw data and returns a structured, natural language analysis—transforming cryptic table rows into actionable intelligence:


## Firewall Security Analysis

### High-Risk Vulnerabilities

**Vulnerability 1: allow-mysql-from-anywhere**

- **Description:** This firewall rule allows unrestricted ingress traffic from any IP address on the internet (0.0.0.0/0) to TCP port 3306 (MySQL).

- **Risk:** Exposing a database port directly to the public internet creates a significant risk of brute-force attacks, SQL injection, and potential data exfiltration. This is a critical vulnerability.

- **Recommendation:** Immediately restrict the source range to only trusted IP addresses of application servers or authorized administrative workstations. If external access is required, it should be routed through a secure connection like a VPN or IAP (Identity-Aware Proxy).

**Vulnerability 2: default-allow-ssh**

- **Description:** This firewall rule allows unrestricted ingress traffic from any IP address on the internet (0.0.0.0/0) to TCP port 22 (SSH).

- **Risk:** Publicly exposed SSH ports are constant targets for automated brute-force login attempts. A successful compromise would grant an attacker shell access to the virtual machine instance.

- **Recommendation:** Restrict the source range to known IP addresses. For a more secure, zero-trust approach, disable this rule and use GCP's Identity-Aware Proxy (IAP) for TCP forwarding to manage SSH access without exposing the port publicly.

### Summary

Two critical firewall vulnerabilities were detected, exposing both database and SSH services to the public internet.

This output is immediately useful. It can be sent as a high-priority alert to a Slack channel, used to automatically generate a JIRA ticket, or, as we’ll see next, be compiled into a formal PDF report.

Using DocsApp to Automate Structured PDF Report Creation

Alerts are useful for immediate action, but stakeholders and management often require structured, professional reports for compliance and review meetings. We can automate the creation of these reports by using Google Docs as a templating engine and the [Automatically create new folders in Google Drive, generate templates in new folders, fill out text automatically in new files, and save info in [Automated Web Scraping with [Multilingual Text-to-Speech Tool with SocialSheet Streamline Your Social Media Posting 123](https://votuduc.com/Multilingual-Text-to-Speech-Tool-with-Google-Workspace-p809282)](https://votuduc.com/Automated-Web-Scraping-with-Google-Sheets-p292968)](https://workspace.google.com/marketplace/app/auto_create_folder_and_files/430076014869) APIs.

The workflow is straightforward:

  1. Create a Template: Design a Google Doc that will serve as your report template. Use placeholder text with double curly braces, such as {{SECURITY_ANALYSIS_MARKDOWN}} and {{COST_ANOMALY_SUMMARY}}, where Gemini’s generated content will be inserted.

  2. Orchestrate with Cloud Functions: A Cloud Function will serve as the glue. After receiving the formatted Markdown from Gemini, it will use the Google Docs API to programmatically create a copy of the template and replace the placeholders.

  3. Populate and Export: The function will then use the Google Drive API to export the newly populated Google Doc as a PDF, which can then be saved to a Cloud Storage bucket or emailed to a distribution list.

Here’s a conceptual JSON-to-Video Automated Rendering Engine snippet illustrating how you might use the Google Docs API to perform the find-and-replace operation within a Cloud Function:


# This is a conceptual snippet, not a complete, runnable script.

# It assumes 'service' is an authenticated Google Docs API client

# and 'gemini_output_markdown' contains the Markdown from Gemini.

# ID of your template document and the new copy

template_id = 'YOUR_TEMPLATE_DOC_ID'

new_document_id = 'ID_OF_THE_NEWLY_CREATED_COPY'

requests = [

{

'replaceAllText': {

'containsText': {

'text': '{{SECURITY_ANALYSIS_MARKDOWN}}',

'matchCase': True

},

'replaceText': gemini_output_markdown,

}

},

# Add other replacements here, e.g., for cost analysis

{

'replaceAllText': {

'containsText': {

'text': '{{REPORT_GENERATION_DATE}}',

'matchCase': True

},

'replaceText': str(date.today()),

}

}

]

# Execute the replacement

service.documents().batchUpdate(

documentId=new_document_id,

body={'requests': requests}

).execute()

print(f"Successfully populated document: {new_document_id}")

# Next step would be to call the Google Drive API to export this doc as a PDF.

By chaining these services together—BigQuery for data, Gemini for insight, and AC2F Streamline Your Google Drive Workflow for presentation—we have created a powerful, end-to-end pipeline that transforms raw audit logs into polished, professional security and cost reports with minimal human intervention.

A Practical Walkthrough Detecting Real-World Anomalies

Theory is one thing; applying it to the messy reality of a production cloud environment is another. This is where Gemini transitions from a novel tool to an indispensable ally. We’ll now walk through two of the most common and critical audit tasks—tackling IAM permission creep and hunting down cost inefficiencies—to demonstrate how you can leverage Gemini to get actionable results, fast. We’ll then dissect a sample report to understand how to interpret and act on its findings.

Use Case: Detecting Over-Privileged IAM Roles

The principle of least privilege is the bedrock of cloud security, yet it’s often the first casualty of rapid development cycles. Granting broad permissions like roles/editor is a convenient shortcut that creates a massive, often invisible, security risk. Let’s see how Gemini can systematically find these needles in the haystack.

The Challenge: Manually auditing IAM policies across dozens of projects is a Herculean task. You need to cross-reference service account usage, understand the context of each role, and identify permissions that are granted but never used. Traditional tools can flag primitive roles but often lack the contextual understanding to identify nuanced risks.

The Gemini-Powered Solution:

  1. Data Ingestion: First, we need to provide Gemini with the raw material. We can export the IAM policies for our GCP projects using the gcloud CLI. For a single project, the command is simple:

gcloud projects get-iam-policy your-gcp-project-id --format="json" > project-iam-policy.json

For a comprehensive audit, you would script this to iterate through all projects in a folder or organization and concatenate the results.

  1. Crafting the Prompt: The magic is in the prompt. We need to instruct Gemini to act as a specialized security auditor.

SYSTEM PROMPT:

You are a Google Cloud Platform (GCP) security expert specializing in Identity and Access Management (IAM). Your task is to analyze the provided JSON array of GCP IAM policies.

Your analysis must adhere to the principle of least privilege. Identify and report on the following security risks:

1.  **Primitive Roles on Service Accounts:** Pinpoint any service accounts assigned the primitive roles of `roles/owner` or `roles/editor`. Explain why this is a high-risk practice.

2.  **Overly Broad User Permissions:** Identify any human user accounts (not service accounts) assigned `roles/editor` or `roles/owner` that are not designated as project administrators.

3.  **Risky `iam.serviceAccountUser` Role: **Find instances where the `roles/iam.serviceAccountUser` role is granted at a project level, which allows a principal to impersonate* any* service account in the project. Recommend scoping this down to individual service accounts.

4.  **High-Privilege Custom Roles:** Analyze any custom roles and flag permissions that are particularly sensitive, such as `iam.roles.update`, `resourcemanager.projects.setIamPolicy`, or `*.*`.

For each finding, provide the following in a clear, structured format:

- **Finding Title:** A brief summary of the issue.

- **Severity:** Critical, High, Medium, or Low.

- **Resource:** The full email of the principal (user or service account).

- **Role:** The problematic role binding.

- **Detailed Risk:** A clear explanation of the security implication.

- **Recommended Remediation:** A specific, actionable step to mitigate the risk, such as suggesting a more granular predefined role or the creation of a custom role with specific permissions.

  1. Analyzing the Output: After feeding Gemini the prompt and your IAM policy JSON, it will produce a detailed analysis. Instead of just a data dump, you get a prioritized list of risks with context.

An entry in Gemini’s report might look like this:

  • Finding Title: Service Account with Project Editor Role

  • Severity: High

  • Resource: serviceAccount:[email protected]

  • Role: roles/editor

  • Detailed Risk: The roles/editor primitive role grants over 9,000 permissions, including the ability to create, modify, and delete most GCP resources. If the credentials for this service account are compromised, an attacker could cause widespread damage, exfiltrate data, or deploy malicious resources.

  • Recommended Remediation: Analyze the specific actions the Terraform scripts perform. Create a custom IAM role containing only the necessary permissions (e.g., compute.instances.create, storage.buckets.update, container.clusters.create). Revoke roles/editor and assign the new, narrowly-scoped custom role to the service account.

This approach transforms a multi-day manual audit into a task that can be completed in minutes, providing clear, actionable intelligence to your security team.

Use Case: Uncovering Hidden Cloud Cost Inefficiencies

Cloud waste is often a death by a thousand cuts. Small, forgotten resources accumulate over time, leading to significant and unnecessary expenditures. FinOps teams traditionally rely on dashboards and GCP’s Recommender, but these tools can miss cross-service inefficiencies. Gemini excels at connecting dots across different datasets to find savings others miss.

The Challenge: Identifying an unattached persistent disk is easy. Identifying a GKE cluster that is consistently over-provisioned for its actual workload, while also using a non-optimal storage class for its logs, requires correlating data from Billing, Monitoring, and Asset Inventory.

The Gemini-Powered Solution:

  1. Data Ingestion: This requires a richer dataset. You would typically export:
  • Detailed Billing Data: Export your GCP billing data to BigQuery to get resource-level cost information.

  • Asset Inventory: Use gcloud asset export to get a snapshot of all deployed resources.

  • Monitoring Metrics: Export key performance metrics (e.g., average CPU utilization for VMs, idle replica counts for Cloud SQL) from Cloud Monitoring.

You would then pre-process and join this data into a single CSV or JSON file for Gemini to analyze. Each row might represent a resource and include columns like resource_name, resource_type, project_id, last_30_day_cost, avg_cpu_utilization_percent, network_egress_gb, and is_attached (for disks).

  1. Crafting the Prompt: Here, we ask Gemini to wear a FinOps hat.

SYSTEM PROMPT:

You are a GCP FinOps specialist. Your objective is to analyze the provided dataset, which combines GCP asset inventory, cost data, and performance metrics. Identify concrete opportunities for cost optimization.

Focus on the following patterns:

1.  **Zombie Resources:** Identify resources that are incurring costs but appear to be unused. This includes unattached persistent disks (`resource_type: 'compute.googleapis.com/Disk'`) and unassociated static IP addresses (`resource_type: 'compute.googleapis.com/Address'`).

2.  **Underutilized Compute Instances:** Find Compute Engine VMs with an average CPU utilization below 15% over the last 30 days. Suggest rightsizing to a smaller machine type.

3.  **Idle Cloud SQL Instances:** Pinpoint Cloud SQL instances with a very low number of queries or connections, suggesting they may be candidates for decommissioning or pausing.

4.  **Storage Optimization:** For Cloud Storage buckets with high storage costs but low retrieval rates, suggest transitioning data to a cheaper storage class like Nearline or Coldline.

For each identified opportunity, provide:

- **Opportunity Title:** A brief summary.

- **Estimated Monthly Savings:** A calculated estimate in USD.

- **Resource(s) Affected:** The full name and project of the resource.

- **Evidence:** The specific data points from the input that support your conclusion (e.g., "Average CPU utilization: 8%", "Attached to VM: null").

- **Recommended Action:** A clear, step-by-step guide for remediation, including example gcloud CLI commands where applicable.

  1. Analyzing the Output: Gemini’s response is a prioritized list of cost-saving initiatives.

A potential finding could be:

  • Opportunity Title: Rightsize Underutilized Compute Instance

  • Estimated Monthly Savings: ~$75

  • Resource(s) Affected: projects/web-prod/zones/us-central1-a/instances/legacy-report-generator

  • Evidence: Machine Type: n2-standard-8. Last 30 Day Cost: $140.25. Average CPU Utilization: 6.5%.

  • Recommended Action: The instance is significantly over-provisioned.

  1. Analyze: Confirm the low utilization during peak business hours using Cloud Monitoring.

  2. Resize: Stop the instance and change the machine type to n2-standard-2.

  3. Command: gcloud compute instances stop legacy-report-generator --zone=us-central1-a followed by gcloud compute instances set-machine-type legacy-report-generator --zone=us-central1-a --machine-type=n2-standard-2.

  4. Monitor: Restart the instance and monitor its performance to ensure the smaller size is adequate.

Analyzing a Sample Gemini-Generated Audit Report

A raw list of findings is useful, but a well-structured report is what enables action. By refining our prompts, we can ask Gemini to synthesize its findings from multiple domains (security and cost) into a single, comprehensive audit document.

Here is an example of what a final, polished report might look like, combining findings from both of our use cases.

GCP Environment Audit: Q3 2024

Generated by: Gemini Audit Automation

Date: 2024-10-26

Executive Summary:

This automated audit identified a total of 8 issues across the audited GCP projects (web-prod, data-analytics, dev-sandbox). The findings include 3 Critical/High severity security risks and 5 cost optimization opportunities with an estimated total monthly savings of $215. Immediate attention is required for the over-privileged service accounts to reduce the security blast radius.


Table of Findings

| Severity | Category | Finding Title | Project | Estimated Savings |

| :--- | :--- | :--- | :--- | :--- |

| Critical | Security | Service Account with Project Owner Role | dev-sandbox | N/A |

| High | Security | Project-Level serviceAccountUser Role | web-prod | N/A |

| Medium | Cost | Unattached Persistent Disk “Orphaned Disk” | data-analytics | $20/mo |

| Medium | Cost | Rightsize Underutilized VM | web-prod | $75/mo |

| Medium | Security | User with Project Editor Role | data-analytics | N/A |

| Low | Cost | Unused Static IP Address | dev-sandbox | $3/mo |

| Low | Cost | Idle Cloud SQL Instance | dev-sandbox | $117/mo |

| Low | Cost | Storage Class Optimization | web-prod | TBD |


Detailed Findings Breakdown

1. (Critical) Service Account with Project Owner Role

  • Resource: serviceAccount:[email protected]

  • Details: This service account possesses the roles/owner role, granting it irrevocable, full control over the dev-sandbox project, including the ability to delete the project itself and manage all billing and IAM policies.

  • Impact: Compromise of this account’s keys would lead to a complete compromise of the project.

  • Remediation: Immediately create a custom role with the minimal permissions required for the Jenkins agent to function (e.g., cloudbuild.builds.create, storage.objects.create/get). Assign the custom role and revoke roles/owner.

2. (High) Project-Level serviceAccountUser Role

  • Resource: user:[email protected]

  • Details: This user is granted roles/iam.serviceAccountUser on the web-prod project.

  • **Impact: This permission allows the user to impersonate any service account within the web-prod project, including highly privileged ones like the default Compute Engine service account. This is a significant privilege escalation risk.

  • **Remediation: Revoke the project-level binding. If access is needed, grant the iam.serviceAccountUser role on specific, individual service accounts that the user needs to impersonate.

3. (Medium) Unattached Persistent Disk “Orphaned Disk”

  • Resource: projects/data-analytics/zones/us-east1-b/disks/temp-data-load-disk-01

  • Details: This 500 GB pd-standard disk is not attached to any VM instance and has been unattached for 45 days.

  • Impact: Incurring monthly storage costs of ~$20 for an unused resource.

  • Remediation: Verify the disk is no longer needed. If it contains valuable data, create a snapshot for archival (gcloud compute disks snapshot ...). If it is obsolete, delete the disk to stop incurring charges (gcloud compute disks delete ...).

(…the report would continue with detailed entries for each finding…)

This structured output is immediately useful. Teams can ingest this Markdown into documentation, convert it to PDF for management, or parse it to automatically create tickets in systems like Jira, assigning each finding to the appropriate owner for remediation. This closes the loop from data analysis to direct action.

Advanced Considerations and Scaling the System

Once you have a functional proof-of-concept, the next step is to evolve it into a robust, enterprise-grade system. This involves integrating it into existing workflows, tailoring its output for diverse audiences, and most critically, ensuring the automation itself is secure. Moving from a scheduled script to a production-ready audit platform requires careful consideration of alerting, reporting, and the security posture of the pipeline itself.

Integrating with Alerting Systems for Real-Time Notifications

While a daily or weekly summary report is invaluable for tracking trends, certain high-risk findings demand immediate attention. Integrating your Gemini-powered audit system with real-time alerting platforms transforms it from a passive reporting tool into an active defense mechanism.

The core principle is to programmatically identify findings that cross a predefined severity threshold and push them directly to your team’s preferred communication channels.

Workflow:

  1. Define Severity in Gemini’s Output: Modify your prompt to instruct Gemini to include a severity field (e.g., CRITICAL, HIGH, MEDIUM, LOW) and a concise, one-sentence summary in its structured JSON response for each finding.

  2. Conditional Logic: In your Cloud Function, after receiving the response from Gemini, parse the JSON and iterate through the findings. Implement logic that checks if finding.severity is CRITICAL or HIGH.

  3. Webhook Integration: For each critical finding, format a message and send it to an incoming webhook for your alerting service (e.g., Slack, PagerDuty, Google Chat). Store these webhook URLs securely in Secret Manager, not in your code.

Here is a conceptual Python snippet demonstrating how to post a critical finding to a Slack webhook from within a Cloud Function:


import os

import json

import requests

from google.cloud import secretmanager

def process_and_alert(gemini_findings):

"""

Parses Gemini's findings and sends alerts for critical issues.

`gemini_findings` is a list of dicts parsed from Gemini's JSON output.

"""

slack_webhook_url = get_secret("slack-webhook-url")

for finding in gemini_findings:

if finding.get("severity") in ["CRITICAL", "HIGH"]:

# Format a rich message for Slack

message = {

"text": f"🚨 *Critical GCP Security Alert:* {finding.get('summary')}",

"blocks": [

{

"type": "header",

"text": {

"type": "plain_text",

"text": f"🚨 {finding.get('severity')} Security Finding"

}

},

{

"type": "section",

"fields": [

{"type": "mrkdwn", "text": f"*Resource:*\n`{finding.get('resource_name')}`"},

{"type": "mrkdwn", "text": f"*Issue:*\n{finding.get('summary')}"}

]

},

{

"type": "section",

"text": {

"type": "mrkdwn",

"text": f"*Recommendation:*\n{finding.get('recommendation')}"

}

},

{

"type": "context",

"elements": [

{

"type": "mrkdwn",

"text": f"Detected by Gemini Audit System"

}

]

}

]

}

try:

response = requests.post(slack_webhook_url, data=json.dumps(message), headers={'Content-Type': 'application/json'})

response.raise_for_status()

except requests.exceptions.RequestException as e:

print(f"Error sending Slack notification: {e}")

def get_secret(secret_id, project_id=os.environ.get("GCP_PROJECT"), version_id="latest"):

"""Retrieves a secret from Google Secret Manager."""

client = secretmanager.SecretManagerServiceClient()

name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"

response = client.access_secret_version(request={"name": name})

return response.payload.data.decode("UTF-8")

This approach ensures that your operations and security teams are notified within minutes of a critical misconfiguration, dramatically reducing the mean time to remediation (MTTR).

Customizing Reports for Different Stakeholders

A single, monolithic report rarely serves everyone well. A CISO needs a high-level overview of risk, a DevOps engineer requires actionable remediation steps, and a FinOps analyst wants to see potential cost savings. Gemini’s generative capabilities are exceptionally well-suited for this kind of persona-based report customization.

Instead of a single prompt, you can chain multiple prompts that operate on the same initial audit data.

Example Persona-Based Prompts:

  1. Initial Data Analysis (System to System):
  • Prompt: “Analyze the following GCP asset inventory data. Identify all security misconfigurations and cost optimization opportunities. For each finding, provide the resource name, a detailed description, a severity level (CRITICAL, HIGH, MEDIUM, LOW), and a detailed remediation guide. Output the result as a structured JSON array.”
  1. Executive Summary (for CISO/Leadership):
  • Input: The JSON output from the first prompt.

  • Prompt: “From the provided JSON data of security findings, generate a one-page executive summary. Start with an overall risk assessment score from 1 to 10. Highlight the top 3 most critical risks in plain, non-technical language, focusing on potential business impact. Conclude with a summary of the total number of findings by severity. Do not include code or technical jargon.”

  1. Technical Remediation Plan (for DevOps/SRE):
  • Input: The JSON output from the first prompt.

  • Prompt: “Using the provided JSON data, create a detailed remediation plan in Markdown format. Group findings by resource type. For each finding, provide the exact gcloud commands and, if applicable, a Terraform HCL snippet to correct the misconfiguration. Include a direct link to the relevant official GCP documentation.”

  1. Cost Savings Analysis (for FinOps/Finance):
  • Input: The JSON output from the first prompt, filtered for cost-related findings.

  • Prompt: “Analyze the following cost optimization findings. For each item, estimate the potential monthly cost savings in USD. Present the results in a CSV format with the following columns: Resource Name, Finding, Estimated Monthly Savings, Implementation Effort (Low/Medium/High).”

By orchestrating these calls within your Cloud Function, you can generate multiple tailored artifacts from a single audit run and distribute them accordingly—a PDF for leadership, a Markdown file in a Git repository for engineers, and a CSV attached to an email for the finance team.

Securing the Automation Pipeline End-to-End

An automated audit system is a powerful tool, but its power comes from its privileged access to your cloud environment’s metadata. Securing this pipeline is not optional; it is a critical requirement.

1. Identity and Access Management (IAM):

  • Dedicated Service Account: Your Cloud Function or Cloud Run job must execute using a dedicated, non-default service account.

  • Principle of Least Privilege (PoLP): Grant this service account the absolute minimum set of permissions required. Avoid broad roles like roles/viewer. Instead, grant fine-grained roles like:

  • roles/cloudasset.viewer: To list and analyze resources via Cloud Asset Inventory.

  • roles/aiplatform.user: To invoke the Gemini model on Vertex AI.

  • roles/secretmanager.secretAccessor: To read secrets like webhook URLs.

  • Specific viewer roles for services you are auditing (e.g., roles/compute.networkViewer, roles/storage.objectViewer).

  • IAM Conditions: Where possible, add IAM Conditions to further restrict access. For example, you could restrict the service account to only access secrets with a specific resource tag.

2. Secrets Management:

  • No Hardcoded Secrets: Never embed API keys, webhook URLs, or any other credentials directly in your source code or environment variables.

  • **Use Secret Manager: Store all sensitive data in Google Cloud Secret Manager. The service account for your function should be granted the Secret Accessor IAM role for only the specific secrets it needs to perform its job.

3. Network Security:

  • VPC Service Controls: For maximum security, place your Cloud Function, Vertex AI endpoint, and Secret Manager within a VPC Service Controls perimeter. This creates a virtual boundary that prevents data exfiltration, ensuring that your audit data and secrets can only be accessed by authorized services within your trusted network.

  • Private Google Access: Configure your function’s VPC connector to use Private Google Access. This ensures that traffic from your function to Google APIs (like Vertex AI and Secret Manager) travels over Google’s private network, not the public internet.

4. Code and Dependency Security:

  • Artifact Registry Scanning: Store your function’s container image in Artifact Registry and enable vulnerability scanning. This will automatically detect known vulnerabilities (CVEs) in your OS packages and language libraries.

  • Secure Coding Practices: Treat the code for your automation with the same rigor as your application code. Use code reviews, static analysis security testing (SAST), and secure dependencies.

By implementing these advanced considerations, you can scale your Gemini-powered audit system from a simple script into a secure, reliable, and highly valuable component of your cloud governance strategy.

Conclusion: The Future of AI-Augmented Cloud Governance

We are at a pivotal moment in cloud management. The scale and complexity of modern GCP environments have outpaced our ability to govern them effectively through manual processes and static scripts alone. The introduction of powerful generative AI models like Gemini isn’t just another tool in the toolbox; it represents a fundamental paradigm shift. We are moving from a world of rigid, predefined rules to one of dynamic, context-aware intelligence. This is the dawn of AI-augmented cloud governance, where our operational capabilities can finally match the velocity of our innovation.

Recap: The Shift from Manual to Intelligent Auditing

Throughout this article, we’ve journeyed from the familiar territory of manual audits and brittle automation to the frontier of intelligent analysis. Let’s distill this transition:

  • The Old Way: Characterized by endless checklists, custom Python scripts that are difficult to maintain, and static policy engines. This approach is reactive, labor-intensive, and generates a high volume of low-context alerts. It answers “Is this port open?” but struggles with “Given the context of this application, should this port be open?”

  • **The New Way: Powered by Gemini, this approach is conversational, contextual, and proactive. Instead of just matching patterns, it understands intent. It can analyze a complex web of IAM policies, network configurations, and resource metadata to identify not just misconfigurations, but genuine risks. We moved from simply flagging an overly permissive firewall rule to generating a human-readable report explaining why it’s a risk for a specific production workload and even suggesting a more secure configuration.

This is the leap from data to wisdom, from simple validation to deep understanding, enabling a more resilient and efficient cloud posture.

Key Takeaways for Your SRE and Cloud Architecture Teams

Adopting an AI-augmented approach has distinct, transformative benefits for the teams on the front lines of cloud operations and design.

For Site Reliability Engineering (SRE) Teams:

  • Automate the Toil: Gemini acts as a tireless digital SRE, handling the repetitive, time-consuming audit tasks that bog down your team. This frees up human experts to focus on higher-value engineering work.

  • Enrich Incident Context: When a security or cost anomaly is detected, Gemini can provide immediate, rich context. Instead of just an alert, your on-call engineer gets a summary of the potential impact, related resources, and recommended remediation steps, drastically reducing Mean Time to Resolution (MTTR).

  • Democratize Expertise: Complex gcloud commands or Policy Intelligence insights can be generated through natural language prompts, lowering the barrier to entry for junior team members and accelerating troubleshooting for everyone.

For Cloud Architecture Teams:

  • **Proactive Design Validation: Integrate AI-driven audits directly into your Infrastructure as Code (IaC) pipeline. Gemini can review a Terraform plan or Google Cloud Deploy configuration before it’s applied, flagging potential security vulnerabilities or cost inefficiencies at the design stage.

  • Continuous Feedback Loop: Your architecture is no longer a static blueprint. AI provides a continuous feedback mechanism, highlighting architectural drift and ensuring that deployed resources adhere to best practices and intended designs over time.

  • Enable Secure Innovation: By providing an intelligent safety net, AI-augmented governance gives architects the confidence to design and deploy more complex, dynamic systems, knowing that a sophisticated layer of oversight is constantly at work.

Your Next Step Towards Scalable Cloud Governance

Embracing this future doesn’t require a complete overhaul of your operations overnight. The journey begins with a single, impactful step.

  1. Identify a High-Value Pilot Project: Don’t try to boil the ocean. Start with a well-defined, persistent pain point. Is it managing public GCS bucket permissions? Auditing IAM roles with owner or editor privileges? Or perhaps understanding anomalous spikes in your BigQuery costs?

  2. Experiment and Adapt: Use the prompts and techniques we’ve discussed as a starting point. Set up a secure, read-only service account for Gemini to use and begin asking it questions about your environment. Refine your prompts to get the specific security and cost insights you need.

  3. Integrate and Automate: Once you have a reliable process, your goal should be to embed it into your existing workflows. Trigger a Gemini-powered audit via a Cloud Function on a schedule, integrate it as a check in your CI/CD pipeline, or have it post daily summaries to a Slack channel.

This is more than just automation; it’s about building a partnership with AI to create a smarter, more secure, and cost-effective cloud. By starting small and iterating, you can build a robust governance framework that scales with your infrastructure, turning reactive firefighting into proactive, intelligent cloud management. The future of cloud operations is here, and it’s powered by collaborative intelligence.


Tags

GCPCloud SecurityCost ManagementAutomationGeminiCloud AuditFinOps

Share


Previous Article
Automating Healthcare MLR Approvals with Gemini Enterprise
Vo Tu Duc

Vo Tu Duc

A Google Developer Expert, Google Cloud Innovator

Stop Doing Manual Work. Scale with AI.

Hi, I'm Vo Tu Duc (Danny), a recognised Google Developer Expert (GDE). I architect custom AI agents and Google Workspace solutions that help businesses eliminate chaos and save thousands of hours.

Want to turn these blog concepts into production-ready reality for your team?
Book a Discovery Call

Table Of Contents

1
The Challenge of Manual Cloud Infrastructure Auditing
2
Architecting the Automated Audit Solution
3
Phase 1 Ingesting and Analyzing Cloud Data
4
Phase 2: Generating Insights with Gemini Enterprise
5
A Practical Walkthrough Detecting Real-World Anomalies
6
Advanced Considerations and Scaling the System
7
Conclusion: The Future of AI-Augmented Cloud Governance

Portfolios

AI Agentic Workflows
AppSheet Solutions
Change Management
Product Showcase
Strategy Playbooks
Uncategorized
Workspace Automation
Cloud Engineering

Related Posts

Automate Site Defect Punch Lists with Gemini and Google Chat
May 22, 2026
© 2026, All Rights Reserved.
Powered By

Quick Links

Book a CallAbout MeVolunteer Legacy

Social Media