Skip to main content
Guava agents can run on Amazon ECS using Fargate. The Expert opens an outbound WebSocket connection to Guava, so it runs as a plain ECS service. You don’t need a load balancer, inbound ports, or a public endpoint. This guide shows the AWS infrastructure three ways: the AWS CDK, Terraform, and AWS CLI commands. Pick one. They all create the same resources.

At a Glance

  1. Containerize your agent with a Dockerfile.
  2. Store your Guava API key in AWS Secrets Manager.
  3. (Skip if adding to an existing ECS application) Create an ECR repository, an execution role, and an ECS cluster.
  4. Create a Fargate task definition and an ECS service with no load balancer.
  5. Push your image and let ECS start the tasks.

Prerequisites

  • An AWS account, and the AWS CLI configured with credentials
  • Docker and uv
  • Terraform or Node.js (for the AWS CDK), if you’re using either
  • A Guava phone number for your agent

Define your agent

Define your agent in agent.py. The phone number comes from the environment, so the same image can be deployed for any number. agent.listen_phone(...) connects your agent to the phone number and does not exit.
agent.py
If your project doesn’t have a pyproject.toml yet, create one with uv.
terminal
Add guava-sdk as a dependency. This updates pyproject.toml and uv.lock, which the Dockerfile installs from.
terminal

Containerize your agent

Add a Dockerfile and a .dockerignore to your project root.
Dockerfile
.dockerignore
requires-python in pyproject.toml must allow the Python version in FROM python:…. If it doesn’t, the build fails.
Fargate tasks in this guide run on x86_64, so images are built with --platform linux/amd64. Without it, images built on Apple Silicon Macs won’t start on Fargate.

Store your Guava API key

Open the API Keys page in the Guava dashboard and click Create API Key. The key has the form gva-.... Store it in AWS Secrets Manager. This command and all the following ones use your AWS CLI’s configured region, so make sure it’s the region you want to deploy to.
terminal
Copy the ARN from the output. ECS reads the secret when each task starts and passes it to your agent as the GUAVA_API_KEY environment variable, so the key never appears in your task definition.

Provision the infrastructure

Each option below creates:
  • An ECR repository for your agent’s image
  • A CloudWatch log group for your agent’s logs
  • An execution role that pulls the image, writes logs, and reads the API key
  • An ECS cluster and a Fargate task definition (1 vCPU, 2 GB)
  • An ECS service that runs two tasks in your default VPC’s public subnets, with a security group that only allows outbound traffic
Create a CDK app in an infra/ directory in your project.
terminal
Replace the contents of infra/bin/infra.ts with the following stack. The CDK builds your Dockerfile and pushes the image for you, so you don’t need to create an ECR repository yourself.
infra/bin/infra.ts
Bootstrap your account. You only need to do this once per account and region.
terminal
Deploy the stack.
terminal
For production, consider running tasks in private subnets with a NAT gateway and turning off public IP assignment. The agent only needs outbound access to Guava and to any APIs it calls.

Call your agent

Tail your agent’s logs. Once each task logs that it started listening on your phone number, you can call your agent.
terminal
Both tasks listen on the same phone number, and each incoming call is handled by one of them. If a task stops, the other keeps taking calls while ECS starts a replacement.

Deploying updates

Run cdk deploy again. The CDK rebuilds the image, pushes it, and registers a new task definition revision.
terminal
ECS performs a rolling deployment. It starts new tasks and stops old ones only while at least two healthy tasks stay running.

Graceful shutdown and health checks

When ECS stops a task, it sends SIGTERM. The Guava SDK responds by draining: it stops accepting new calls and lets in-flight calls finish, while the other tasks pick up new calls. The task definition sets stopTimeout to 120 seconds, the Fargate maximum, which is how long ECS waits before force-stopping the container. Setting GUAVA_HEALTH_SERVER=true starts a health check server inside the container on port 4828: The container health check uses /live. Don’t use /ready for it: /ready returns 503 while a task drains, so ECS would mark tasks unhealthy while they are still finishing calls.

Clean up

From infra/, destroy the stack. The CDK bootstrap stack (CDKToolkit) stays, since every CDK app in the account and region shares it.
terminal
The API key secret isn’t part of any of these. To delete it, use --force-delete-without-recovery. Otherwise Secrets Manager keeps the guava/api-key name reserved for 7 to 30 days.
terminal