DEV Community 👩‍💻👨‍💻

Pedro Emanoel
Pedro Emanoel

Posted on

How to build microsservices with Spring Boot and AWS with Fargate and DOCKER - Part 5

Image description

Aplication Deployment on AWS with EC2, ECS and Fargate

First, We need put this dependency on POM.XML

        <dependency>
            <groupId>software.amazon.awscdk</groupId>
            <artifactId>ec2</artifactId>
            <version>${cdk.version}</version>
        </dependency>
Enter fullscreen mode Exit fullscreen mode

we copy the class AwsSpringCdkStack and we will use the template.
Copy de class with name VpcStack

Image description

Lets create a VPC
Image description

then, we need make an instantiation that vpc

Image description

Deploy VPC

now, in the terminal write the command: cdk list to see all yours stacks

and cdk deploy Vpc to deploy the vpc

Image description

in the AWS we can see the stack status

Image description

When created, we have the status:
Image description

in VPC page, we can se our vpcs
Image description

Creating Cluster

First, add two dependencies on POM.XML

      <dependency>
            <groupId>software.amazon.awscdk</groupId>
            <artifactId>ecs</artifactId>
            <version>${cdk.version}</version>
        </dependency>

        <dependency>
            <groupId>software.amazon.awscdk</groupId>
            <artifactId>ecs-patterns</artifactId>
            <version>${cdk.version}</version>
        </dependency>
Enter fullscreen mode Exit fullscreen mode

Then Copy the class AwsSpringCdkStack to new class called ClusterStack

Next, in the constructors parameters, we need add more one parameter, called Vpc, our cluster need are inside a VPC.

Image description

public class ClusterStack extends Stack {

    public ClusterStack(final Construct scope, final String id, Vpc vpc) {
        this(scope, id, null, vpc);
    }

    public ClusterStack(final Construct scope, final String id, final StackProps props, Vpc vpc) {
        super(scope, id, props);

        Cluster.Builder.create(this, id)
                .clusterName("cluster-01")
                .vpc(vpc)
                .build();
    }
}
Enter fullscreen mode Exit fullscreen mode

To pass a vpc for ClusterStack we need make changes in VpcStack

Image description

Now, we create a private attribute with Vpc type and we create a getter to it.

package com.myorg;

import software.amazon.awscdk.core.Construct;
import software.amazon.awscdk.core.Stack;
import software.amazon.awscdk.core.StackProps;
import software.amazon.awscdk.services.ec2.Vpc;

public class VpcStack extends Stack {

    public VpcStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    private Vpc vpc;

    public VpcStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        //he need two parameters, scope and id
        vpc = Vpc.Builder.create(this, "Vpc01")
                .maxAzs(3) //Max availability quantity  zones that our vpc will act inside the region
                .build();

        // The code that defines your stack goes here
    }

    public Vpc getVpc() {
        return vpc;
    }
}
Enter fullscreen mode Exit fullscreen mode

and now we will make the instance to the clusterStack
Image description

in terminal put:
cdk diff

Image description

its will see the differences between your project and your aws.

now make the deploy
Image description

It Works
Image description

We cluster are created!

Image description

Application Load Balance

The responsable to make the requisitons balance to our instances

we will see:
SERVICES
TARGET GROUP
AUTO SCALLING RULES
TASK DEFINITION

Copy a new stack with de code:

package com.myorg;

import software.amazon.awscdk.core.Construct;
import software.amazon.awscdk.core.RemovalPolicy;
import software.amazon.awscdk.core.Stack;
import software.amazon.awscdk.core.StackProps;
import software.amazon.awscdk.services.ec2.Vpc;
import software.amazon.awscdk.services.ecs.AwsLogDriverProps;
import software.amazon.awscdk.services.ecs.Cluster;
import software.amazon.awscdk.services.ecs.ContainerImage;
import software.amazon.awscdk.services.ecs.LogDriver;
import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedFargateService;
import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedTaskImageOptions;
import software.amazon.awscdk.services.logs.LogGroup;

public class Service01Stack extends Stack {

