1. Введение
Обзор
В этой практической работе вы развернете полностью персистентный экземпляр OpenClaw (фреймворка ИИ-агентов с открытым исходным кодом) в экземплярах Cloud Run с помощью декларативной инфраструктуры как кода (Terraform). Вы подготовите экземпляры Cloud Run, используя ресурс google_cloud_run_v2_instance от поставщика google, подключите Google Cloud Storage через Cloud Storage FUSE, чтобы сохранить состояние рабочей области агента, настроите безопасное управление учетными данными API с помощью Google Cloud Secret Manager и будете взаимодействовать со своим ИИ-агентом через встроенный веб-интерфейс 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. - (Необязательно.) Настройте канал обмена сообщениями (Telegram или WhatsApp).
- (Необязательно.) Расширьте возможности агента, добавив в Cloud Storage собственные навыки.
Что вы узнаете
- Как объявлять и развертывать экземпляры Cloud Run с помощью Terraform.
- Как настроить точки подключения томов Cloud Storage FUSE в Terraform.
- Как безопасно внедрять секреты Secret Manager в качестве переменных среды в экземпляры Cloud Run.
- Как управлять аутентификацией устройств OpenClaw 2.0 с помощью встроенного SSH экземпляров Cloud Run
- Как запускать долгоживущие постоянные рабочие нагрузки агентов в экземплярах Cloud Run.
2. Настройка и требования
Настройка проекта GCP
- Войдите в консоль Google Cloud.
- Создайте или выберите проект Google Cloud.
- Убедитесь, что для проекта Google Cloud включены платежные функции.
Открыть Cloud Shell
Откройте Google Cloud Shell, нажав на значок в верхней панели инструментов Cloud Console. В 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 версии 1.5.0 или более поздней.
3. Как настроить интеграцию с мессенджерами (Telegram или WhatsApp) (необязательно)
Вы можете подключить OpenClaw к Telegram или WhatsApp. Выберите вариант А или вариант Б ниже.
Вариант А. Настройка бота Telegram
- Откройте Telegram и найдите
@BotFather. - Отправьте команду
/newbotи следуйте инструкциям, чтобы указать название и имя пользователя бота. - Скопируйте сгенерированный токен HTTP API (например,
123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ). - Найдите
@userinfobotв Telegram, отправьте/startи скопируйте свой числовой идентификатор пользователя (например,8035936176).
Эти значения нужно будет указать в качестве входных переменных Terraform в файле terraform.tfvars.
Вариант Б. Настройка WhatsApp
- Укажите свой номер телефона в WhatsApp в международном формате без пробелов и символов (например,
+15551234567). - OpenClaw подключается через белый список каналов WhatsApp.
4. Определение инфраструктуры в Terraform
Мы объявим всю нашу инфраструктуру в Terraform. В частности, вам нужно будет включить необходимые API 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:
- Перейдите в Google AI Studio и войдите в аккаунт Google.
- Нажмите Создать ключ API и выберите облачный проект Google Cloud.
- Скопируйте сгенерированный ключ 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
- Откройте
$INSTANCE_URLв браузере. - Когда появится запрос на аутентификацию, введите пароль шлюза (
$GATEWAY_PASSWORD). - Поскольку это новый сеанс браузера, в интерфейсе OpenClaw Control появится запрос на подключение устройства с идентификатором запроса (например,
b56143fc-1654-49da-a1d8-5d40479ddc66). Скопируйте этот идентификатор.
2. Подключение к экземпляру Cloud Run по SSH
В Cloud Shell запустите защищенную интерактивную оболочку в работающем экземпляре:
gcloud beta run instances ssh openclaw-instance --region=${REGION}
3. Одобрить подключение устройств
В сеансе SSH одобрите запрос браузера:
openclaw devices approve <REQUEST_ID> --password ${GATEWAY_PASSWORD}
4. Как задать запрос агенту (примеры)
После одобрения ваш браузер сразу же подключится к панели управления OpenClaw.
- Протестируйте агент OpenClaw, отправив запрос в интерфейсе чата, например
"Hello". - Чтобы протестировать длительный жизненный цикл экземпляра 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. - Поскольку состояние OpenClaw, файлы рабочей области и базы данных SQLite сохраняются непосредственно в Cloud Storage через Cloud Storage FUSE, запланированная задача, история разговоров и сгенерированные файлы дайджестов сохраняются при перезапуске экземпляра и обновлении контейнера.
7. Проверьте интеграцию каналов обмена сообщениями (необязательно)
Если вы настроили Telegram или WhatsApp, как описано выше, вы можете проверить доставку сообщений.
- Проверьте журналы экземпляра в Cloud Shell:
gcloud beta run instances logs read openclaw-instance --region ${REGION} --limit 20 - Откройте Telegram или WhatsApp и отправьте сообщение, например
/startилиHello OpenClaw!. - Бот проверит ваш идентификатор пользователя по белому списку в
openclaw.jsonи ответит с помощью Gemini.
8. Отслеживание и проверка журналов экземпляров
Экземпляры Cloud Run захватывают stdout и stderr из контейнера и передают их напрямую в Google Cloud Logging. Вы можете использовать Cloud Shell или Cloud Console, чтобы отслеживать трафик шлюза и проверять запуски инструментов агента в режиме реального времени.
1. Чтение журналов недавних экземпляров
Чтобы получить последние записи в журнале из экземпляра в Cloud Shell:
gcloud beta run instances logs read openclaw-instance \
--region ${REGION} \
--limit 50
2. Основные сигнатуры журналов, на которые следует обратить внимание
При наблюдении за работающим агентом обратите внимание на следующие ключевые события журнала выполнения:
[gateway] ready– подтверждает, что шлюз OpenClaw HTTP и WebSocket инициализирован и прослушивает порт 18789.[gateway] agent model: ...– показывает активную модель Gemini (например,google/gemini-3.1-pro-previewилиgoogle/gemini-3.5-flash).[agents/tool-policy]– инструменты, разрешенные или запрещенные вашими правилами.[agent/embedded]отслеживает выполнение и вызов инструментов агентом.
3. Как проверить журналы в Google Cloud Console
Вы также можете просматривать и фильтровать журналы с помощью Logs Explorer в Cloud Console.
resource.type="cloud_run_instance"
resource.labels.instance_name="openclaw-instance"
9. Как расширить возможности агента с помощью навыков (необязательно)
OpenClaw поддерживает навыки – модульные пакеты возможностей, которые обучают агента определенным рабочим процессам, специализированным инструментам CLI и инструкциям для конкретных доменов.
Как работают навыки
Каждый навык – это каталог, содержащий файл SKILL.md. Он начинается с блока Front Matter в формате YAML, в котором указаны метаданные (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/, загружаются автоматически и сохраняются при перезапуске экземпляра:
- Как узнать название сегмента
export BUCKET_NAME=$(terraform output -raw storage_bucket) - Создайте каталог местных навыков.
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 - Загрузите навык в Cloud Storage:
gcloud storage cp -r my-skill gs://${BUCKET_NAME}/skills/ - Как использовать навык в Chat
- Вернитесь в веб-интерфейс OpenClaw Control.
- Теперь вы можете отправлять агенту запросы, используя
/summarize-logsили задавая вопросы на естественном языке, соответствующие описанию навыка.
10. Убирать
Чтобы избежать постоянных расходов на аккаунт Google Cloud за ресурсы, используемые в этой практической работе, вы можете уничтожить всю подготовленную инфраструктуру за один шаг с помощью Terraform:
- Перейдите в каталог
openclaw-terraform:cd openclaw-terraform - Удалить все ресурсы:
terraform destroy - Когда появится запрос, проверьте ресурсы, которые нужно удалить, и введите
yesдля подтверждения. Terraform удалит экземпляр Cloud Run, секреты Secret Manager, привязки правил IAM, сервисный аккаунт и сегмент Cloud Storage.
11. Заключение
Поздравляем! Вы успешно развернули безопасный полностью постоянный экземпляр OpenClaw в Cloud Run Instances с помощью декларативного Terraform, поддерживаемого сохранением состояния Cloud Storage, безопасностью учетных данных Secret Manager и собственным SSH Cloud Run Instances для безопасной аутентификации устройств.