Skip to content

Add GCP Cloud Run support with managed services orchestration#9

Draft
Copilot wants to merge 3 commits intocopilot/add-cloud-resource-provisioningfrom
copilot/add-gcp-cli-wrapper
Draft

Add GCP Cloud Run support with managed services orchestration#9
Copilot wants to merge 3 commits intocopilot/add-cloud-resource-provisioningfrom
copilot/add-gcp-cli-wrapper

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 25, 2026

Adds Google Cloud Platform compute via Cloud Run (serverless containers), mirroring the existing Azure and AWS implementations.

Implementation

fastops/gcp.py - New CLI wrapper and orchestrator

  • Gcp(Cli) class with gcloud singleton following Az/Aws pattern
  • callgcloud() helper appends --format=json for structured output
  • gcp_stack() orchestrates Cloud Run + optional Cloud SQL (PostgreSQL) and Memorystore (Redis)
  • Idempotent resource creation catches "already exists" errors
  • Auto-configures DATABASE_URL and REDIS_URL environment variables

fastops/ship.py - GCP deployment integration

  • Added **kw to function signature for extensibility
  • to='gcp' branch with lazy import and kw.get() parameter pattern

fastops/teardown.py - Resource cleanup utilities

  • destroy_cloud_run(), destroy_cloud_sql(), destroy_memorystore()
  • teardown_gcp() orchestrator for full application cleanup

Usage

from fastops.ship import ship

# Deploy to Cloud Run with managed services
ship('.', to='gcp', 
     image='gcr.io/project/app:latest',
     domain='api.example.com',
     postgres=True, 
     redis=True,
     region='us-central1',
     min_instances=0,
     max_instances=10)

# Teardown all resources
from fastops.teardown import teardown_gcp
teardown_gcp('myapp', region='us-central1', postgres=True, redis=True)

Cloud Run defaults: serverless scaling (0-10 instances), 512Mi memory, 1 CPU, public ingress.

Original prompt

Overview

fastops currently has compute support for Docker (local), Hetzner VPS, Azure (azure_stack()), and AWS (aws_stack()), but no GCP compute. This PR adds fastops/gcp.py with a gcloud CLI wrapper and gcp_stack() orchestrator, plus ship(to='gcp') support.

Branch off copilot/add-cloud-resource-provisioning.


File 1: fastops/gcp.py

Module docstring

"""Google Cloud Platform CLI wrapper and opinionated resource builders."""

__all__

['Gcp', 'gcloud', 'gcp_stack']

Imports

import os, json, subprocess
from .core import Cli

Class: Gcp(Cli)

Follow the exact same pattern as Az in azure.py and Aws in aws.py. The Cli base class (from core.py) uses __getattr__ to dispatch subcommands.

class Gcp(Cli):
    'Google Cloud CLI wrapper'
    def __init__(self): super().__init__('gcloud')

Create a module-level singleton: gcloud = Gcp()

Helper: callgcloud(*args)

def callgcloud(*args):
    'Run a gcloud command and return parsed JSON output'
    cmd = ['gcloud'] + list(args) + ['--format=json']
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        raise RuntimeError(f'gcloud error: {result.stderr}')
    return json.loads(result.stdout) if result.stdout.strip() else {}

Function: gcp_stack(name, *, image=None, port=8080, region='us-central1', project=None, postgres=False, redis=False, domain=None, min_instances=0, max_instances=10, memory='512Mi', cpu='1', env=None, service_account=None)

High-level GCP orchestrator using Cloud Run (serverless containers — the GCP equivalent of Azure Container Instances / AWS ECS Fargate).

def gcp_stack(name, *, image=None, port=8080, region='us-central1', project=None,
              postgres=False, redis=False, domain=None, min_instances=0, max_instances=10,
              memory='512Mi', cpu='1', env=None, service_account=None):
    'Deploy a containerized app to GCP Cloud Run with optional managed services'
    result = {'name': name, 'region': region, 'services': []}
    
    proj = project or os.environ.get('GCLOUD_PROJECT') or os.environ.get('GOOGLE_CLOUD_PROJECT', '')
    proj_args = ['--project', proj] if proj else []
    
    app_env = dict(env or {})
    
    # Optional: Cloud SQL (PostgreSQL)
    if postgres:
        db_instance = f'{name}-db'
        db_password = os.environ.get('DB_PASSWORD', 'changeme')
        try:
            callgcloud('sql', 'instances', 'create', db_instance,
                       '--database-version=POSTGRES_16',
                       '--tier=db-f1-micro',
                       f'--region={region}',
                       '--root-password=' + db_password,
                       *proj_args)
        except RuntimeError as e:
            if 'already exists' not in str(e).lower(): raise
        
        callgcloud('sql', 'databases', 'create', name,
                    f'--instance={db_instance}', *proj_args)
        
        app_env['DATABASE_URL'] = f'postgresql://postgres:{db_password}@/{name}?host=/cloudsql/{proj}:{region}:{db_instance}'
        result['services'].append({'type': 'cloud-sql', 'instance': db_instance})
    
    # Optional: Memorystore (Redis)
    if redis:
        redis_instance = f'{name}-redis'
        try:
            callgcloud('redis', 'instances', 'create', redis_instance,
                       f'--region={region}',
                       '--size=1',
                       '--tier=basic',
                       *proj_args)
        except RuntimeError as e:
            if 'already exists' not in str(e).lower(): raise
        
        redis_info = callgcloud('redis', 'instances', 'describe', redis_instance,
                                f'--region={region}', *proj_args)
        redis_host = redis_info.get('host', 'localhost')
        redis_port = redis_info.get('port', 6379)
        app_env['REDIS_URL'] = f'redis://{redis_host}:{redis_port}'
        result['services'].append({'type': 'memorystore', 'instance': redis_instance})
    
    # Deploy to Cloud Run
    if image:
        deploy_args = [
            'run', 'deploy', name,
            f'--image={image}',
            f'--port={port}',
            f'--region={region}',
            f'--memory={memory}',
            f'--cpu={cpu}',
            f'--min-instances={min_instances}',
            f'--max-instances={max_instances}',
            '--allow-unauthenticated',
            *proj_args,
        ]
        
        if service_account:
            deploy_args.append(f'--service-account={service_account}')
        
        if app_env:
            env_str = ','.join(f'{k}={v}' for k, v in app_env.items())
            deploy_args.append(f'--set-env-vars={env_str}')
        
        if postgres:
            deploy_args.append(f'--add-cloudsql-instances={proj}:{region}:{name}-db')
        
        deploy_result = callgcloud(*deploy_args)
        
        url = deploy_result.get('status', {}).get('u...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

<!-- START COPILOT CODING AGENT TIPS -->
---Let Copilot coding agent [set things up for you](https://github.com/Karthik777/fastops/issues/new?title=+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits February 25, 2026 04:59
Co-authored-by: Karthik777 <7102951+Karthik777@users.noreply.github.com>
Co-authored-by: Karthik777 <7102951+Karthik777@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Google Cloud Platform compute support to fastops Add GCP Cloud Run support with managed services orchestration Feb 25, 2026
Copilot AI requested a review from Karthik777 February 25, 2026 05:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants