Skip to content

ECS

Deploy DeepIntShield on AWS ECS using either Makefile automation or direct AWS CLI commands. This guide covers both Fargate and EC2 launch types, with options for managing configuration secrets.

Choose your preferred deployment method:

The easiest way to deploy DeepIntShield to ECS is using the provided Makefile.

Terminal window
# First, create your config.json file with your DeepIntShield configuration
cat > /tmp/deepintshield-config.json <<EOF
{
"config_store": {
"enabled": true,
"type": "postgres",
"config": {
"host": "your-db-host",
"port": "5432",
"user": "your-db-user",
"password": "your-db-password",
"db_name": "deepintshield",
"ssl_mode": "disable"
}
},
"logs_store": {
"enabled": true,
"type": "postgres",
"config": {
"host": "your-db-host",
"port": "5432",
"user": "your-db-user",
"password": "your-db-password",
"db_name": "deepintshield",
"ssl_mode": "disable"
}
}
}
EOF
# Deploy with VPC ID (recommended - auto-fetches all subnets)
make deploy-ecs \
VPC_ID='vpc-xxx' \
SECURITY_GROUP_IDS='sg-xxx' \
CONFIG_JSON_FILE='/tmp/deepintshield-config.json'
# Deploy with specific subnet IDs
make deploy-ecs \
SUBNET_IDS='subnet-xxx,subnet-yyy' \
SECURITY_GROUP_IDS='sg-xxx' \
CONFIG_JSON_FILE='/tmp/deepintshield-config.json'
# Deploy with EC2 launch type and SSM Parameter Store
make deploy-ecs \
LAUNCH_TYPE=EC2 \
SECRET_BACKEND=ssm \
VPC_ID='vpc-xxx' \
SECURITY_GROUP_IDS='sg-xxx' \
CONFIG_JSON_FILE='/tmp/deepintshield-config.json'
# Deploy with Application Load Balancer
make deploy-ecs \
VPC_ID='vpc-xxx' \
SECURITY_GROUP_IDS='sg-xxx' \
TARGET_GROUP_ARN='arn:aws:elasticloadbalancing:...' \
CONFIG_JSON_FILE='/tmp/deepintshield-config.json'
# Deploy without configuration secret
make deploy-ecs \
VPC_ID='vpc-xxx' \
SECURITY_GROUP_IDS='sg-xxx'
ParameterDefaultDescription
ECS_CLUSTER_NAMEdeepintshield-clusterName of the ECS cluster
ECS_SERVICE_NAMEdeepintshield-serviceName of the ECS service
ECS_TASK_FAMILYdeepintshield-taskTask definition family name
IMAGE_TAGlatestDeepIntShield Docker image tag
LAUNCH_TYPEFARGATELaunch type: FARGATE or EC2
SECRET_BACKENDsecretsmanagerSecret storage: secretsmanager or ssm
AWS_REGIONus-east-1AWS 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_PORT8080Container port
SECRET_NAMEdeepintshield/configSecret/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
  • 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 service
  • update-ecs-service: Force new deployment
  • tail-ecs-logs: Continuously tail CloudWatch logs in real-time (Ctrl+C to exit)
  • ecs-status: Show current service status, running tasks, and recent logs
  • get-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

The task execution role (ecsTaskExecutionRole) needs the following permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:log-group:/ecs/deepintshield-task:*"
},
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:us-east-1:YOUR_ACCOUNT_ID:secret:deepintshield/config*"
}
]
}

When deployed without a load balancer, the ECS task gets a public IP address. You can find it using AWS CLI:

Terminal window
# Get the public IP address of your running task
aws ec2 describe-network-interfaces \
--network-interface-ids $(aws ecs describe-tasks \
--cluster deepintshield-cluster \
--tasks $(aws ecs list-tasks \
--cluster deepintshield-cluster \
--service-name deepintshield-service \
--region us-east-1 \
--query 'taskArns[0]' \
--output text) \
--region us-east-1 \
--query 'tasks[0].attachments[0].details[?name==`networkInterfaceId`].value' \
--output text) \
--region us-east-1 \
--query 'NetworkInterfaces[0].Association.PublicIp' \
--output text

Testing your deployment:

Terminal window
# Test health endpoint (replace YOUR_PUBLIC_IP with the IP from above)
curl http://YOUR_PUBLIC_IP:8080/health
# Expected response
{"status":"ok"}

If you deployed with TARGET_GROUP_ARN, your service is accessible via the load balancer’s DNS name:

Terminal window
# Get the load balancer DNS name (replace YOUR_TARGET_GROUP_ARN with your actual ARN)
aws elbv2 describe-load-balancers \
--load-balancer-arns $(aws elbv2 describe-target-groups \
--target-group-arns YOUR_TARGET_GROUP_ARN \
--region us-east-1 \
--query 'TargetGroups[0].LoadBalancerArns[0]' \
--output text) \
--region us-east-1 \
--query 'LoadBalancers[0].DNSName' \
--output text
# Test via load balancer (replace YOUR_ALB_DNS with the DNS from above)
curl http://YOUR_ALB_DNS/health

The load balancer provides:

  • ✅ Stable DNS endpoint
  • ✅ SSL/TLS termination (if configured)
  • ✅ Health checks with automatic failover
  • ✅ Multiple task load balancing

The easiest way to monitor your deployment logs:

Terminal window
# Tail logs in real-time (press Ctrl+C to exit)
make tail-ecs-logs
# Check service status and recent logs
make ecs-status
Terminal window
# Tail logs using AWS CLI v2 (recommended)
aws logs tail /ecs/deepintshield-task --follow --region us-east-1
# Get log stream names
aws logs describe-log-streams \
--log-group-name /ecs/deepintshield-task \
--order-by LastEventTime \
--descending \
--max-items 5 \
--region us-east-1
# View logs from a specific stream
aws logs get-log-events \
--log-group-name /ecs/deepintshield-task \
--log-stream-name deepintshield/deepintshield/TASK_ID \
--region us-east-1
Terminal window
# Describe service
aws ecs describe-services \
--cluster deepintshield-cluster \
--services deepintshield-service \
--region us-east-1
# List tasks
aws ecs list-tasks \
--cluster deepintshield-cluster \
--service-name deepintshield-service \
--region us-east-1
# Describe task
aws ecs describe-tasks \
--cluster deepintshield-cluster \
--tasks TASK_ARN \
--region us-east-1

To remove all ECS resources:

Terminal window
# Using Makefile
make cleanup-ecs
# Or manually
# Delete service
aws ecs update-service \
--cluster deepintshield-cluster \
--service deepintshield-service \
--desired-count 0 \
--region us-east-1
aws ecs delete-service \
--cluster deepintshield-cluster \
--service deepintshield-service \
--region us-east-1
# Deregister task definitions
aws ecs list-task-definitions \
--family-prefix deepintshield-task \
--region us-east-1 \
--query 'taskDefinitionArns[]' \
--output text | \
xargs -n 1 aws ecs deregister-task-definition --task-definition --region us-east-1
# Delete secret (optional)
aws secretsmanager delete-secret \
--secret-id deepintshield/config \
--force-delete-without-recovery \
--region us-east-1
# Or delete SSM parameter (optional)
aws ssm delete-parameter \
--name /deepintshield/config \
--region us-east-1