DEV Community

Romin Irani
Romin Irani

Posted on • Originally published at Medium on

Google Cloud Skills Tutorial — Part 2 : Intermediate Skills in Action

Welcome to the definitive guide on Google Cloud Agent Skills.

The Series:

-
Part 1 : What are Google Cloud Skills

- Part 2 : Intermediate Skills in Action (BigQuery and Cloud Run) (this blog)

_- Part 3 : Advanced Ops (WAF Security, Architecture, Custom Skills)

  • Part 4 : More Use Cases_

Before your agent or code can interact with any Google Cloud service, it needs permission to do so. Authentication is the very first step in the Google Cloud Agent Skills workflow because without it, every subsequent operation will fail with a 401 Unauthorized or 403 Forbidden error.

Setting up authentication correctly ensures a smooth, secure experience whether you are building locally, deploying to the cloud, or using agents.

Prerequisites: Manual Setup

While our agent will do most of the heavy lifting, authentication requires an initial manual login to establish your identity on your machine.

Run the following commands in your terminal:

# Set your active project
gcloud config set project YOUR_PROJECT_ID

# Login to the gcloud CLI
gcloud auth login

# Set up Application Default Credentials (ADC)
gcloud auth application-default login
Enter fullscreen mode Exit fullscreen mode

Once this is done, you are ready to use the agent for everything else!

Confirming Skill Installation

For this step, we will use the google-cloud-recipe-auth skill. Confirm it's installed:

npx skills list
Enter fullscreen mode Exit fullscreen mode

Prompt-Driven Authentication Checks

Instead of manually running diagnostic scripts or consulting complex decision trees, you can just ask your agent. The agent uses the google-cloud-recipe-auth skill to evaluate your environment and provide tailored guidance.

The responses given below are from running them in Antigravity CLI.

1. Verifying Authentication

You prompt: Check if my Google Cloud authentication is set up correctly for project YOUR_PROJECT_ID

Agent response:

Yes, your Google Cloud authentication is set up correctly for project PROJECT_ID.                                                       

  ### Verification Details:                                                                                                                           

  1. Active Account (gcloud CLI)                                                                                                                      
      • Account: YOUR_ACCOUNT                                                                                                                    
      • Status: Authenticated & Active                                                                                                                
  2. Project Configuration                                                                                                                            
      • Active Project: PROJECT_ID                                                                                                        
      • Quota Project: PROJECT_ID                                                                                                         
      • Compute Region: us-central1                                                                                                                   
  3. Project Access & Status                                                                                                                          
      • Project Name: PROJECT_ID                                                                                                                 
      • Project Number: PROJECT_NUMBER                                                                                                                  
      • Lifecycle State: ACTIVE                                                                                                                       
      • Permissions: Verified (able to retrieve project metadata via Resource Manager API).                                                           
  4. Application Default Credentials (ADC)                                                                                                            
      • Status: Active & Valid (client SDKs and application libraries can successfully authenticate to Google Cloud APIs).
Enter fullscreen mode Exit fullscreen mode

2. Architectural Auth Decisions

You prompt: What authentication method should I use for a Cloud Run service that needs to access BigQuery?

Agent response: (Which skill did it use? Answer comes a bit later)

