Skip to content

Drafteame/formae-agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

formae-agent AWS deployment

End-to-end AWS deployment automation for the Formae agent on ECS Express Mode. Provisions and configures all required infrastructure from a single script.

What gets provisioned

Resource Name Notes
Aurora Serverless v2 formae-db PostgreSQL 16.4, Data API enabled
Secrets Manager formae-db-creds DB username + password
Secrets Manager formae-config Rendered Pkl agent config
ECR repository formae Private, mirrors image from GHCR
IAM role formae-ecs-execution Image pull, logs, secret injection
IAM role formae-ecs-infrastructure ALB, networking, auto-scaling managed by ECS
ECS cluster formae
ECS Express service formae-agent Fargate, ALB, 1–4 tasks

Prerequisites

Dev shell

All required tools (aws, docker, pkl, ruby, jq) are provided via the Nix dev shell:

nix develop
# or just cd into the directory if direnv is active

AWS credentials

Configure credentials for the target account before running any script:

export AWS_PROFILE=your-profile
# or use environment variables
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...   # if using temporary credentials

Required environment variables

Variable Required Notes
AWS_ACCOUNT_ID Always 12-digit AWS account ID
AWS_REGION Always Deployment region (e.g. us-east-2)
DB_PASSWORD First install Master password for Aurora. Not needed if SKIP_DB=1
IMAGE_TAG No Image tag to deploy. Defaults to latest

First installation

Run the full setup from scratch:

export AWS_ACCOUNT_ID=123456789012
export AWS_REGION=us-east-2
export DB_PASSWORD=your-secure-password

bash setup.sh

This runs 5 steps in order:

  1. Database — Creates Aurora Serverless v2 cluster formae-db with Data API enabled, and stores credentials in formae-db-creds
  2. Configuration — Renders config/formae.conf.pkl.erb and stores the result in the formae-config secret
  3. ECR — Creates the formae ECR repository, pulls the image from GHCR, and pushes it
  4. IAM — Creates the formae-ecs-execution and formae-ecs-infrastructure roles with the required policies
  5. Deploy — Creates the ECS Express service with an ALB, Fargate tasks, and auto-scaling

On completion, a resource summary is printed with ARNs and AWS console links.

Skip flags

Each step can be skipped independently. Set any of these to a non-empty value:

Flag Skips
SKIP_DB=1 Aurora cluster + credentials secret
SKIP_CONFIGURE=1 Pkl config rendering + secret update
SKIP_ECR=1 ECR repo creation + image push
SKIP_IAM=1 IAM role creation
SKIP_DEPLOY=1 ECS Express service creation

Examples:

# Re-deploy only (all infrastructure already exists)
SKIP_DB=1 SKIP_CONFIGURE=1 SKIP_ECR=1 SKIP_IAM=1 bash setup.sh

# Recreate IAM roles and redeploy (DB, config and image already set)
SKIP_DB=1 SKIP_CONFIGURE=1 SKIP_ECR=1 bash setup.sh

# Set up everything except the service deployment
SKIP_DEPLOY=1 bash setup.sh

Optional overrides

Variable Default Notes
SERVICE_NAME formae-agent ECS Express service name
ECS_CLUSTER formae ECS cluster name
ECS_EXECUTION_ROLE_NAME formae-ecs-execution Execution IAM role name
ECS_INFRA_ROLE_NAME formae-ecs-infrastructure Infrastructure IAM role name

Updating the agent configuration

Use update-config.sh to re-render the Pkl config and apply it to the running service with zero downtime:

export AWS_ACCOUNT_ID=123456789012
export AWS_REGION=us-east-2

bash update-config.sh

This runs 5 steps:

  1. Fetch ARNs — Resolves DB cluster ARN, DB secret ARN, config secret ARN, execution role ARN, and verifies the ECS service is active
  2. Render config — Re-renders config/formae.conf.pkl.erb with current environment variables
  3. Update secret — Pushes the new config to the formae-config Secrets Manager secret
  4. Trigger update — Snapshots the current service revision, then calls update-express-gateway-service to start a rolling deployment
  5. Wait — Polls until activeConfigurations[0].serviceRevisionArn changes and the service status returns to ACTIVE

The service stays available throughout the rolling update.

When to run this

  • Any time a configuration value changes (DB cluster ARN, region, etc.)
  • After rotating the DB credentials secret
  • To force tasks to restart and pick up a new version of the config

Architecture

Config delivery

ECS Express does not support file mounts. The Pkl config is stored in Secrets Manager and injected as the FORMAE_CONFIG environment variable at task startup. The container command writes it to disk:

printenv FORMAE_CONFIG > /tmp/formae.conf.pkl && formae agent start --config /tmp/formae.conf.pkl

ECS Express service

Setting Value
Launch type Fargate
Container port 49684
Health check GET /api/v1/health
Min tasks 1
Max tasks 4
Auto-scaling metric Average CPU at 60%
Ingress Public ALB (HTTPS)

IAM roles

formae-ecs-execution (task execution + runtime role):

  • AmazonECSTaskExecutionRolePolicy — ECR image pull, CloudWatch logs
  • PowerUserAccess — infrastructure operations
  • Inline policy — read access to the formae-config Secrets Manager secret

formae-ecs-infrastructure (ECS-managed infrastructure):

  • AmazonECSInfrastructureRoleforExpressGatewayServices — ALB, target groups, security groups, auto-scaling

Database

Aurora Serverless v2 with the Data API (--enable-http-endpoint) allows the agent to query the database over HTTPS without VPC connectors or NAT gateways.

Setting Value
Engine PostgreSQL 16.4
Instance class db.serverless
Min capacity 0.5 ACU
Max capacity 2.0 ACU
Database name formae
DB user postgres

Config templates

All .erb files under config/ are rendered with Ruby's erb. Rendered outputs are git-ignored.

Template Output Purpose
formae.conf.pkl.erb formae.conf.pkl Agent Pkl config (DB ARNs, region)
ecs-primary-container.json.erb ecs-primary-container.json ECS container definition
ecs-execution-policy.json.erb ecs-execution-policy.json IAM inline policy for secret access
formae-data-api-policy.json.erb formae-data-api-policy.json IAM policy for Aurora Data API

Render a template manually:

erb config/formae.conf.pkl.erb > config/formae.conf.pkl

Verifying the deployment

# Health check
curl -s -o /dev/null -w "%{http_code}" https://$SERVICE_URL/api/v1/health
# Expected: 200

The service URL is printed at the end of both setup.sh and update-config.sh.

About

Formae agent deployment configuration for ECS Express Mode

Resources

Stars

Watchers

Forks

Releases

No releases published

Contributors