איך פורסים את OpenClaw במכונות של Cloud Run באמצעות Terraform

1. מבוא

סקירה כללית

בשיעור ה-Lab הזה תפרסו מכונה קבועה לחלוטין ברמת ייצור של OpenClaw – מסגרת של סוכן AI בקוד פתוח – במכונות של Cloud Run באמצעות תשתית הצהרתית כקוד (Terraform). תקצו מכונות של Cloud Run באמצעות המשאב google_cloud_run_v2_instance מהספק google, תטענו את Google Cloud Storage דרך Cloud Storage FUSE כדי לשמור את המצב של סביבת העבודה של הסוכן, תנהלו את פרטי הכניסה ל-API באופן מאובטח באמצעות Google Cloud Secret Manager ותתקשרו עם סוכן ה-AI דרך ממשק המשתמש המובנה באינטרנט של OpenClaw באמצעות SSH מקורי של מכונות Cloud Run להתאמת מכשירים מאובטחת.

לפני שמתחילים, כדאי לעיין במסמכי התיעוד של OpenClaw כדי להכיר את הארכיטקטורה, הכלים ותהליכי העבודה של הסוכנים ב-OpenClaw.

הפעולות שתבצעו:

  • מגדירים את כל התשתית באופן הצהרתי ב-Terraform‏ (main.tf), כולל ממשקי API, חשבונות שירות, קישורי IAM, סודות, קטגוריות אחסון ומכונות Cloud Run.
  • פורסים את OpenClaw 2.0+‎ (ghcr.io/openclaw/openclaw:latest) באמצעות google_cloud_run_v2_instance.
  • יצירה ואחסון אוטומטיים של פרטי כניסה מאובטחים לשער גישה מאובטח ב-Secret Manager.
  • טוענים קטגוריה של Cloud Storage באמצעות Cloud Storage FUSE ומסנכרנים את /home/node/.openclaw כדי לשמור על המצב, סביבת העבודה וה-SQLite.
  • משתמשים ב-gcloud beta run instances ssh כדי לאמת ולאשר בקשות להתאמת מכשירים בדפדפן בממשק המשתמש של OpenClaw Control באינטרנט.
  • (אופציונלי) מגדירים ערוץ להעברת הודעות (טלגרם או וואטסאפ).
  • (אופציונלי) כדי להרחיב את היכולות של הסוכן, אפשר להוסיף מיומנויות בהתאמה אישית ל-Cloud Storage.

מה תלמדו

  • איך להצהיר על מכונות Cloud Run ולפרוס אותן באמצעות Terraform.
  • איך מגדירים נקודות טעינה של Cloud Storage FUSE ב-Terraform.
  • איך להחדיר באופן מאובטח סודות של Secret Manager כמשתני סביבה למכונות של Cloud Run.
  • איך לנהל את אימות המכשירים ב-OpenClaw 2.0 באמצעות SSH מקורי של מכונות Cloud Run.
  • איך מריצים עומסי עבודה של סוכנים קבועים וארוכים במכונות של Cloud Run.

2. הגדרה ודרישות

הגדרת פרויקט ב-GCP

  1. נכנסים למסוף Google Cloud.
  2. בוחרים פרויקט קיים ב-Google Cloud או יוצרים פרויקט חדש.
  3. מוודאים שהחיוב מופעל בפרויקט בענן ב-Google Cloud.

פתיחת Cloud Shell

מפעילים את Google Cloud Shell מסרגל הכלים העליון של מסוף Cloud. ב-Cloud Shell מותקנים מראש Terraform ו-Google Cloud SDK.

הגדרת פרויקט ואזור

מגדירים את מזהה הפרויקט והאזור כמשתני סביבה, ומגדירים את gcloud:

export PROJECT_ID=<YOUR_PROJECT_ID>
export REGION=<YOUR_REGION>

gcloud config set project $PROJECT_ID
gcloud config get project

התקנת רכיבי בטא של gcloud

מוודאים שהרכיב beta מותקן (נדרש ל-SSH של מכונות Cloud Run ולסטרימינג של יומנים):

gcloud components install beta --quiet
gcloud components update

אימות של Terraform

מוודאים ש-Terraform מותקנת ושהיא עומדת בדרישות הגרסה:

terraform version