For a Cloud Run service accessing BigQuery, the recommended Google Cloud best practice is Service-to-Service Authentication via attached Service    
  Accounts.                                                                                                                                           
  ──────                                                                                                                                              
  ### Recommended Setup                                                                                                                               

  #### 1. Authentication (Identity)                                                                                                                   

  Attach a Custom User-Managed Service Account to your Cloud Run service instead of using default accounts or static JSON key files.                  

  • Create a custom service account (e.g., cloud-run-bq-sa@<project-id>.iam.gserviceaccount.com).                                                     
  • Attach it to Cloud Run during deployment:                                                                                                         
    gcloud run deploy SERVICE_NAME \                                                                                                                  
      --image IMAGE_URL \                                                                                                                             
      --service-account cloud-run-bq-sa@PROJECT_ID.iam.gserviceaccount.com                                                                            


  │ ⚠️ Avoid using static Service Account Keys (JSON files). Cloud Run provides a secure local metadata server that handles token issuance dynamically.
  ──────                                                                                                                                              
  #### 2. Authorization (IAM Roles)                                                                                                                   

  Grant your service account the least-privilege IAM roles required for BigQuery:                                                                     

  • roles/bigquery.jobUser: Required to run query jobs in the project.                                                                                
  • roles/bigquery.dataViewer (or roles/bigquery.dataEditor): Required to read (or write) data in the specific dataset or tables.                     

    # Grant permission to run jobs in the project                                                                                                     
    gcloud projects add-iam-policy-binding PROJECT_ID \                                                                                               
      --member="serviceAccount:cloud-run-bq-sa@PROJECT_ID.iam.gserviceaccount.com" \                                                                  
      --role="roles/bigquery.jobUser"                                                                                                                 

    # Grant permission on the dataset                                                                                                                 
    gcloud bigquery datasets add-iam-policy-binding DATASET_NAME \                                                                                    
      --member="serviceAccount:cloud-run-bq-sa@PROJECT_ID.iam.gserviceaccount.com" \                                                                  
      --role="roles/bigquery.dataViewer"                                                                                                              
    ──────                                                                                                                                            
  #### 3. In-Code Access (Application Default Credentials)                                                                                            

  In your application code, initialize the official Google Cloud BigQuery client library without passing explicit credentials. The library            
  automatically retrieves tokens via Application Default Credentials (ADC) from the Cloud Run metadata server.                                        

  Python Example:                                                                                                                                     

    from google.cloud import bigquery                                                                                                                 

    # Automatically authenticates using the attached service account                                                                                  
    client = bigquery.Client(project="PROJECT_ID")                                                                                        

    query_job = client.query("SELECT 1 AS test")                                                                                                      
    results = query_job.result()
Enter fullscreen mode Exit fullscreen mode

I asked Antigravity CLI the following question: how did you answer the above question?

And here is the response. Check how it used the other skill:

