1. Introdução
Visão geral
Neste laboratório, você vai implantar uma instância totalmente persistente e de nível de produção do OpenClaw, um framework de agente de IA de código aberto, em instâncias do Cloud Run usando infraestrutura como código declarativa (Terraform). Você vai provisionar instâncias do Cloud Run usando o recurso google_cloud_run_v2_instance do provedor google, montar o Google Cloud Storage via Cloud Storage FUSE para manter o estado do espaço de trabalho do agente, gerenciar as credenciais de API com segurança usando o Google Cloud Secret Manager e interagir com seu agente de IA pela interface da Web integrada do OpenClaw usando o SSH nativo das instâncias do Cloud Run para o pareamento de dispositivos seguro.
Antes de começar, consulte a documentação do OpenClaw para se familiarizar com a arquitetura, as ferramentas e os fluxos de trabalho de agentes do OpenClaw.
Atividades deste laboratório
- Defina toda a infraestrutura de forma declarativa no Terraform (
main.tf), incluindo APIs, contas de serviço, vinculações do IAM, secrets, buckets de armazenamento e instâncias do Cloud Run. - Implante o OpenClaw 2.0+ (
ghcr.io/openclaw/openclaw:latest) usandogoogle_cloud_run_v2_instance. - Gerar e armazenar automaticamente credenciais de gateway seguro no Secret Manager.
- Monte um bucket do Cloud Storage usando o Cloud Storage FUSE e sincronize
/home/node/.openclawpara estado durável, espaço de trabalho e persistência do SQLite. - Use
gcloud beta run instances sshpara autenticar e aprovar solicitações de pareamento de dispositivos do navegador na interface da Web do OpenClaw Control. - (Opcional) Configure um canal de mensagens (Telegram ou WhatsApp).
- (Opcional) Amplie os recursos do agente adicionando habilidades personalizadas ao Cloud Storage.
O que você vai aprender
- Como declarar e implantar instâncias do Cloud Run usando o Terraform.
- Como configurar montagens de volume do Cloud Storage FUSE no Terraform.
- Como injetar secrets do Secret Manager com segurança como variáveis de ambiente em instâncias do Cloud Run.
- Como gerenciar a autenticação de dispositivos do OpenClaw 2.0 usando o SSH nativo das instâncias do Cloud Run.
- Como executar cargas de trabalho de agentes persistentes e de longa duração em instâncias do Cloud Run.
2. Configuração e requisitos
Configuração do projeto do GCP
- Faça login no Console do Google Cloud.
- Criar ou selecionar um projeto do Google Cloud.
- Confira se o faturamento está ativado para seu projeto do Google Cloud
Abrir o Cloud Shell
Ative o Google Cloud Shell na barra de ferramentas superior do console do Cloud. O Cloud Shell inclui o Terraform e o SDK Google Cloud pré-instalados.
Definir projeto e região
Defina o ID do projeto e a região como variáveis de ambiente e configure gcloud:
export PROJECT_ID=<YOUR_PROJECT_ID>
export REGION=<YOUR_REGION>
gcloud config set project $PROJECT_ID
gcloud config get project
Instalar componentes Beta da gcloud
Verifique se o componente beta está instalado (necessário para o SSH de instâncias do Cloud Run e o streaming de registros):
gcloud components install beta --quiet
gcloud components update
Verificar o Terraform
Confirme se o Terraform está instalado e atende aos requisitos de versão:
terraform version
Você vai ver o Terraform v1.5.0 ou mais recente.
3. (Opcional) Configurar integrações de mensagens (Telegram ou WhatsApp)
Você pode conectar o OpenClaw ao Telegram ou ao WhatsApp. Escolha a Opção A ou a Opção B abaixo.
Opção A: configuração do bot do Telegram
- Abra o Telegram e pesquise
@BotFather. - Envie o comando
/newbote siga as instruções para especificar um nome e um nome de usuário para o bot. - Copie o token da API HTTP gerado (por exemplo,
123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ). - Pesquise
@userinfobotno Telegram, envie/starte copie seu ID do usuário numérico (por exemplo,8035936176).
Você vai fornecer esses valores como variáveis de entrada do Terraform no arquivo terraform.tfvars.
Opção B: configuração do WhatsApp
- Pegue seu número de telefone pessoal do WhatsApp no formato internacional, sem espaços ou símbolos (por exemplo,
+15551234567). - O OpenClaw se conecta pela política de lista de permissões do canal do WhatsApp.
4. Definir infraestrutura no Terraform
Vamos declarar toda a infraestrutura no Terraform. Isso inclui ativar as APIs necessárias do Google Cloud, criar a conta de serviço dedicada e os papéis do IAM, gerar e armazenar secrets no Secret Manager, provisionar o bucket de estado do Cloud Storage, gerar a configuração openclaw.json e implantar a instância do Cloud Run.
1. Criar um diretório do Terraform
No Cloud Shell, crie um diretório para os arquivos do Terraform e acesse-o:
mkdir openclaw-terraform && cd openclaw-terraform
2. Criar main.tf
Crie um arquivo chamado main.tf. Essa configuração usa o provedor do Google para definir todos os componentes de infraestrutura:
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. Criar variables.tf
Crie um arquivo chamado variables.tf para definir as variáveis de entrada:
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. Criar outputs.tf
Crie um arquivo chamado outputs.tf para expor o URL da instância implantada, a senha do gateway gerada e o nome do bucket de armazenamento:
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. Criar terraform.tfvars
Para conseguir uma chave de API Gemini:
- Acesse o Google AI Studio e faça login com sua Conta do Google.
- Clique em Criar chave de API e selecione seu projeto do Google Cloud.
- Copie a chave de API gerada.
Crie um arquivo chamado terraform.tfvars com as coordenadas do projeto:
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. Implantar infraestrutura com o Terraform
1. Inicializar e aplicar
Inicialize o diretório de trabalho do Terraform e faça o download dos plug-ins do provedor:
terraform init
Implante a infraestrutura:
terraform apply
Quando solicitado, revise os recursos planejados e digite yes para confirmar.
2. Extrair saídas de implantação
Exporte o URL da instância e a senha do gateway gerada do estado do 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. Interagir pela interface da Web e autenticar pelo SSH do Cloud Run
O OpenClaw 2.0+ aplica a autenticação criptográfica de dispositivos. Ao se conectar de um novo navegador, o gateway gera uma solicitação de pareamento que você aprova diretamente pelo SSH nativo das instâncias do Cloud Run.
1. Abra a interface de controle do OpenClaw.
- Abra o
$INSTANCE_URLno navegador da Web. - Quando a autenticação for solicitada, insira a senha do gateway (
$GATEWAY_PASSWORD). - Como esta é uma nova sessão do navegador, a interface de controle do OpenClaw mostra uma solicitação de pareamento de dispositivo pendente com um ID de solicitação (por exemplo:
b56143fc-1654-49da-a1d8-5d40479ddc66). Copie esse ID.
2. Acessar a instância do Cloud Run por SSH
No Cloud Shell, inicie um shell interativo seguro na instância em execução:
gcloud beta run instances ssh openclaw-instance --region=${REGION}
3. Aprovar o pareamento de dispositivos
Na sessão SSH, aprove a solicitação do navegador:
openclaw devices approve <REQUEST_ID> --password ${GATEWAY_PASSWORD}
4. Comandos para o agente (instâncias em ação)
Depois de aprovado, seu navegador se conecta imediatamente ao painel de controle do OpenClaw.
- Teste o agente do OpenClaw enviando um comando na interface de chat, como
"Hello". - Para testar o ciclo de vida de longa duração e o armazenamento persistente da instância do Cloud Run, peça ao agente do OpenClaw para realizar uma tarefa autônoma programada. Por exemplo, peça para ele monitorar um repositório do GitHub em busca de lançamentos e elaborar um resumo:
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. - Como o estado do OpenClaw, os arquivos do espaço de trabalho e os bancos de dados SQLite são mantidos diretamente no Cloud Storage pelo Cloud Storage FUSE, a tarefa programada, o histórico de conversas e os arquivos de resumo gerados sobrevivem a reinicializações de instâncias e upgrades de contêineres.
7. (Opcional) Verificar as integrações de canais de mensagens
Se você configurou o Telegram ou o WhatsApp nas etapas de configuração opcionais acima, verifique a entrega de mensagens:
- Verifique os registros da instância no Cloud Shell:
gcloud beta run instances logs read openclaw-instance --region ${REGION} --limit 20 - Abra o Telegram (ou WhatsApp) e envie uma mensagem (por exemplo,
/startouHello OpenClaw!). - O bot vai autenticar seu ID do usuário com a lista de permissões em
openclaw.jsone responder usando o Gemini.
8. Monitorar e inspecionar registros de instâncias
As instâncias do Cloud Run capturam stdout e stderr do seu contêiner e os transmitem diretamente para o Google Cloud Logging. Use o Cloud Shell ou o console do Cloud para monitorar o tráfego do gateway e inspecionar as execuções de ferramentas do agente em tempo real.
1. Ler registros de instâncias recentes
Para buscar entradas de registro recentes da instância no Cloud Shell:
gcloud beta run instances logs read openclaw-instance \
--region ${REGION} \
--limit 50
2. Assinaturas de registro de chaves para observar
Ao observar o agente em execução, procure os seguintes eventos principais de registro de ambiente de execução:
[gateway] ready: confirma que o gateway HTTP e WebSocket do OpenClaw foi inicializado e está detectando na porta 18789.[gateway] agent model: ...: mostra o modelo do Gemini ativo (por exemplo,google/gemini-3.1-pro-previewougoogle/gemini-3.5-flash).[agents/tool-policy]: mostra as ferramentas permitidas ou restritas de acordo com sua política.[agent/embedded]: rastreia a execução e a invocação de ferramentas pelo agente.
3. Inspecionar registros no console do Google Cloud
Também é possível visualizar e filtrar registros usando a Análise de registros no console do Cloud:
resource.type="cloud_run_instance"
resource.labels.instance_name="openclaw-instance"
9. (Opcional) Ampliar o agente com habilidades
O OpenClaw oferece suporte a Habilidades, que são pacotes de recursos modulares que ensinam ao agente fluxos de trabalho específicos, ferramentas de CLI especializadas e instruções específicas de domínio.
Como as habilidades funcionam
Cada habilidade é um diretório que contém um arquivo SKILL.md. Ele começa com o frontmatter YAML especificando metadados (name e description), seguido por instruções 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: o identificador da habilidade (também pode ser chamado diretamente como um comando de barra, por exemplo,/summarize-logs).description: informa ao modelo do OpenClaw quando invocar automaticamente essa habilidade em uma conversa natural.
Adicionar uma habilidade personalizada ao bucket do Cloud Storage
Como o bucket do Cloud Storage está montado em /mnt/openclaw e configurado em skills.load.extraDirs, as habilidades colocadas em gs://${BUCKET_NAME}/skills/ são carregadas e mantidas automaticamente nas reinicializações da instância:
- Recupere o nome do bucket:
export BUCKET_NAME=$(terraform output -raw storage_bucket) - Criar um diretório de habilidades local:
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 - Faça upload da habilidade para o Cloud Storage:
gcloud storage cp -r my-skill gs://${BUCKET_NAME}/skills/ - Use a habilidade no chat:
- Volte para a interface da Web do OpenClaw Control.
- Agora você pode usar
/summarize-logspara dar comandos ao seu agente ou fazer perguntas em linguagem natural que correspondam à descrição da habilidade.
10. Limpeza
Para evitar cobranças contínuas na sua conta do Google Cloud pelos recursos usados neste codelab, destrua toda a infraestrutura provisionada em uma única etapa usando o Terraform:
- Verifique se você está no diretório
openclaw-terraform:cd openclaw-terraform - Destrua todos os recursos:
terraform destroy - Quando solicitado, revise os recursos que serão removidos e digite
yespara confirmar. O Terraform vai excluir de forma limpa a instância do Cloud Run, os secrets do Secret Manager, as vinculações de política do IAM, a conta de serviço e o bucket do Cloud Storage.
11. Conclusão
Parabéns! Você implantou uma instância segura e totalmente persistente do OpenClaw nas instâncias do Cloud Run usando o Terraform declarativo, com o suporte da persistência de estado do Cloud Storage, da segurança de credenciais do Secret Manager e do SSH nativo das instâncias do Cloud Run para autenticação segura de dispositivos.