AWS ECS (CDK)
Complete guide for deploying All ID on AWS ECS Fargate using CDK.
Overview
This guide explains how to deploy All ID using the AWS CDK (Cloud Development Kit) Infrastructure as Code.
The deployment requires:
All ID Application CDK (
allid/) - Application services (ECS, RDS, ALB)Existing VPC - You must provide a VPC ID in the CDK context
Network Requirements: The All ID CDK requires an existing VPC with public, private, and isolated subnets. If you don't have a VPC yet, Certta provides a reference CDK project (shared/) that creates a production-ready network infrastructure.
Certta will provide you with a package containing:
All ID CDK project (required)
Reference network infrastructure CDK project (optional, use if you need to create a new VPC)
Configuration examples and documentation
Prerequisites
Before deploying, ensure you have:
Tools:
Node.js >= 18.x
AWS CLI configured with credentials
AWS CDK >= 2.x (
npm install -g aws-cdk)
AWS Account:
AWS account with appropriate permissions
Permissions to create: ECS, RDS, ALB, CloudFormation, IAM roles, Security Groups
AWS credentials configured (
aws configure)
Network Infrastructure:
Existing VPC ID with:
Public subnets (minimum 2 AZs) for Application Load Balancer
Private subnets (minimum 2 AZs) for ECS services
Isolated subnets (minimum 2 AZs) for RDS database
Internet Gateway and NAT Gateway configured
Don't have a VPC? Certta provides a reference CDK project that creates all required network infrastructure. See Step 2: Network Infrastructure below.
Container Images:
Access to Certta's private container registry
ECR repository URIs for Peer and Facematch images
Image versions/tags to deploy
Important: Contact your Certta technical account manager to obtain:
CDK project files (All ID + optional network infrastructure)
Container registry credentials and image URIs
Router Service certificates for mTLS communication
Project structure
Certta will provide you with CDK project files. The package structure:
Shared infrastructure is optional: Only deploy if you need to create a new VPC. If you already have a VPC, skip the shared/ project and configure your VPC ID in src/cdk/allid/cdk.json.
Step 1: Extract CDK project
Extract the CDK project files provided by Certta:
Step 2: Network infrastructure (optional)
Skip this step if you already have a VPC. Only deploy the shared infrastructure if you need to create a new VPC.
If you need to create a new VPC, deploy the reference network infrastructure:
What gets deployed:
VPC with environment-specific CIDR blocks
2 Public subnets (across 2 availability zones)
2 Private subnets (across 2 availability zones)
2 Isolated subnets (across 2 availability zones) for databases
Internet Gateway for public internet access
NAT Gateway for private subnet outbound access
VPC Endpoints for AWS services (S3, ECR, CloudWatch, Secrets Manager)
Deployment time: ~5-10 minutes
After deployment, get the VPC ID:
Option 1: AWS Console
Navigate to VPC Console → Your VPCs
Find the VPC created by the deployment (look for tags with prefix
shared)Copy the VPC ID (format:
vpc-xxxxxxxxxxxxx)
Option 2: AWS CLI
Save this VPC ID - you'll need it in the next step.
Step 3: Configure CDK context
Edit src/cdk/allid/cdk.json to configure your deployment:
Update the context section with your environment-specific values:
Configuration values to update:
vpc-id
Your VPC ID
From Step 2 (if deployed shared) or your existing VPC
peer-ecr-repository-uri
Peer Service container registry
Provided by Certta
peer-version
Peer image tag to deploy
Provided by Certta (e.g., latest, commit hash)
facematch-ecr-repository-uri
Facematch container registry
Provided by Certta
facematch-version
Facematch image tag to deploy
Provided by Certta (e.g., latest, commit hash)
router-rest-url
Certta Router endpoint for your region/env
Provided by Certta
Multiple environments: You can configure multiple environments (dev, stg, prd) in the same cdk.json file. The CDK will use the context based on the region and environment variables.
Step 4: Deploy All ID application
Deploy the All ID application services:
What gets deployed:
ECS Cluster + Service Discovery (
ClusterStack)ECS Fargate cluster
Cloud Map private namespace (
allid.local)
Database (
DatabaseStack)Aurora MySQL Serverless v2 cluster
Database security group
Secrets Manager for credentials (auto-generated)
Load Balancer (
LoadBalancerStack)Application Load Balancer (internet-facing)
HTTP listener (port 80)
Security group with IP whitelisting
Facematch Service (
FacematchStack)ECS Task Definition (CPU: 1024, Memory: 2048 MB)
Fargate Service with 2 instances
Cloud Map service registration (
facematch.allid.local)Security group for internal communication
Peer Services (
PeerStack)Creates 3 peer instances (default, client-a, client-b)
Each peer has:
ECS Task Definition (CPU: 256, Memory: 512 MB)
Fargate Service with 1 instance
ALB target group with path-based routing
Cloud Map service registration
Database connection to RDS
Router mTLS certificate secret (placeholder)
Deployment time: ~15-20 minutes
The CDK automatically handles stack dependencies and deploys them in the correct order: cluster → database → load-balancer → facematch → peer.
Important: After deployment, the Peer Services will initially fail to start. You must complete Steps 5 and 6 (database initialization and Router certificates update) to make them operational. The services will automatically restart and become healthy once these steps are completed.
Step 5: Initialize database
The Peer Service requires a database schema to be initialized. Certta will provide a SQL dump file that must be restored to the Aurora MySQL database.
Critical: The Peer Services are currently failing to start because the database schema is not initialized. Complete this step to allow the services to become operational.
Multi-tenant setup: Each peer instance uses its own database. The database names follow the pattern peer-{name}:
peer-default(for default peer)peer-client-a(for client-a peer)peer-client-b(for client-b peer)
Database access methods
The Aurora MySQL database is deployed in isolated subnets with no direct internet access. You need to establish a secure connection to access it.
Option 1: Bastion Host (Recommended for production)
Deploy a bastion host (EC2 instance) in a public subnet to act as a jump server:
Launch an EC2 instance in a public subnet of your VPC
Configure security groups to allow:
SSH access from your IP to the bastion host
MySQL access from bastion host to the RDS security group
Connect to the database through SSH tunnel:
Option 2: VPN Connection
If you have a VPN connection configured to your VPC:
Connect to your VPN
Access the database directly using its private endpoint
Option 3: AWS Systems Manager Session Manager
Use Session Manager for secure access without exposing SSH ports:
Ensure your bastion host has SSM agent installed
Grant necessary IAM permissions
Create port forwarding session:
Option 4: Temporary Public Access (Development Only)
Not recommended for production: Only use this method for development/testing environments.
Temporarily modify the RDS security group to allow your IP
Make the RDS instance publicly accessible (requires modification)
Revert changes after database initialization
Get database endpoint and credentials
Option 1: AWS Console
Navigate to RDS Console → Databases
Find the Aurora cluster (look for name with
allid-database)Copy the Writer endpoint (e.g.,
allid-database-cluster.cluster-xxx.us-east-1.rds.amazonaws.com)Navigate to Secrets Manager Console → Secrets
Find the database secret (look for name with
allid-database)Click "Retrieve secret value" to see username and password
Option 2: AWS CLI
Create and initialize databases
You can use any of the following tools to create databases and restore the dump:
Option A: MySQL Command Line Client
Best for automation and CI/CD pipelines:
Option B: DBeaver (GUI Tool)
Recommended for visual database management:
Create a new connection:
Database: MySQL
Host:
{DB_ENDPOINT}(from above)Port: 3306
Username:
{DB_USERNAME}(from Secrets Manager)Password:
{DB_PASSWORD}(from Secrets Manager)
Create databases:
Right-click on connection → SQL Editor → New SQL Script
Execute:
Restore dump:
Right-click on each database → Tools → Execute Script
Select the
allid-dump.sqlfile provided by CerttaClick "Start" to execute
Option C: MySQL Workbench (GUI Tool)
Alternative GUI tool for MySQL management:
Create a new connection:
Connection Name:
All ID DatabaseHostname:
{DB_ENDPOINT}Port: 3306
Username:
{DB_USERNAME}Password: Store in Keychain/Vault
Create databases:
Open connection → Query tab
Execute:
Import dump:
Server → Data Import
Select "Import from Self-Contained File"
Choose
allid-dump.sqlfileSelect target database (repeat for each: peer-default, peer-client-a, peer-client-b)
Click "Start Import"
Option D: phpMyAdmin (Web Interface)
If you have phpMyAdmin deployed in your environment:
Login to phpMyAdmin
Create databases using the "New" button
Select each database and use the "Import" tab to upload and execute the SQL dump file
Connection troubleshooting: If you cannot connect to the database, ensure:
You have established proper access (bastion host, VPN, or Session Manager)
The RDS security group allows connections from your source
The database endpoint and credentials are correct
Critical: Each Peer Service will fail to start if its corresponding database is not initialized. Contact your Certta technical account manager to obtain the SQL dump file.
Step 6: Update Router mTLS certificates
The Peer Services require mTLS certificates to communicate with Certta's Router Service. The CDK automatically created placeholder secrets during deployment. You must update these secrets with the actual certificates before the Peer Services can start successfully.
Placeholder values: The CDK created secrets with placeholder text REPLACE_WITH_ACTUAL_PRIVATE_KEY and REPLACE_WITH_ACTUAL_CERTIFICATE. The Peer Services are failing to start until you replace these with real certificates.
Update certificate secrets for each peer instance:
Option 1: AWS Console (recommended)
Navigate to Secrets Manager Console → Secrets
Find and click on each secret:
allid-peer-default-router-certificateallid-peer-client-a-router-certificateallid-peer-client-b-router-certificate
Click "Retrieve secret value" → "Edit"
Update the JSON with your actual certificates:
Save changes
Option 2: AWS CLI
Critical: Contact your Certta technical account manager to obtain:
mTLS certificate files (private key and certificate) for your environment
Proper formatting instructions for the certificates
Certificate formatting: If you have certificate files (.pem or .key files), you need to format them for JSON by replacing newlines with \n. The AWS Console handles this automatically when you paste multi-line certificates in plain text mode.
For CLI users, you can use text processing tools like awk or sed to format the certificates, or use the console for easier management.
Services will auto-recover: Once you update the certificates, the Peer Services will automatically restart and become healthy within a few minutes. ECS will detect the configuration change and redeploy the tasks.
Step 7: Retrieve endpoints
After deployment completes, get the application endpoint:
Option 1: AWS Console
Navigate to EC2 Console → Load Balancers
Find the load balancer (look for name with
allid-load-balancer)Copy the DNS name (e.g.,
allid-load-balancer-123456789.us-east-1.elb.amazonaws.com)
Option 2: AWS CLI
The deployment creates 3 peer instances with path-based routing for multi-tenant support. Each peer has its own isolated endpoint with path prefix.
API endpoints (3 peer instances by default):
Health check endpoints:
To add/remove peers, edit src/cdk/allid/src/stacks/peer-stack.ts and modify the peerConfigs array. Remember to create the corresponding database and update the Router certificate secret for new peers BEFORE deploying.
Step 8: Validate deployment
Test that all services are healthy:
Test peer endpoints (using ALB DNS from Step 7):
All endpoints should return HTTP 200 with status information.
Check ECS services status:
AWS Console:
Navigate to ECS Console → Clusters →
allid-clusterClick on "Services" tab
Verify all services show "Running" status and desired count matches running count
AWS CLI:
All services should show runningCount matching desiredCount.
Check CloudWatch Logs (if services fail to start):
AWS Console:
Navigate to CloudWatch Console → Log groups
Find log groups:
/ecs/allid/peer-default,/ecs/allid/facematch, etc.Check recent log streams for errors
AWS CLI:
Architecture overview
Network layers
The deployment creates a three-tier network architecture:
Service communication
Path-based routing (multi-tenant)
The ALB uses path-based routing to support multiple peer instances:
Each peer instance:
Has its own ECS service
Has its own isolated database (peer-default, peer-client-a, peer-client-b)
Operates independently from other peers
Shares the same Facematch service pool
Configuration management
The CDK project automatically configures environment variables and secrets for all services.
Environment variables are defined in src/cdk/allid/src/constructs/peer-construct.ts and include:
Database connection (host, port, database name)
Facematch service endpoint
Router Service URL
Feature flags (RabbitMQ, Redis, Router communication)
Secrets are injected via ECS task secrets and include:
Database credentials (auto-generated by CDK)
Router mTLS certificates (created with placeholders, must be updated manually)
See Configuration for complete list of environment variables, required values, and configuration details.
Secrets management
The CDK automatically creates secrets in AWS Secrets Manager:
Secret naming convention:
Database credentials:
allid-database-secret-<random-suffix>Router certificates:
allid-peer-{name}-router-certificate(e.g.,allid-peer-default-router-certificate)
Router certificate secrets are created with placeholder values during deployment. You must update them with real certificates before the Peer Services can start successfully (see Step 6).
Security
The CDK automatically configures security groups and IP whitelisting following least-privilege principles.
Security groups:
ALB accepts traffic only from whitelisted IPs
Peer Services accept traffic only from ALB and internal VPC
Facematch accepts traffic only from Peer Services
Database accepts traffic only from Peer Services
IP whitelisting:
ALB is configured to accept traffic only from Certta Router IP addresses
Configure additional IPs in
src/cdk/allid/src/stacks/load-balancer-stack.ts
See Security Best Practices for:
Complete list of Certta Router IP addresses
Network segmentation recommendations
Secrets management best practices
Additional security hardening options
Updating the deployment
Update container images
Update image versions in
src/cdk/allid/cdk.json:
Redeploy affected stacks:
Update environment variables
Edit variables in
src/cdk/allid/src/constructs/peer-construct.tsRedeploy the Peer stack:
This will update all peer instances (default, client-a, client-b) with the new configuration.
Scale services
Scale Peer Services: Edit desired count in src/cdk/allid/src/constructs/peer-construct.ts:
Then redeploy:
Scale Facematch Service: Edit desired count in src/cdk/allid/src/stacks/facematch-stack.ts:
Then redeploy:
Add/remove peer instances
To add a new peer instance:
Edit the CDK configuration in
src/cdk/allid/src/stacks/peer-stack.ts:
Deploy the updated Peer stack:
The CDK will automatically create the Router certificate secret with placeholder values.
Create and initialize the database for the new peer (see Step 5):
Update the Router certificate secret with real certificates (see Step 6):
The new Peer Service will fail to start initially (like in the initial deployment), but will automatically become healthy after you complete steps 3 and 4 (database initialization and certificate update).
Troubleshooting
Deployment fails with "VPC not found"
Cause: VPC ID not configured correctly in cdk.json or VPC doesn't exist.
Solution:
Verify VPC ID:
AWS Console: Navigate to VPC Console → Your VPCs
Look for the VPC you want to use and copy its VPC ID
If you don't have a VPC, deploy the shared infrastructure (see Step 2):
Get the VPC ID:
AWS Console: VPC Console → Your VPCs → find your VPC
AWS CLI: List all VPCs:
Update
src/cdk/allid/cdk.jsonwith the correct VPC ID:
Redeploy:
Peer Service won't start
Check CloudWatch Logs:
AWS Console:
CloudWatch Console → Log groups
Find
/ecs/allid/peer-default(or peer-client-a, peer-client-b)Click on latest log stream
Look for error messages in the logs
AWS CLI:
Common causes:
Database not initialized: See Step 5 (database initialization and dump restoration)
Router certificates not updated: See Step 6 (update secrets with real certificates) - the CDK creates secrets with placeholder values that must be replaced
Database connection failed: Check security groups and RDS endpoint
Facematch service unavailable: Check Facematch service status
Check task stopped reason:
AWS Console:
ECS Console → Clusters → allid-cluster
Click on service (e.g., peer-default)
Go to "Tasks" tab → Click on stopped tasks
Check "Stopped reason" field
Health check failures
Check ECS service status:
AWS Console:
ECS Console → Clusters → allid-cluster → Services
Check each service status
Look at "Events" tab for recent messages
Check ALB target health:
AWS Console:
EC2 Console → Target Groups
Find target groups with
allidprefixClick on each target group
Go to "Targets" tab
Check health status of registered targets (should be "healthy")
AWS CLI:
Common issues:
Security groups blocking traffic between ALB and Peer Services
Service not registered in Cloud Map (DNS resolution fails)
Database connection errors (check credentials secret)
Facematch service not responding
Can't access ALB
Check if your IP is whitelisted:
If you get connection timeout or 403 Forbidden, your IP is not whitelisted.
Check ALB security group:
AWS Console:
EC2 Console → Load Balancers → Find your ALB
Click on "Security" tab
Click on the security group
Check "Inbound rules" - verify your IP is allowed
Add your IP to the allowlist:
Edit
src/cdk/allid/src/stacks/load-balancer-stack.ts:
Redeploy:
See Security Best Practices for the complete list of Certta Router IP addresses that should be whitelisted.
Cleanup
To remove all resources and stop incurring costs:
Warning: This permanently deletes all resources including:
Aurora MySQL database and all data
CloudWatch logs
Secrets Manager secrets (database credentials, Router certificates)
ECS services and tasks
Ensure you have backups before destroying. Database snapshots are NOT automatically created during destroy.
Create database snapshot before cleanup (optional):
Next steps
Review Technical Requirements for resource specifications
Review Configuration for environment variable details
Review Security Best Practices for hardening
Last updated

