At a Glance
- Containerize your agent with a Dockerfile.
- Store your Guava API key in AWS Secrets Manager.
- (Skip if adding to an existing ECS application) Create an ECR repository, an execution role, and an ECS cluster.
- Create a Fargate task definition and an ECS service with no load balancer.
- 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 inagent.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
pyproject.toml yet, create one with uv.
terminal
guava-sdk as a dependency. This updates pyproject.toml and uv.lock, which the Dockerfile installs from.
terminal
Containerize your agent
Add aDockerfile 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 formgva-.... 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
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
- AWS CDK
- Terraform
- AWS CLI
Create a CDK app in an Replace the contents of Bootstrap your account. You only need to do this once per account and region.Deploy the stack.
infra/ directory in your project.terminal
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
terminal
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
Deploying updates
- AWS CDK
- Terraform
- AWS CLI
Run
cdk deploy again. The CDK rebuilds the image, pushes it, and registers a new task definition revision.terminal
Graceful shutdown and health checks
When ECS stops a task, it sendsSIGTERM. 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
- AWS CDK
- Terraform
- AWS CLI
From
infra/, destroy the stack. The CDK bootstrap stack (CDKToolkit) stays, since every CDK app in the account and region shares it.terminal
--force-delete-without-recovery. Otherwise Secrets Manager keeps the guava/api-key name reserved for 7 to 30 days.
terminal