אמורה להופיע גרסה Terraform v1.5.0 ואילך.

3. (אופציונלי) הגדרת שילובים של אפליקציות להעברת הודעות (טלגרם או וואטסאפ)

אתם יכולים לקשר את OpenClaw ל-Telegram או ל-WhatsApp. בוחרים באפשרות א' או ב' בהמשך.

אפשרות א': הגדרת בוט ב-Telegram

  1. פותחים את Telegram ומחפשים את @BotFather.
  2. שולחים את הפקודה /newbot ופועלים לפי ההנחיות כדי לציין שם לבוט ושם משתמש.
  3. מעתיקים את טוקן ה-HTTP API שנוצר (למשל, 123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ).
  4. מחפשים את @userinfobot ב-Telegram, שולחים את /start ומעתיקים את מזהה המשתמש המספרי (למשל, 8035936176).

תצטרכו לספק את הערכים האלה כמשתני קלט של Terraform בקובץ terraform.tfvars.

אפשרות ב': הגדרת וואטסאפ

  1. משיגים את מספר הטלפון האישי שלכם בוואטסאפ בפורמט לחיוג בינלאומי, בלי רווחים או סמלים (למשל, +15551234567).
  2. ‫OpenClaw מתחבר דרך מדיניות רשימת ההיתרים של ערוץ וואטסאפ.

4. הגדרת תשתית ב-Terraform

נצהיר על כל התשתית שלנו ב-Terraform. התהליך כולל הפעלה של ממשקי ה-Cloud APIs הנדרשים של Google Cloud, יצירה של חשבון השירות הייעודי ותפקידי IAM, יצירה ואחסון של סודות ב-Secret Manager, הקצאת קטגוריית המצב של Cloud Storage, יצירת ההגדרות של openclaw.json ופריסת המכונה של Cloud Run.

1. יצירת ספריית Terraform

יוצרים ספרייה חדשה ב-Cloud Shell לקובצי Terraform ועוברים אליה:

mkdir openclaw-terraform && cd openclaw-terraform

2. יצירה של main.tf

יוצרים קובץ בשם main.tf. ההגדרה הזו משתמשת בספק של Google כדי להגדיר את כל רכיבי התשתית:

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">= 8.8.0"
    }
    random = {
      source  = "hashicorp/random"
      version = ">= 3.5.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

# 1. Enable Required APIs
resource "google_project_service" "services" {
  for_each = toset([
    "run.googleapis.com",
    "secretmanager.googleapis.com",
    "storage.googleapis.com",
    "generativelanguage.googleapis.com",
    "compute.googleapis.com"
  ])
  project            = var.project_id
  service            = each.key
  disable_on_destroy = false
}

# 2. Dedicated Service Account
resource "google_service_account" "openclaw_sa" {
  account_id   = "openclaw-sa"
  display_name = "OpenClaw Service Account"
  depends_on   = [google_project_service.services]
}

# 3. Secret Manager: Gateway Password
resource "random_password" "gateway_password" {
  length  = 32
  special = false
}

resource "google_secret_manager_secret" "gateway_password" {
  secret_id = "openclaw-gateway-password"
  replication {
    auto {}
  }
  depends_on = [google_project_service.services]
}

resource "google_secret_manager_secret_version" "gateway_password" {
  secret      = google_secret_manager_secret.gateway_password.id
  secret_data = random_password.gateway_password.result
}

resource "google_secret_manager_secret_iam_member" "sa_gateway_password" {
  secret_id = google_secret_manager_secret.gateway_password.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.openclaw_sa.email}"
}

# 4. Secret Manager: Gemini API Key
resource "google_secret_manager_secret" "gemini_api_key" {
  secret_id = "gemini-api-key"
  replication {
    auto {}
  }
  depends_on = [google_project_service.services]
}

resource "google_secret_manager_secret_version" "gemini_api_key" {
  secret      = google_secret_manager_secret.gemini_api_key.id
  secret_data = var.gemini_api_key
}

resource "google_secret_manager_secret_iam_member" "sa_gemini_api_key" {
  secret_id = google_secret_manager_secret.gemini_api_key.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.openclaw_sa.email}"
}

