Skip to main content

IDIAL Deployment on AWS ECS Fargate

Overview

This document describes the complete setup of IDIAL on AWS ECS Fargate.

Region

We always and only deploy our applications in the eu-central-1 region (Frankfurt).

IDIAL consists of two containers running together as a single ECS task:

ContainerImagePortFunction
IDIALbxc2security/idial:v0.145000REST API + PKI
Web_Backendbxc2security/idial-web-backend:latest5555Web UI

Prerequisites

  • AWS CLI installed and configured (aws configure)
  • DockerHub account with access to the bxc2security repository

1. Configure Secrets Manager

All credentials are stored in AWS Secrets Manager. Three secrets are required.

1.1 DockerHub Credentials

GUI: AWS Console → Secrets Manager → Store a new secret

  • Secret type: Other type of secret
  • Key/Value:
    • username → your DockerHub username (not email)
    • password → your DockerHub Personal Access Token (not your login password)
  • Secret name: DockerHub

Create a Personal Access Token via: Docker Hub → Account Settings → Personal access tokens → Generate new token

Permission: Read-only is sufficient.

AWS Secrets Manager – Store a new secret

1.2 IDIAL PKCS8 Password

aws secretsmanager create-secret \
--name idial/pkcs8-pw \
--secret-string "YOUR_SECRET_VALUE" \
--region eu-central-1

1.3 Web Backend Secret Key

aws secretsmanager create-secret \
--name idial/web-secret-key \
--secret-string "$(openssl rand -base64 32)" \
--region eu-central-1
note

The resulting ARNs will include a random suffix (e.g. idial/pkcs8-pw-05u5Sl). This is expected and handled using wildcards in IAM policies.


2. Configure IAM Role

The ECS Task Execution Role requires access to all three secrets.

2.1 Verify Role

GUI: IAM → Roles → ecsTaskExecutionRole

If the role does not exist:

aws iam create-role \
--role-name ecsTaskExecutionRole \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ecs-tasks.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'

aws iam attach-role-policy \
--role-name ecsTaskExecutionRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

2.2 Add Secrets Manager Policy

aws iam put-role-policy \
--role-name ecsTaskExecutionRole \
--policy-name idial-secrets-access \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": [
"arn:aws:secretsmanager:eu-central-1:015955903887:secret:DockerHub*",
"arn:aws:secretsmanager:eu-central-1:015955903887:secret:idial/pkcs8-pw*",
"arn:aws:secretsmanager:eu-central-1:015955903887:secret:idial/web-secret-key*"
]
}
]
}' \
--region eu-central-1
warning

The * wildcard is required because Secrets Manager appends a random suffix to secret ARNs.


3. Create ECS Cluster

GUI: ECS → Clusters → Create Cluster

  • Cluster name: IDIALCluster
  • Infrastructure: AWS Fargate (serverless)
aws ecs create-cluster \
--cli-input-json file://ecs-cluster.json \
--region eu-central-1

AWS ECS – Create Cluster


4. Register Task Definition

The task definition defines both containers, environment variables, ports, and volumes.

GUI: ECS → Create new task definition

Task Definition – Infrastructure & Launch type

4.1 Container Configuration

Task Definition – Container settings

4.2 Volumes

Ephemeral Storage

Both containers use ephemeral storage. Data is lost on task restart. For persistence, use EFS.

VolumeContainerPath
database_dataIDIAL/app/sql
device_certificatesIDIAL/app/certs
api_keyIDIAL/app/secrets
rest_tlsIDIAL/app/tls
idial_webapp_runtime_dataWeb_Backend/app/runtime_data
idial_webapp_logsWeb_Backend/app/logs
idial_webapp_configWeb_Backend/app/config

Task Definition – Volume configuration

Task Definition – Container mount points


5. Configure Security Group

PortProtocolSourcePurpose
5000TCPYour IP /32REST API
5555TCPYour IP /32Web UI
aws ec2 authorize-security-group-ingress \
--group-id <SECURITY_GROUP_ID> \
--ip-permissions '[
{"IpProtocol":"tcp","FromPort":5555,"ToPort":5555,"IpRanges":[{"CidrIp":"<YOUR_IP>/32"}]},
{"IpProtocol":"tcp","FromPort":5000,"ToPort":5000,"IpRanges":[{"CidrIp":"<YOUR_IP>/32"}]}
]'

6. Create and Start Service

GUI: ECS → Clusters → IDIALCluster → Services → Create

6.1 Determine Subnet & Security Group

aws ec2 describe-subnets ...
aws ec2 describe-security-groups ...
warning

Use a public subnet (MapPublicIpOnLaunch = true).

6.2 Configure ecs-service.json

{
"cluster": "IDIALCluster",
"serviceName": "idial",
"desiredCount": 1,
"launchType": "FARGATE"
}

6.3 Create Service

ECS – Create Service configuration

aws ecs create-service --cli-input-json file://ecs-service.json

6.4 Check Status

aws ecs describe-services --cluster IDIALCluster --services idial

7. Access IDIAL

Find the public IP of the running task:

aws ecs list-tasks --cluster IDIALCluster --service-name idial
aws ecs describe-tasks --cluster IDIALCluster --tasks <TASK_ARN>

Then open:

https://<PUBLIC_IP>:5555

8. Logs

aws logs describe-log-streams --log-group-name /ecs/idial
aws logs get-log-events --log-group-name /ecs/idial --log-stream-name <STREAM>

9. IDIAL API Key

On first start, the API key is printed to the container logs:

IDIAL API key (save this now): XXXXX
Save immediately

The API key is lost on task restart. Copy it from the logs immediately after first start.


Troubleshooting

AccessDeniedException

The ECS task cannot read secrets. Check the IAM policy in section 2.2 – verify ARNs and wildcard suffix.

401 Unauthorized

Wrong DockerHub credentials in Secrets Manager. Update the DockerHub secret with a valid Personal Access Token.

ERR_EMPTY_RESPONSE

  • Ensure you are using HTTPS (https://, not http://)
  • Check that the Security Group allows inbound TCP on port 5555 from your IP
  • Check the container logs: aws logs get-log-events ...

IP Changed

If your public IP changes, update the Security Group:

# Remove old rule
aws ec2 revoke-security-group-ingress \
--group-id <SG_ID> \
--ip-permissions '[{"IpProtocol":"tcp","FromPort":5555,"ToPort":5555,"IpRanges":[{"CidrIp":"<OLD_IP>/32"}]},{"IpProtocol":"tcp","FromPort":5000,"ToPort":5000,"IpRanges":[{"CidrIp":"<OLD_IP>/32"}]}]'

# Add new rule
aws ec2 authorize-security-group-ingress \
--group-id <SG_ID> \
--ip-permissions '[{"IpProtocol":"tcp","FromPort":5555,"ToPort":5555,"IpRanges":[{"CidrIp":"<NEW_IP>/32"}]},{"IpProtocol":"tcp","FromPort":5000,"ToPort":5000,"IpRanges":[{"CidrIp":"<NEW_IP>/32"}]}]'