I answered the question by drawing on Google Cloud's Security Best Practices (documented in the SKILL.md skill):                                    

  1. Authentication Framework (Identity)                                                                                                              
      • Google Cloud recommends using managed service identities for production workloads rather than static credentials (like JSON key files).       
      • In Cloud Run, attaching a custom service account allows the instance metadata server to issue short-lived access tokens dynamically.          
  2. IAM Authorization Model (Permissions)                                                                                                            
      • Google Cloud IAM enforces the principle of least privilege.                                                                                   
      • Accessing BigQuery requires separating job execution rights (roles/bigquery.jobUser) from data access rights (roles/bigquery.dataViewer or    
      dataEditor).                                                                                                                                    
  3. Application Default Credentials (ADC)                                                                                                            
      • Standard Google Cloud Client Libraries automatically search for credentials in a predefined hierarchy.                                        
      • On Cloud Run, ADC automatically retrieves tokens from the attached service account via the internal metadata server (http://169.254.169.254), 
      making hardcoded credentials unnecessary.
Enter fullscreen mode Exit fullscreen mode

3. Setting up a Service Account

Try out things like this Help me set up a service account for my Cloud Run application with minimal permissions to access BigQuery

BigQuery Skills

In this step, we’ll explore how to use Agent Skills to interact with Google BigQuery. Instead of manually writing bash scripts, SQL queries, or Python clients, we will rely entirely on our AI agent.

Confirming Skill Installation

For this step, we will use the bigquery-basics skill. Confirm it's installed:

npx skills list
Enter fullscreen mode Exit fullscreen mode

Prompt-Driven BigQuery Operations

With the bigquery-basics skill, the agent understands how to manage datasets, create tables, insert data, and run analytical queries.

1. Creating a Dataset

You prompt: Create a new BigQuery dataset called skills_tutorial in my project PROJECT_ID

Agent response:

The BigQuery dataset skills_tutorial has been successfully created in project PROJECT_ID.                                               

  ### Dataset Details:                                                                                                                                

  • Dataset ID: PROJECT_ID:skills_tutorial                                                                                                
  • Location: US                                                                                                                                      
  • Type: DEFAULT                                                                                                                                     
  • Status: Active (Verified)
Enter fullscreen mode Exit fullscreen mode
  1. Creating a Table

You prompt: Now create a table called web_analytics in that dataset with columns for: event_timestamp (TIMESTAMP), page_url (STRING), user_id (STRING), session_duration_seconds (FLOAT64), country (STRING)

Agent response:

The BigQuery table web_analytics has been successfully created in dataset skills_tutorial.                                                          

  ### Table Details:                                                                                                                                  

  • Table ID: PROJECT_ID:skills_tutorial.web_analytics                                                                                    

  ### Schema:                                                                                                                                         

   Column Name │ Type │ Mode
  ─────────────────────────────────────────────────┼─────────────────────────────────────────────────┼────────────────────────────────────────────────
   event_timestamp │ TIMESTAMP │ NULLABLE
   page_url │ STRING │ NULLABLE
   user_id │ STRING │ NULLABLE
   session_duration_seconds │ FLOAT64 │ NULLABLE
   country │ STRING │ NULLABLE
Enter fullscreen mode Exit fullscreen mode

3. Inserting Sample Data

You prompt: Insert 10 rows of realistic sample web analytics data into the web_analytics table

Agent response:

10 realistic sample rows have been inserted into PROJECT_ID:skills_tutorial.web_analytics.                                              

  ### Inserted Data Preview:                                                                                                                          

   event_timestamp │ page_url │ user_id │ session_duration_seconds │ country
  ───────────────────────────┼─────────────────────────────────────┼───────────────────────────┼───────────────────────────┼──────────────────────────
   2026-07-23 10:15:30 UTC │ https://example.com/home │ usr_1001 │ 45.2 │ US
   2026-07-23 10:18:12 UTC │ https://example.com/products/laptop │ usr_1002 │ 120.8 │ CA
   2026-07-23 11:02:45 UTC │ https://example.com/blog/ai-trends │ usr_1003 │ 310.5 │ GB
   2026-07-23 11:45:00 UTC │ https://example.com/cart │ usr_1001 │ 88.0 │ US
   2026-07-23 12:30:15 UTC │ https://example.com/checkout │ usr_1004 │ 215.3 │ DE
   2026-07-23 13:10:05 UTC │ https://example.com/home │ usr_1005 │ 15.6 │ IN
   2026-07-23 14:05:22 UTC │ https://example.com/pricing │ usr_1006 │ 175.4 │ JP
   2026-07-23 14:22:10 UTC │ https://example.com/docs/api │ usr_1007 │ 450.0 │ US
   2026-07-23 15:00:50 UTC │ https://example.com/about │ usr_1008 │ 62.1 │ FR
   2026-07-23 15:40:18 UTC │ https://example.com/contact │ usr_1009 │ 95.7 │ AU
Enter fullscreen mode Exit fullscreen mode

4. Running Analytical Queries

You prompt: Query the web_analytics table to show me the top 5 countries by average session duration

Agent response:

Here are the top 5 countries by average session duration from the web_analytics table:                                                              

  ### Query Results:                                                                                                                                  

                  Rank  Country  Average Session Duration (seconds)  Total Sessions
  ─────────────────────────────────────┼────────────────────────────────────┼────────────────────────────────────┼────────────────────────────────────
                    1  United Kingdom (GB)  310.50 s  1
                    2  Germany (DE)  215.30 s  1
                    3  United States (US)  194.40 s  3
                    4  Japan (JP)  175.40 s  1
                    5  Canada (CA)  120.80 s  1
  ──────                                                                                                                                              
  ### Executed SQL Query:                                                                                                                             

    SELECT                                                                                                                                            
      country,                                                                                                                                        
      ROUND(AVG(session_duration_seconds), 2) AS avg_session_duration_seconds,                                                                        
      COUNT(*) AS total_sessions                                                                                                                      
    FROM `PROJECT_ID.skills_tutorial.web_analytics`                                                                                       
    GROUP BY country                                                                                                                                  
    ORDER BY avg_session_duration_seconds DESC                                                                                                        
    LIMIT 5;
Enter fullscreen mode Exit fullscreen mode

5. Complex Aggregations

You prompt: Show me a query that calculates daily page view counts grouped by URL

Agent response:

Here is the SQL query to calculate daily page view counts grouped by URL, along with unique visitor metrics:                                        

  ### SQL Query:                                                                                                                                      

    SELECT                                                                                                                                            
      DATE(event_timestamp) AS event_date,                                                                                                            
      page_url,                                                                                                                                       
      COUNT(*) AS page_views,                                                                                                                         
      COUNT(DISTINCT user_id) AS unique_visitors                                                                                                      
    FROM `PROJECT_ID.skills_tutorial.web_analytics`                                                                                       
    GROUP BY                                                                                                                                          
      event_date,                                                                                                                                     
      page_url                                                                                                                                        
    ORDER BY                                                                                                                                          
      event_date DESC,                                                                                                                                
      page_views DESC;                                                                                                                                
    ──────                                                                                                                                            
  ### Execution Results:                                                                                                                              

   Event Date  Page URL  Page Views  Unique Visitors
  ────────────────────────────────────┼─────────────────────────────────────┼────────────────────────────────────┼────────────────────────────────────
   2026-07-23  https://example.com/home  2  2
   2026-07-23  https://example.com/products/laptop  1  1
   2026-07-23  https://example.com/blog/ai-trends  1  1
   2026-07-23  https://example.com/cart  1  1
   2026-07-23  https://example.com/checkout  1  1
   2026-07-23  https://example.com/pricing  1  1
   2026-07-23  https://example.com/docs/api  1  1
   2026-07-23  https://example.com/about  1  1
   2026-07-23  https://example.com/contact  1  1
Enter fullscreen mode Exit fullscreen mode

6. Cleanup

You prompt: Clean up i.e. delete the skills_tutorial dataset

Agent response:

The dataset skills_tutorial (and its contained web_analytics table) has been successfully deleted from project PROJECT_ID.              

  ### Clean-Up Summary:                                                                                                                               

  • Deleted Dataset: PROJECT_ID:skills_tutorial                                                                                           
  • Verification Status: Confirmed deleted (Not found).
Enter fullscreen mode Exit fullscreen mode

Notice how you never had to write SQL or learn the bq CLI. The agent did it all.

Cloud Run Deployment

In this step, we’ll deploy a Python application to Google Cloud Run, a fully managed compute platform that automatically scales your stateless containers. Instead of writing the code, containerizing it, and deploying it manually, we’ll let the AI agent handle the entire process.

Confirming Skill Installation

For this step, we will use the cloud-run-basics skill. Confirm it's installed:

npx skills list
Enter fullscreen mode Exit fullscreen mode

Prompt-Driven Application Deployment

With the cloud-run-basics skill, the agent knows how to write application code, create optimized Dockerfiles, and deploy to Cloud Run using best practices.

1. Generating the Application Code

You prompt: Create a simple Flask web API with three endpoints: GET / (returns service info), GET /health (returns OK), and POST /analyze (accepts JSON with a text field and returns word count and character count)

Agent response:

The Flask Web API has been created in app.py and verified with tests in test_app.py.                                                                

  ### API Endpoints Summary                                                                                                                           

  1. GET /                                                                                                                                            
       Description: Returns service information and endpoints metadata.                                                                              
       Response:                                                                                                                                     
        {                                                                                                                                             
          "service": "Text Analysis Web API",                                                                                                         
          "version": "1.0.0",                                                                                                                         
          "status": "running",                                                                                                                        
          "endpoints": [...]                                                                                                                          
        }                                                                                                                                             

  2. GET /health                                                                                                                                      
       Description: Health check endpoint.                                                                                                           
       Response: {"status": "OK"} (HTTP 200)                                                                                                         
  3. POST /analyze                                                                                                                                    
       Description: Accepts a JSON body containing a text string field and returns word count and character count.                                   
       Sample Request:                                                                                                                               
        curl -X POST http://localhost:8080/analyze \                                                                                                  
          -H "Content-Type: application/json" \                                                                                                       
          -d '{"text": "Hello world from Flask API!"}'                                                                                                

       Sample Response:                                                                                                                              
        {                                                                                                                                             
          "text": "Hello world from Flask API!",                                                                                                      
          "word_count": 5,                                                                                                                            
          "character_count": 27                                                                                                                       
        }                                                                                                                                             


  ──────                                                                                                                                              
  ### How to Run locally                                                                                                                              

    ./.venv/bin/python3 app.py
Enter fullscreen mode Exit fullscreen mode

2. Containerizing the App

You prompt: Create a Dockerfile for this Flask application

Agent response:

The Dockerfile, .dockerignore, and requirements.txt have been created.                                                                              

  ### Dockerfile Contents:                                                                                                                            

    # Use official lightweight Python image                                                                                                           
    FROM python:3.11-slim                                                                                                                             

    # Prevent Python from writing .pyc files and buffer stdout/stderr                                                                                 
    ENV PYTHONUNBUFFERED=1 \                                                                                                                          
        PYTHONDONTWRITEBYTECODE=1 \                                                                                                                   
        PORT=8080                                                                                                                                     

    # Set working directory                                                                                                                           
    WORKDIR /app                                                                                                                                      

    # Install dependencies                                                                                                                            
    COPY requirements.txt .                                                                                                                           
    RUN pip install --no-cache-dir -r requirements.txt                                                                                                

    # Copy application source code                                                                                                                    
    COPY app.py .                                                                                                                                     

    # Expose port                                                                                                                                     
    EXPOSE 8080                                                                                                                                       

    # Run the web service using Gunicorn                                                                                                              
    CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 app:app                                                                
    ──────                                                                                                                                            
  ### Key Highlights:                                                                                                                                 

  • Production WSGI: Configured with gunicorn for high performance and concurrency.                                                                   
  • Cloud Run Compatible: Listens on dynamic $PORT (defaulting to 8080).                                                                              
  • Optimized Build: .dockerignore created to exclude virtual environments, cache files, and unnecessary repository metadata.
Enter fullscreen mode Exit fullscreen mode
  1. Deploying to Cloud Run

You prompt: Deploy this application to Cloud Run in us-central1 region as a service called skills-tutorial-analyzer

Agent response:

The deployment command for skills-tutorial-analyzer to Cloud Run in us-central1 has been launched in the background. I will wait for it to complete 
  before proceeding.....

The Flask application has been successfully built and deployed to Cloud Run!                                                                        

  ### Deployment Details:                                                                                                                             

  • Service Name: skills-tutorial-analyzer                                                                                                            
  • Region: us-central1                                                                                                                               
  • Project: PROJECT_ID                                                                                                                   
  • Service URL: [https://skills-tutorial-analyzer-<PROJECT-NUMBER>.us-central1.run.app](https://skills-tutorial-analyzer-415458962931.us-central1.run.app)                                                                    
  ──────                                                                                                                                              
  ### Verified Endpoints:                                                                                                                             

  #### 1. Service Information (GET /)                                                                                                                 

    curl https://skills-tutorial-analyzer-<PROJECT-NUMBER>.us-central1.run.app/                                                                           

  Response:                                                                                                                                           

    {                                                                                                                                                 
      "service": "Text Analysis Web API",                                                                                                             
      "version": "1.0.0",                                                                                                                             
      "status": "running",                                                                                                                            
      "endpoints": [...]                                                                                                                              
    }                                                                                                                                                 

  #### 2. Health Check (GET /health)                                                                                                                  

    curl https://skills-tutorial-analyzer-<PROJECT-NUMBER>.us-central1.run.app/health                                                                     

  Response:                                                                                                                                           

    {                                                                                                                                                 
      "status": "OK"                                                                                                                                  
    }                                                                                                                                                 

  #### 3. Text Analysis (POST /analyze)                                                                                                               

    curl -X POST https://skills-tutorial-analyzer-<PROJECT_NUMBER>.us-central1.run.app/analyze \                                                          
      -H "Content-Type: application/json" \                                                                                                           
      -d '{"text": "Hello world from deployed Cloud Run service!"}'                                                                                   

  Response:                                                                                                                                           

    {                                                                                                                                                 
      "text": "Hello world from deployed Cloud Run service!",                                                                                         
      "word_count": 7,                                                                                                                                
      "character_count": 44                                                                                                                           
    }
Enter fullscreen mode Exit fullscreen mode

4. Testing the Health Endpoint

You prompt: What’s the URL of my deployed service? Test it by hitting the health endpoint

Agent response:

The URL of your deployed Cloud Run service is:                                                                                                      

  🔗 https://skills-tutorial-analyzer-<PROJECT-NUMBER>.us-central1.run.app                                                                                
  ──────                                                                                                                                              
  ### Health Endpoint Test (GET /health)                                                                                                              

    curl -i https://skills-tutorial-analyzer-<PROJECT-NUMBER>.us-central1.run.app/health                                                                  

  #### Response:                                                                                                                                      

    HTTP/2 200                                                                                                                                        
    content-type: application/json                                                                                                                    
    date: Thu, 23 Jul 2026 10:43:31 GMT                                                                                                               
    server: Google Frontend                                                                                                                           

    {"status":"OK"}
Enter fullscreen mode Exit fullscreen mode

5. Testing the Analyze Endpoint

You prompt: Send a POST request to the /analyze endpoint with the text ‘Google Cloud Skills make AI agents powerful’

Agent response:

Here is the response from sending the POST request to the /analyze endpoint:                                                                        

  ### Request:                                                                                                                                        

    curl -X POST https://skills-tutorial-analyzer-<PROJECT-NUMBER>.us-central1.run.app/analyze \                                                          
      -H "Content-Type: application/json" \                                                                                                           
      -d '{"text": "Google Cloud Skills make AI agents powerful"}'                                                                                    
    ──────                                                                                                                                            
  ### Response (HTTP 200 OK):                                                                                                                         

    {                                                                                                                                                 
      "text": "Google Cloud Skills make AI agents powerful",                                                                                          
      "word_count": 7,                                                                                                                                
      "character_count": 43                                                                                                                           
    }
Enter fullscreen mode Exit fullscreen mode

6. Cleanup

You prompt: Delete the skills-tutorial-analyzer Cloud Run service to clean up

Agent response:

The deletion command for Cloud Run service skills-tutorial-analyzer has been launched in the background. I will wait for it to complete before      
  proceeding.                                                                                                                                         

....
....

  The Cloud Run service skills-tutorial-analyzer has been successfully deleted from region us-central1 in project PROJECT_ID.             

  ### Clean-Up Verification:                                                                                                                          

  • Service Name: skills-tutorial-analyzer                                                                                                            
  • Region: us-central1                                                                                                                               
  • Status: Deleted (Verified via gcloud run services describe)
Enter fullscreen mode Exit fullscreen mode

The agent wrote the code, containerized it, deployed it, and tested it — all from natural language.

To summarize

You have seen how to use Google Cloud Agent Skills now. The next part of the series will cover a few advanced skills around Architecture, Security and even writing your own Custom Skill. Stay tuned.


Top comments (0)