# 5. Optional Secret Manager: Telegram Bot Token
resource "google_secret_manager_secret" "telegram_bot_token" {
  count     = var.telegram_bot_token != "" ? 1 : 0
  secret_id = "telegram-bot-token"
  replication {
    auto {}
  }
  depends_on = [google_project_service.services]
}

resource "google_secret_manager_secret_version" "telegram_bot_token" {
  count       = var.telegram_bot_token != "" ? 1 : 0
  secret      = google_secret_manager_secret.telegram_bot_token[0].id
  secret_data = var.telegram_bot_token
}

resource "google_secret_manager_secret_iam_member" "sa_telegram_bot_token" {
  count     = var.telegram_bot_token != "" ? 1 : 0
  secret_id = google_secret_manager_secret.telegram_bot_token[0].id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.openclaw_sa.email}"
}

# 6. Cloud Storage Bucket for State Persistence
resource "google_storage_bucket" "openclaw_state" {
  name                        = "openclaw-state-${var.project_id}"
  location                    = var.region
  uniform_bucket_level_access = true
  force_destroy               = true
  depends_on                  = [google_project_service.services]
}

resource "google_storage_bucket_iam_member" "sa_storage" {
  bucket = google_storage_bucket.openclaw_state.name
  role   = "roles/storage.objectUser"
  member = "serviceAccount:${google_service_account.openclaw_sa.email}"
}

# 7. Upload openclaw.json to Cloud Storage Root
resource "google_storage_bucket_object" "openclaw_config" {
  name   = "openclaw.json"
  bucket = google_storage_bucket.openclaw_state.name
  content = jsonencode({
    gateway = {
      mode           = "local"
      port           = 18789
      trustedProxies = ["127.0.0.1", "::1", "169.254.0.0/16", "10.0.0.0/8"]
      bind           = "lan"
      auth = {
        password = "$${OPENCLAW_GATEWAY_PASSWORD}"
      }
      controlUi = {
        allowedOrigins = ["*"]
        enabled        = true
      }
    }
    memory = {
      search = {
        provider = "gemini"
      }
    }
    agents = {
      defaults = {
        model = {
          primary = "google/gemini-3.1-pro-preview"
        }
        sandbox = {
          mode = "off"
        }
      }
    }
    skills = {
      load = {
        extraDirs = ["/mnt/openclaw/skills"]
      }
    }
    channels = {
      telegram = {
        enabled        = var.telegram_bot_token != ""
        defaultAccount = "default"
        accounts = {
          default = {
            enabled   = var.telegram_bot_token != ""
            dmPolicy  = "allowlist"
            allowFrom = var.telegram_user_id != "" ? [var.telegram_user_id] : []
          }
        }
      }
    }
    plugins = {
      entries = {
        google   = { enabled = true }
        telegram = { enabled = var.telegram_bot_token != "" }
      }
    }
  })
}

# 8. Cloud Run Instance
resource "google_cloud_run_v2_instance" "openclaw" {
  name     = "openclaw-instance"
  location = var.region

  ingress              = "INGRESS_TRAFFIC_ALL"
  invoker_iam_disabled = true
  restart_policy       = "ON_FAILURE"
  service_account      = google_service_account.openclaw_sa.email

  containers {
    image = "ghcr.io/openclaw/openclaw:latest"
    args = [
      "/bin/sh",
      "-c",
      "cp /mnt/openclaw/openclaw.json /home/node/.openclaw/ && exec node /app/openclaw.mjs gateway"
    ]

    ports {
      container_port = 18789
    }

    resources {
      limits = {
        cpu    = "4"
        memory = "4Gi"
      }
    }

    env {
      name = "GEMINI_API_KEY"
      value_source {
        secret_key_ref {
          secret  = google_secret_manager_secret.gemini_api_key.secret_id
          version = "latest"
        }
      }
    }

    env {
      name = "OPENCLAW_GATEWAY_PASSWORD"
      value_source {
        secret_key_ref {
          secret  = google_secret_manager_secret.gateway_password.secret_id
          version = "latest"
        }
      }
    }

    dynamic "env" {
      for_each = toset(var.telegram_bot_token != "" ? ["telegram"] : [])
      content {
        name = "TELEGRAM_BOT_TOKEN"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.telegram_bot_token[0].secret_id
            version = "latest"
          }
        }
      }
    }

    volume_mounts {
      name       = "openclaw-storage"
      mount_path = "/mnt/openclaw"
    }
  }

  volumes {
    name = "openclaw-storage"
    gcs {
      bucket        = google_storage_bucket.openclaw_state.name
      read_only     = false
      mount_options = ["uid=1000", "gid=1000", "file-mode=0700", "dir-mode=0700"]
    }
  }

  depends_on = [
    google_project_service.services,
    google_storage_bucket_object.openclaw_config,
    google_secret_manager_secret_version.gateway_password,
    google_secret_manager_secret_version.gemini_api_key,
    google_secret_manager_secret_iam_member.sa_gateway_password,
    google_secret_manager_secret_iam_member.sa_gemini_api_key,
    google_storage_bucket_iam_member.sa_storage
  ]
}