    // Specify the cluster
    public Service01Stack(final Construct scope, final String id, Cluster cluster) {
        this(scope, id, null, cluster);
    }

    public Service01Stack(final Construct scope, final String id, final StackProps props, Cluster cluster) {
        super(scope, id, props);

        ApplicationLoadBalancedFargateService service01 = ApplicationLoadBalancedFargateService
                .Builder
                .create(this, "ALB-01")
                .serviceName("service-01")
                .cluster(cluster)
                .cpu(512) // how much cpu we need use
                .desiredCount(2) // how much instances we want
                .listenerPort(8080)
                .memoryLimitMiB(1024)
                .taskImageOptions(
                        //Container informations
                        ApplicationLoadBalancedTaskImageOptions.builder()
                                .containerName("aws_project01")
                                .image(ContainerImage.fromRegistry("pedrospiet/aws_training_01:1.0.0")) //Your repository on dockerHub
                                .containerPort(8080)
                                .logDriver(LogDriver.awsLogs(AwsLogDriverProps.builder()
                                                .logGroup(LogGroup.Builder.create(this, "Service01LogGroup")
                                                        .logGroupName("Service01")
                                                        .removalPolicy(RemovalPolicy.DESTROY)
                                                        .build()
                                                ).streamPrefix("Service01")
                                        .build()))
                                .build()
                ).publicLoadBalancer(true)
                .build();

    }


}

Enter fullscreen mode Exit fullscreen mode

it will create a new stack for us with docker container and logs informations in CloudWatch where we to can see our logs.

For instanciation, we need pass a cluster. First we need change the ClusterStack class

public class ClusterStack extends Stack {

    public ClusterStack(final Construct scope, final String id, Vpc vpc) {
        this(scope, id, null, vpc);
    }

    private Cluster cluster;
    public ClusterStack(final Construct scope, final String id, final StackProps props, Vpc vpc) {
        super(scope, id, props);

        cluster = Cluster.Builder.create(this, id)
                .clusterName("cluster-01")
                .vpc(vpc)
                .build();
    }

    public Cluster getCluster() {
        return cluster;
    }
}
Enter fullscreen mode Exit fullscreen mode

now we will add the Auto Scalling and Health Check



        service01.getTargetGroup().configureHealthCheck(new HealthCheck.Builder()
                .path("/actuator/health")
                .port("8080")
                .healthyHttpCodes("200")
                .build());

      ScalableTaskCount scalableTaskCount = service01.getService().autoScaleTaskCount(EnableScalingProps.builder()
                .minCapacity(2)
                .maxCapacity(4)
                .build());

        scalableTaskCount.scaleOnCpuUtilization("Service01AutoScaling", CpuUtilizationScalingProps.builder()
                .targetUtilizationPercent(50)
                .scaleInCooldown(Duration.seconds(60))
                .scaleOutCooldown(Duration.seconds(60))
                .build());
Enter fullscreen mode Exit fullscreen mode
  • I Dont use the Auto Scalling because AWS Educate dont have permission *

add Service01Stack to main class

public class AwsSpringCdkApp {
    public static void main(final String[] args) {
        App app = new App();

        VpcStack vpcStack = new VpcStack(app, "Vpc");

        ClusterStack clusterStack = new ClusterStack(app, "Cluster", null, vpcStack.getVpc());
        clusterStack.addDependency(vpcStack);

        Service01Stack service01Stack = new Service01Stack(app, "Service01", clusterStack.getCluster());
        service01Stack.addDependency(clusterStack);
        app.synth();
    }
}
Enter fullscreen mode Exit fullscreen mode

and to run deploy

Image description

On terminal, you can see the:
Service01.ALB01ServiceURL774C913E

copy the url and put on INSOMNIA
Image description

IT WORKS!

****** WARNING *****
to avoid charges is necessary DESTROY the instances

put on terminal:

cdk destroy Vpc Cluster Service01

Thats it :)

Top comments (0)

Take a look at this:

Settings

Go to your customization settings to nudge your home feed to show content more relevant to your developer experience level. 🛠