AWS ECS¶
This guide covers preparing a Haute pipeline for AWS Elastic Container Service (ECS). haute deploy validates the pipeline, builds its Docker image, pushes it to the configured registry, and finishes there: updating the ECS service is a manual step, because Haute's ECS service-update adapter is not implemented yet.
What is AWS ECS?
ECS is Amazon's service for running Docker containers in the cloud. You don't manage individual servers - AWS handles that. You tell it which Docker image to run and how much compute to allocate, and it keeps your API available. Think of it as a managed hosting service for your pricing API.
Platform service update is not yet implemented
Haute builds the Docker image for AWS ECS, pushes it to your registry, and then finishes without updating the service. The CI deploy job succeeds once the image is pushed and prints the image tag: that tag is the handoff to your IT team, who point the service at it. A registry is required; without one haute deploy stops before building. The generated CI has no smoke-test or impact-analysis job for this target, because nothing runs the new image until the service is updated.
This target requires IT support
AWS ECS involves cloud infrastructure setup (registries, clusters, IAM policies) that is done by an IT or platform team. The "Infrastructure setup" section below is written for your IT team. As an analyst, your role is to configure haute.toml and merge to main - CI and IT handle the rest.
If your organisation uses Databricks, the Databricks target is simpler and doesn't involve containers.
Prerequisites¶
- Python 3.11+ and Haute installed on your machine
- An AWS account with ECS, ECR, and IAM access (your IT team manages this)
- A Haute project initialised with the AWS ECS target - open your VS Code terminal and run:
Your team may have already done this
If you cloned an existing project that already has a haute.toml file, skip this step - it's already initialised.
Before you begin
Your IT team needs to set up the AWS infrastructure first (ECR repository, ECS cluster, IAM credentials). If that hasn't been done yet, send them the Infrastructure setup for IT section at the bottom of this page. Once they've done it, they'll give you the values you need for the steps below.
Step 1: Configure haute.toml¶
[project]
name = "motor-pricing"
pipeline = "rating/main.py"
[deploy]
target = "aws-ecs"
model_name = "motor-pricing"
[deploy.container]
registry = "123456789012.dkr.ecr.eu-west-1.amazonaws.com"
port = 8080
base_image = "python:3.11.9-slim"
[deploy.aws-ecs]
region = "eu-west-1"
cluster = "pricing-cluster"
service = "motor-pricing"
[test_quotes]
dir = "tests/quotes"
What each setting means¶
| Setting | What it does | Example |
|---|---|---|
target |
Tells Haute to deploy to AWS ECS | "aws-ecs" |
registry |
Your ECR repository URI (without the image name) | "123456789012.dkr.ecr.eu-west-1.amazonaws.com" |
port |
The port your API listens on | 8080 |
region |
AWS region where your ECS cluster lives | "eu-west-1" |
cluster |
Name of your ECS cluster | "pricing-cluster" |
service |
Name of your ECS service | "motor-pricing" |
Step 2: Add credentials to CI¶
CI needs registry credentials to push images to ECR. Credentials for a manual ECS service update belong to the tool and process your platform team uses, not to Haute's current adapter.
| Secret name | Value |
|---|---|
DOCKER_USERNAME |
AWS |
DOCKER_PASSWORD |
ECR auth token (CI handles refresh automatically) |
AWS_ACCESS_KEY_ID |
Your AWS access key |
AWS_SECRET_ACCESS_KEY |
Your AWS secret key |
AWS_DEFAULT_REGION |
e.g. eu-west-1 |
How to add them depends on your CI provider - see GitHub Actions, GitLab, or Azure DevOps.
Step 3: Deploy by merging to main¶
You don't run any deploy command. When you merge to main, CI automatically:
- Validates your pipeline and scores test quotes
- Generates a FastAPI app and Dockerfile
- Builds the Docker image
- Pushes the image to your ECR repository
- Finishes without updating the ECS service, printing the pushed image tag
Expected CI result until the adapter exists
The deploy job succeeds once the image is pushed. It does not update ECS.
- In your CI provider - the deploy job is green after the image build and push
- In the CI logs -
Image pushed: 123456789012.dkr.ecr.eu-west-1.amazonaws.com/motor-pricing:a1b2c3d, followed byThe aws-ecs service was not updatedand the tag to point it at
A green deploy job is not an ECS deployment. Your platform team must update the task definition or service, then verify its health. Run haute smoke and haute impact once the service runs the new image.
Use the pushed image tag when your IT team updates the ECS task definition manually, then deploy that new task-definition revision to the service. The command below only starts new tasks from the service's current task definition; it does not replace its image by itself.
aws ecs update-service \
--cluster pricing-cluster \
--service motor-pricing \
--force-new-deployment
Step 4: Test the API¶
Once the service is running, find the endpoint URL in the AWS Console (ECS → Services → your service → Tasks → Public IP or load balancer URL).
import requests
response = requests.post(
"http://<your-endpoint>:8080/quote",
json=[{"IDpol": 99001, "VehPower": 7, "DrivAge": 42, "Area": "C", "VehBrand": "B12"}],
)
print(response.json())
Troubleshooting¶
"Access denied" when pushing to ECR¶
Your AWS credentials don't have permission to push images. Check the IAM policy includes the ECR actions listed in the infrastructure setup section.
ECS service was not updated by Haute¶
If the service does not pick up the new image, first register a task-definition revision whose image is the tag printed by CI, then force the service to use that revision:
aws ecs update-service \
--cluster pricing-cluster \
--service motor-pricing \
--force-new-deployment
Container keeps restarting¶
Check the task logs in the AWS Console: ECS → Clusters → your cluster → Tasks → click the task → Logs. Common causes are missing dependencies or model files.
Health check failing¶
Make sure the health check path is /health and the port matches your haute.toml port setting.
Infrastructure setup (one-time, done by IT)¶
As an analyst, you can skip this section entirely - send this page to whoever manages your AWS account and they'll set things up for you.
1. Create an ECR repository (click to expand)
ECR (Elastic Container Registry) is where Docker images are stored:
Note the repository URI - it looks like:
2. Create an ECS cluster (click to expand)
Or create one in the AWS Console: ECS → Clusters → Create Cluster.
3. Create a task definition and service (click to expand)
This defines how the container runs (CPU, memory, port mappings) and keeps it running. Set this up through the AWS Console or CloudFormation.
Key settings:
- Container port: match the
portinhaute.toml(default 8080) - Health check path:
/health - CPU/Memory: 256 CPU / 512 MB is fine for small workloads
4. Create an IAM user for deployments (click to expand)
Create an IAM user (or role) with permissions to push images and update services:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecs:UpdateService",
"ecs:DescribeServices"
],
"Resource": "*"
}
]
}
Generate an access key for this user and give the Access Key ID and Secret Access Key to whoever is setting up CI secrets.