3. יצירה של variables.tf

יוצרים קובץ בשם variables.tf כדי להגדיר את משתני הקלט:

variable "project_id" {
  type        = string
  description = "Google Cloud Project ID"
}

variable "region" {
  type        = string
  default     = "us-west1"
  description = "Google Cloud Region for Cloud Run and Storage"
}

variable "gemini_api_key" {
  type        = string
  sensitive   = true
  description = "Gemini API Key from Google AI Studio"
}

variable "telegram_bot_token" {
  type        = string
  default     = ""
  sensitive   = true
  description = "(Optional) Telegram Bot HTTP API Token"
}

variable "telegram_user_id" {
  type        = string
  default     = ""
  description = "(Optional) Telegram User ID for allowlist policy"
}

4. יצירה של outputs.tf

יוצרים קובץ בשם outputs.tf כדי לחשוף את כתובת ה-URL של המכונה שנפרסה, את הסיסמה שנוצרה לשער ואת השם של קטגוריית האחסון:

output "instance_url" {
  description = "Public URL for OpenClaw Cloud Run Instance"
  value       = google_cloud_run_v2_instance.openclaw.urls[0]
}

output "gateway_password" {
  description = "Generated OpenClaw Gateway Password"
  value       = random_password.gateway_password.result
  sensitive   = true
}

output "storage_bucket" {
  description = "Cloud Storage bucket persisting OpenClaw state"
  value       = google_storage_bucket.openclaw_state.name
}

5. יצירה של terraform.tfvars

כדי לקבל מפתח Gemini API:

  1. נכנסים ל-Google AI Studio באמצעות חשבון Google.
  2. לוחצים על יצירת מפתח API ובוחרים את הפרויקט ב-Google Cloud.
  3. מעתיקים את מפתח ה-API שנוצר.

יוצרים קובץ בשם terraform.tfvars עם הקואורדינטות של הפרויקט:

project_id     = "YOUR_PROJECT_ID"
region         = "YOUR_REGION"
gemini_api_key = "YOUR_GEMINI_API_KEY"

# Optional: Uncomment if configuring Telegram
# telegram_bot_token = "YOUR_TELEGRAM_BOT_TOKEN"
# telegram_user_id   = "YOUR_TELEGRAM_USER_ID"

5. פריסת תשתית באמצעות Terraform

1. הפעלה והחלה

מפעילים את ספריית העבודה של Terraform ומורידים את הפלאגינים של הספק:

terraform init

פורסים את התשתית:

terraform apply

כשמופיעה בקשה, בודקים את המשאבים המתוכננים ומקלידים yes כדי לאשר.

2. חילוץ פלטים של פריסה

מייצאים את כתובת ה-URL של המכונה ואת סיסמת השער שנוצרה ממצב Terraform:

export INSTANCE_URL=$(terraform output -raw instance_url)
export GATEWAY_PASSWORD=$(terraform output -raw gateway_password)

echo "Instance URL: ${INSTANCE_URL}"
echo "Gateway Password: ${GATEWAY_PASSWORD}"

6. אינטראקציה דרך ממשק המשתמש באינטרנט ואימות באמצעות Cloud Run SSH

ב-OpenClaw 2.0 ואילך מתבצעת אכיפה של אימות מכשיר קריפטוגרפי. כשמתחברים מדפדפן חדש, השער יוצר בקשת התאמה שמאשרים ישירות דרך ה-SSH המקורי של מכונות Cloud Run.

