This guide assumes you already have:
- An ECS cluster
- VPC with subnets
- Security groups configured (must allow inbound traffic on port 8080 or your container port)
- (Optional) Application Load Balancer with target group
- For direct access (no load balancer): Allow inbound traffic on port 8080 (or
CONTAINER_PORT) from your IP or0.0.0.0/0 - For load balancer: Allow inbound traffic from the load balancer’s security group
Deployment Methods
Choose your preferred deployment method:- Using Makefile
- Using AWS CLI
- Using CloudFormation
Quick Start with Makefile
The easiest way to deploy Bifrost to ECS is using the provided Makefile.First-time deployment? If you don’t know your VPC ID or network configuration, run:This will list all available VPCs, subnets, and security groups in your AWS region.
Available Makefile Parameters
| Parameter | Default | Description |
|---|---|---|
ECS_CLUSTER_NAME | bifrost-cluster | Name of the ECS cluster |
ECS_SERVICE_NAME | bifrost-service | Name of the ECS service |
ECS_TASK_FAMILY | bifrost-task | Task definition family name |
IMAGE_TAG | latest | Bifrost Docker image tag |
LAUNCH_TYPE | FARGATE | Launch type: FARGATE or EC2 |
SECRET_BACKEND | secretsmanager | Secret storage: secretsmanager or ssm |
AWS_REGION | us-east-1 | AWS region |
VPC_ID | (optional*) | VPC ID (auto-fetches all subnets in VPC) |
SUBNET_IDS | (optional*) | Comma-separated subnet IDs (if VPC_ID not provided) |
SECURITY_GROUP_IDS | (required) | Comma-separated security group IDs |
TARGET_GROUP_ARN | (optional) | ALB target group ARN |
CONTAINER_PORT | 8080 | Container port |
SECRET_NAME | bifrost/config | Secret/parameter name |
CONFIG_JSON_FILE | (optional) | Path to config.json file |
SECRET_ARN | (optional) | Existing secret ARN (skip auto-lookup) |
EXECUTION_ROLE_ARN | (optional) | ECS task execution role ARN |
TASK_ROLE_ARN | (optional) | ECS task role ARN |
Network Configuration (*):
You must provide either
You must provide either
VPC_ID OR SUBNET_IDS:- VPC_ID (recommended): Automatically fetches all subnets in the VPC. Simpler and works across all availability zones.
- SUBNET_IDS: Specify exact subnet IDs if you want fine-grained control over subnet placement.
Makefile Targets
list-ecs-network-resources: List available VPCs, subnets and security groups in your AWS region (helpful for first deployment)deploy-ecs: Complete deployment (creates secret if CONFIG_JSON_FILE provided, registers task definition, creates service, waits for stabilization, and shows deployment status)create-ecs-secret: Create/update configuration secret (requires CONFIG_JSON_FILE parameter)register-ecs-task-definition: Register new task definition (with or without secret)create-ecs-service: Create or update ECS serviceupdate-ecs-service: Force new deploymenttail-ecs-logs: Continuously tail CloudWatch logs in real-time (Ctrl+C to exit)ecs-status: Show current service status, running tasks, and recent logsget-ecs-url: Get the public URL/IP to access the service (works with or without load balancer)cleanup-ecs: Remove service and deregister task definitions
CONFIG_JSON_FILE Parameter: This is optional. If provided, the Makefile will create a secret in AWS Secrets Manager or SSM Parameter Store and mount it in the ECS task. If omitted, the task will be deployed without a secret, and you can use other configuration methods (environment variables, mounted volumes, etc.).How Configuration Secrets Work: When
CONFIG_JSON_FILE is provided, the deployment:- Stores your
config.jsonin AWS Secrets Manager or SSM Parameter Store - Injects the secret as an environment variable
BIFROST_CONFIGinto the container - Uses a custom entrypoint that:
- Silently writes the secret content to
/app/data/config.json - Exits with error only if
BIFROST_CONFIGis not set - Then starts Bifrost normally
- Silently writes the secret content to
- Bifrost reads the configuration from the file at startup
IAM Permissions
Task Execution Role
The task execution role (ecsTaskExecutionRole) needs the following permissions:
The Makefile automatically creates the CloudWatch log group
/ecs/bifrost-task, so the execution role only needs CreateLogStream and PutLogEvents permissions, not CreateLogGroup.- For Secrets Manager
- For SSM Parameter Store
Accessing Your Service
Without Load Balancer
When deployed without a load balancer, the ECS task gets a public IP address. You can find it using AWS CLI:Important Notes:
- The public IP changes every time the task is restarted
- You must allow inbound traffic on port 8080 (or your
CONTAINER_PORT) in your security group - For production, consider using an Application Load Balancer for a stable endpoint
With Load Balancer
If you deployed withTARGET_GROUP_ARN, your service is accessible via the load balancer’s DNS name:
- ✅ Stable DNS endpoint
- ✅ SSL/TLS termination (if configured)
- ✅ Health checks with automatic failover
- ✅ Multiple task load balancing
Monitoring and Logs
Tail Logs (Makefile)
The easiest way to monitor your deployment logs:The
deploy-ecs command automatically waits for the deployment to stabilize and shows you:- Deployment status (running/desired count)
- Task details (ARN, status, health)
- Recent logs (last 20 events)
make tail-ecs-logs to continuously monitor your application.
