AWS

How to Build and Deploy a Java Application on AWS Using ECS and Fargate – Part 2

In Part 1 we built a simple Java Books API and wrapped it in a Docker container. Running it locally was easy, but the real goal was to host it in AWS so anyone can hit it via a public endpoint.

This time, we’ll use the AWS CDK (in TypeScript) to:

  • Create an ECS cluster
  • Deploy our container to Fargate
  • Put an Application Load Balancer (ALB) in front
  • End up with a working public endpoint like:
<http://BookCd-Books-XXXXXXX-XXXXXXX.us-west-2.elb.amazonaws.com/books>

Let’s dive in.

Step 1: Initialize a CDK Project

In a new directory (outside your Java project), run:

mkdir book-cdk && cd book-cdk
cdk init app --language typescript
npm install @aws-cdk/aws-ecs @aws-cdk/aws-ecs-patterns @aws-cdk/aws-ec2

This gives us a fresh basic CDK app.

Step 2: Create an ECS Cluster

In lib/book-cdk-stack.ts:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecs_patterns from 'aws-cdk-lib/aws-ecs-patterns';
import * as ecr_assets from 'aws-cdk-lib/aws-ecr-assets';

export class ApplicationStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 1. VPC (2 AZs by default)
    const vpc = new ec2.Vpc(this, 'BooksVpc', {
      maxAzs: 2
    });

    // 2. ECS Cluster
    const cluster = new ecs.Cluster(this, 'BooksCluster', {
      vpc: vpc
    });

    // 3. Fargate Service with ALB
    const service = new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'BooksService', {
      cluster: cluster,
      cpu: 256,
      memoryLimitMiB: 512,
      desiredCount: 1,
      listenerPort: 80,
      taskImageOptions: {
        image: ecs.ContainerImage.fromAsset('/Users/himanshusourav/book-api/books-api', {
            platform: ecr_assets.Platform.LINUX_AMD64
        }), // Path to your Dockerfile
        containerPort: 8080,
      },
      publicLoadBalancer: true,
    });

    // 4. Configuring health check
    service.targetGroup.configureHealthCheck({
        path: '/books',
        interval: cdk.Duration.seconds(30),
        healthyThresholdCount: 2,
        unhealthyThresholdCount: 2,
        timeout: cdk.Duration.seconds(5),
      });

    // Give the container time to start before health check kicks in
    service.targetGroup.setAttribute('deregistration_delay.timeout_seconds', '30'); // optional
    (service.service.node.defaultChild as ecs.CfnService).healthCheckGracePeriodSeconds = 60;   
  }
}

Here’s what’s happening:

  • We spin up a VPC (network).
  • Create an ECS cluster in it.
  • Add a Fargate service with an ALB in front.
  • The container is built straight from ../books-api (your Dockerized app from Part 1).
  • Adding health check path

Step 3: Deploy to AWS

Run:

cdk bootstrap
cdk deploy

The first time takes a while — CDK uploads assets, builds the container, and provisions ECS + ALB.

When it’s done, CDK outputs something like:

Outputs:
BookCdkStack.BooksServiceLoadBalancerDNS = BooksServiceLB-123456789.us-west-2.elb.amazonaws.com

We can also get out ALB endpoint from AWS console under EC2 → Load Balancers

That’s your API endpoint!


Step 4: Test the Endpoint

Grab the ALB DNS name and hit it:

# curl <http://BookCd-Books-XXXXXXX-XXXXXXX.us-west-2.elb.amazonaws.com/books>

Expected response:

["Harry Potter", "The Fourth Wing", "The Midnight Library", "The Way of Kings"]

If you see that, your Java app is now running in AWS with ECS + Fargate.


Debugging Note:

  1. The Health Check

At first, my containers kept shutting down in a loop.

Here’s why:

  • The ALB by default probes /, but my API only had /books.
  • Spring Boot took ~20–30 seconds to warm up, but ECS expected an instant response.

ECS thought the container was unhealthy and killed it before it was even ready. The fix was to explicitly configure the health check and add a grace period (see code above). This gave the container enough breathing room to start before ALB checks began.

2. M1/M2 Macs:Remember to build with --platform linux/amd64 (from Part 1). Otherwise, your container might crash in Fargate.

3. Costs:ALBs aren’t free. Don’t forget to cdk destroy when you’re done experimenting.


Now we’ve got:

  • A public ALB endpoint
  • Traffic routed into our Books API running in ECS FargateWhat’s Next?

We’ve got a working ECS service exposed to the internet. But that long ALB DNS name is not user-friendly.

In Part 3, we’ll:

  • Add a custom domain with Route 53
  • Point a subdomain like api.mydomain.com to the ALB
  • Prep for HTTPS with ACM certificates

So by the end, your API will live at a clean domain.


Series Roadmap

  1. (Done) Build and containerize the Java app
  2. (This post) Deploy to ECS Fargate with ALB (via CDK)
  3. Add Route 53 and a custom domain
  4. Secure with HTTPS (ACM) and protect the endpoint
  5. Scaling and monitoring

2 Comments on “How to Build and Deploy a Java Application on AWS Using ECS and Fargate – Part 2

Leave a Reply

Your email address will not be published. Required fields are marked *