For the complete documentation index, see llms.txt. This page is also available as Markdown.

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.

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

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)

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

  1. Navigate to VPC Console → Your VPCs

  2. Find the VPC created by the deployment (look for tags with prefix shared)

  3. 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:

Field
Description
How to obtain

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:

  1. ECS Cluster + Service Discovery (ClusterStack)

    • ECS Fargate cluster

    • Cloud Map private namespace (allid.local)

  2. Database (DatabaseStack)

    • Aurora MySQL Serverless v2 cluster

    • Database security group

    • Secrets Manager for credentials (auto-generated)

  3. Load Balancer (LoadBalancerStack)

    • Application Load Balancer (internet-facing)

    • HTTP listener (port 80)

    • Security group with IP whitelisting

  4. 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

  5. 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.

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.

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:

  1. Launch an EC2 instance in a public subnet of your VPC

  2. Configure security groups to allow:

    • SSH access from your IP to the bastion host

    • MySQL access from bastion host to the RDS security group

  3. Connect to the database through SSH tunnel:

Option 2: VPN Connection

If you have a VPN connection configured to your VPC:

  1. Connect to your VPN

  2. 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:

  1. Ensure your bastion host has SSM agent installed

  2. Grant necessary IAM permissions

  3. Create port forwarding session:

Option 4: Temporary Public Access (Development Only)

  1. Temporarily modify the RDS security group to allow your IP

  2. Make the RDS instance publicly accessible (requires modification)

  3. Revert changes after database initialization

Get database endpoint and credentials

Option 1: AWS Console

  1. Navigate to RDS Console → Databases

  2. Find the Aurora cluster (look for name with allid-database)

  3. Copy the Writer endpoint (e.g., allid-database-cluster.cluster-xxx.us-east-1.rds.amazonaws.com)

  4. Navigate to Secrets Manager Console → Secrets

  5. Find the database secret (look for name with allid-database)

  6. 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:

  1. 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)

  2. Create databases:

    • Right-click on connection → SQL Editor → New SQL Script

    • Execute:

  3. Restore dump:

    • Right-click on each database → Tools → Execute Script

    • Select the allid-dump.sql file provided by Certta

    • Click "Start" to execute

Option C: MySQL Workbench (GUI Tool)

Alternative GUI tool for MySQL management:

  1. Create a new connection:

    • Connection Name: All ID Database

    • Hostname: {DB_ENDPOINT}

    • Port: 3306

    • Username: {DB_USERNAME}

    • Password: Store in Keychain/Vault

  2. Create databases:

    • Open connection → Query tab

    • Execute:

  3. Import dump:

    • Server → Data Import

    • Select "Import from Self-Contained File"

    • Choose allid-dump.sql file

    • Select 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:

  1. Login to phpMyAdmin

  2. Create databases using the "New" button

  3. 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

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.

Update certificate secrets for each peer instance:

Option 1: AWS Console (recommended)

  1. Navigate to Secrets Manager Console → Secrets

  2. Find and click on each secret:

    • allid-peer-default-router-certificate

    • allid-peer-client-a-router-certificate

    • allid-peer-client-b-router-certificate

  3. Click "Retrieve secret value" → "Edit"

  4. Update the JSON with your actual certificates:

  1. Save changes

Option 2: AWS CLI

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.

Step 7: Retrieve endpoints

After deployment completes, get the application endpoint:

Option 1: AWS Console

  1. Navigate to EC2 Console → Load Balancers

  2. Find the load balancer (look for name with allid-load-balancer)

  3. 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:

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:

  1. Navigate to ECS Console → Clusters → allid-cluster

  2. Click on "Services" tab

  3. 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:

  1. Navigate to CloudWatch Console → Log groups

  2. Find log groups: /ecs/allid/peer-default, /ecs/allid/facematch, etc.

  3. 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)

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

  • Complete list of Certta Router IP addresses

  • Network segmentation recommendations

  • Secrets management best practices

  • Additional security hardening options

Updating the deployment

Update container images

  1. Update image versions in src/cdk/allid/cdk.json:

  1. Redeploy affected stacks:

Update environment variables

  1. Edit variables in src/cdk/allid/src/constructs/peer-construct.ts

  2. Redeploy 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:

  1. Edit the CDK configuration in src/cdk/allid/src/stacks/peer-stack.ts:

  1. Deploy the updated Peer stack:

The CDK will automatically create the Router certificate secret with placeholder values.

  1. Create and initialize the database for the new peer (see Step 5):

  1. 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:

  1. Verify VPC ID:

    • AWS Console: Navigate to VPC Console → Your VPCs

    • Look for the VPC you want to use and copy its VPC ID

  2. If you don't have a VPC, deploy the shared infrastructure (see Step 2):

  1. Get the VPC ID:

    • AWS Console: VPC Console → Your VPCs → find your VPC

    • AWS CLI: List all VPCs:

  1. Update src/cdk/allid/cdk.json with the correct VPC ID:

  1. Redeploy:

Peer Service won't start

Check CloudWatch Logs:

AWS Console:

  1. CloudWatch Console → Log groups

  2. Find /ecs/allid/peer-default (or peer-client-a, peer-client-b)

  3. Click on latest log stream

  4. Look for error messages in the logs

AWS CLI:

Common causes:

  1. Database not initialized: See Step 5 (database initialization and dump restoration)

  2. Router certificates not updated: See Step 6 (update secrets with real certificates) - the CDK creates secrets with placeholder values that must be replaced

  3. Database connection failed: Check security groups and RDS endpoint

  4. Facematch service unavailable: Check Facematch service status

Check task stopped reason:

AWS Console:

  1. ECS Console → Clusters → allid-cluster

  2. Click on service (e.g., peer-default)

  3. Go to "Tasks" tab → Click on stopped tasks

  4. Check "Stopped reason" field

Health check failures

Check ECS service status:

AWS Console:

  1. ECS Console → Clusters → allid-cluster → Services

  2. Check each service status

  3. Look at "Events" tab for recent messages

Check ALB target health:

AWS Console:

  1. EC2 Console → Target Groups

  2. Find target groups with allid prefix

  3. Click on each target group

  4. Go to "Targets" tab

  5. 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:

  1. EC2 Console → Load Balancers → Find your ALB

  2. Click on "Security" tab

  3. Click on the security group

  4. Check "Inbound rules" - verify your IP is allowed

Add your IP to the allowlist:

  1. Edit src/cdk/allid/src/stacks/load-balancer-stack.ts:

  1. 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:

Create database snapshot before cleanup (optional):

Next steps

Last updated