1. פותחים את ממשק המשתמש של OpenClaw Control.

  1. פותחים את $INSTANCE_URL בדפדפן האינטרנט.
  2. כשמופיעה בקשה לאימות, מזינים את סיסמת השער ($GATEWAY_PASSWORD).
  3. מכיוון שזהו סשן חדש בדפדפן, בממשק המשתמש של OpenClaw Control מוצגת בקשה בהמתנה להתאמת מכשירים עם מזהה בקשה (לדוגמה: b56143fc-1654-49da-a1d8-5d40479ddc66). מעתיקים את מזהה הבקשה הזה.

2. ‫SSH למכונה של Cloud Run

ב-Cloud Shell, מפעילים מעטפת אינטראקטיבית מאובטחת במכונה שפועלת:

gcloud beta run instances ssh openclaw-instance --region=${REGION}

3. אישור התאמת המכשירים

בסשן ה-SSH, מאשרים את הבקשה של הדפדפן:

openclaw devices approve <REQUEST_ID> --password ${GATEWAY_PASSWORD}

4. הנחיה לסוכן (אינסטנסים בפעולה)

אחרי האישור, הדפדפן מתחבר מיד למרכז הבקרה של OpenClaw.

  1. כדי לבדוק את סוכן OpenClaw, שולחים הנחיה בממשק המשתמש של הצ'אט, למשל "Hello".
  2. כדי לבדוק את מחזור החיים הארוך ואת האחסון המתמיד של המכונה ב-Cloud Run, מבקשים מסוכן OpenClaw לבצע משימה אוטונומית מתוזמנת. לדוגמה, אפשר לבקש ממנו לעקוב אחרי גרסאות במאגר ב-GitHub ולנסח תקציר:
    Check the GitHub repository openclaw/openclaw every hour for the next 24 hours. Track any new releases, merged pull requests, and breaking changes. Save a structured markdown digest titled `daily-release-digest.md` to your workspace, and notify me in this chat with a summary whenever a new release is detected.
    
  3. מכיוון שהמצב של OpenClaw, קובצי סביבת העבודה ומסדי הנתונים של SQLite נשמרים ישירות ב-Cloud Storage דרך Cloud Storage FUSE, המשימה המתוזמנת, היסטוריית השיחות וקובצי התקציר שנוצרו נשמרים גם אחרי הפעלה מחדש של המכונה ושדרוג של הקונטיינר.

7. (אופציונלי) אימות השילובים של ערוצי ההודעות

אם הגדרתם את Telegram או את WhatsApp בשלבי ההגדרה האופציונליים שלמעלה, אתם יכולים לאמת את שליחת ההודעות:

  1. בודקים את יומני המכונה ב-Cloud Shell:
    gcloud beta run instances logs read openclaw-instance --region ${REGION} --limit 20
    
  2. פותחים את Telegram (או וואטסאפ) ושולחים הודעה (למשל /start או Hello OpenClaw!).
  3. הבוט יאמת את מזהה המשתמש שלכם מול רשימת ההיתרים ב-openclaw.json ויענה באמצעות Gemini.

8. מעקב ובדיקה של יומני מכונות

מופעי Cloud Run מתעדים את stdout ו-stderr מהקונטיינר ומעבירים אותם ישירות ל-Google Cloud Logging. אתם יכולים להשתמש ב-Cloud Shell או במסוף Cloud כדי לעקוב אחרי התנועה בשער ולבדוק את הפעלות הכלים של הנציג בזמן אמת.

1. קריאת יומני המופעים האחרונים

כדי לאחזר רשומות יומן אחרונות מהמכונה ב-Cloud Shell:

gcloud beta run instances logs read openclaw-instance \
  --region ${REGION} \
  --limit 50

2. חתימות של יומני מפתחות שצריך לבדוק

כשצופים ב-Agent שפועל, צריך לחפש את האירועים המרכזיים הבאים ביומן זמן הריצה:

  • ‫[gateway] ready: מאשר ששער ה-HTTP וה-WebSocket של OpenClaw אותחל ומאזין ליציאה 18789.
  • ‫[gateway] agent model: ...: מציג את מודל Gemini הפעיל (למשל google/gemini-3.1-pro-preview או google/gemini-3.5-flash).
  • ‫[agents/tool-policy]: הצגת הכלים שמותרים או מוגבלים בהתאם למדיניות שלכם.
  • ‫[agent/embedded]: מעקב אחרי הביצוע והפעלת הכלים על ידי הנציג.

