← ProjectsDocker · Terraform · ECS Fargate

Deploying a containerised application on AWS using Terraform

Built, containerised and deployed an application using Docker, Terraform and ECS, with HTTPS and a custom domain.

DockerECRECS FargateALBRoute 53ACMGitHub Actions
01 — Overview

What I built.

I took a web application from local containerisation through to a repeatable AWS deployment. Docker packaged the application, ECR stored the image, ECS Fargate ran the workload, an Application Load Balancer exposed it over HTTPS, Route 53 provided the custom domain and Terraform moved the infrastructure away from manual setup. GitHub Actions then automated both infrastructure and application delivery using OIDC.

FargateServerless container runtime
HTTPSALB + ACM
ECRApplication image registry
OIDCGitHub Actions to AWS
02 — Architecture

How the platform fits together.

Architecture & deployment flow

Application architecture

Switch between the public request path and the application delivery path.

03 — Implementation

How it was implemented.

  1. 01Built the application with a multi-stage Dockerfile and used NGINX as the runtime web server, including a /health endpoint.
  2. 02Validated the container locally before pushing the application image to Amazon ECR.
  3. 03Created the initial ECS cluster, Fargate service, load balancer, target group, security groups, Route 53 DNS and ACM certificate manually to understand how the services worked together.
  4. 04Removed the manual resources and rebuilt the networking, security, ECR, ACM, ALB and ECS infrastructure using modular Terraform with remote state in S3.
  5. 05Added GitHub Actions workflows using OIDC for infrastructure changes and application deployments without stored long-lived AWS access keys.
  6. 06Configured HTTP-to-HTTPS redirection and restricted inbound application traffic so ECS tasks are reached through the load balancer.
  7. 07Verified the HTTPS endpoint and application health before destroying the AWS infrastructure to avoid ongoing charges.
docker · threat composer
04 — Troubleshooting

Issues resolved.

01Container runtime

NGINX failed as a non-root user

ProblemRunning NGINX without root privileges caused a PID-file permission issue.

FixMoved the PID file to /tmp so the container could run with the intended permissions.

02TLS validation

ACM validation was delayed

ProblemHosted-zone issues prevented the expected certificate validation path from completing cleanly.

FixWorked through the Route 53 DNS and ACM validation configuration until the certificate could be issued and attached to the load balancer.

03CI reliability

Container builds were unreliable in CI

ProblemARM64 emulation slowed builds and a Yarn network timeout also caused workflow failures.

FixKept the build stage native where possible and increased the Yarn network timeout rather than treating the failure as an application defect.

Outcome.

The application was successfully deployed on ECS Fargate behind an HTTPS Application Load Balancer and custom Route 53 domain. Docker images were stored in ECR, the infrastructure was managed with modular Terraform, and GitHub Actions used OIDC for both infrastructure and application deployment workflows. The AWS environment was later destroyed with Terraform to avoid ongoing charges.