3. בדיקת היומנים במסוף Google Cloud

אפשר גם להציג ולסנן יומנים באמצעות Logs Explorer במסוף Cloud:

resource.type="cloud_run_instance"
resource.labels.instance_name="openclaw-instance"

9. (אופציונלי) הרחבת היכולות של הסוכן באמצעות מיומנויות

‫OpenClaw תומך במיומנויות – חבילות יכולות מודולריות שמלמדות את הסוכן תהליכי עבודה ספציפיים, כלי CLI מיוחדים והוראות ספציפיות לדומיין.

איך פועלים ה-Skills

כל מיומנות היא ספרייה שמכילה קובץ SKILL.md. הוא מתחיל ב-YAML frontmatter שמציין מטא-נתונים (name ו-description), ואחריו הוראות Markdown:

---
name: summarize-logs
description: Summarize Cloud Run error logs into actionable bullet points.
---

# Log Summarizer Skill

When asked to analyze or summarize logs:
1. Parse error stack traces and group similar errors by frequency.
2. Identify root causes such as memory limits, timeouts, or permission errors.
3. Propose concrete remediation steps.
  • ‫name: מזהה המיומנות (אפשר גם להפעיל אותו ישירות כפקודה דרך שורת הפקודות, למשל /summarize-logs).
  • ‫description: אומר למודל של OpenClaw מתי להפעיל את הסקיל הזה באופן אוטומטי בשיחה טבעית.

הוספת מיומנות בהתאמה אישית לקטגוריה של Cloud Storage

מכיוון שהקטגוריה של Cloud Storage מותקנת ב-/mnt/openclaw ומוגדרת ב-skills.load.extraDirs, מיומנויות שמוצבות ב-gs://${BUCKET_NAME}/skills/ נטענות באופן אוטומטי ונשמרות בהפעלות מחדש של המכונה:

  1. אחזור שם הקטגוריה:
    export BUCKET_NAME=$(terraform output -raw storage_bucket)
    
  2. יצירת מאגר מיומנויות מקומי:
    mkdir -p my-skill
    cat << 'EOF' > my-skill/SKILL.md
    ---
    name: summarize-logs
    description: Summarize Cloud Run error logs into actionable bullet points.
    ---
    
    # Log Summarizer Skill
    
    When asked to analyze or summarize logs, group errors by frequency and suggest actionable fixes.
    EOF
    
  3. העלאת המיומנות ל-Cloud Storage:
    gcloud storage cp -r my-skill gs://${BUCKET_NAME}/skills/
    
  4. שימוש במיומנות ב-Chat:
    • חוזרים לממשק המשתמש האינטרנטי של OpenClaw Control.
    • עכשיו אפשר לתת הנחיות לסוכן באמצעות /summarize-logs או לשאול שאלות בשפה טבעית שתואמות לתיאור המיומנות.

10. מחיקה

כדי להימנע מחיובים מתמשכים בחשבון Google Cloud על המשאבים שבהם השתמשתם ב-Codelab הזה, אתם יכולים להשמיד את כל התשתית שהוקצתה בשלב אחד באמצעות Terraform:

  1. מוודאים שאתם נמצאים בספרייה openclaw-terraform:
    cd openclaw-terraform
    
  2. השמדת כל המשאבים:
    terraform destroy
    
  3. כשמופיעה בקשה, בודקים את המשאבים שיוסרו ומקלידים yes כדי לאשר. ‫Terraform ימחק באופן נקי את המכונה של Cloud Run, את הסודות של Secret Manager, את קישורי המדיניות של IAM, את חשבון השירות ואת הקטגוריה של Cloud Storage.

11. סיכום

מעולה! פרסתם בהצלחה מכונה מאובטחת ומתמידה לחלוטין של OpenClaw במכונות של Cloud Run באמצעות Terraform הצהרתי, שמגובה על ידי התמדת מצב של Cloud Storage, אבטחת פרטי כניסה של Secret Manager ו-SSH מקורי של מכונות Cloud Run לאימות מאובטח של מכשירים.