DEV Community 👩‍💻👨‍💻

Pedro Emanoel
Pedro Emanoel

Posted on

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

Image description

AWS RDS

What is RDS?
Relational Database Service, is a service in cloud disponibilized by amazon to facility the scalonament and management of databases, to app uses. With RDS we can use sundry relational databases, like MYSQL, SQL SERVER, MaRIADB, POSTGRESQL, etc...


Now, we gonna create a RDS Stack in AWS CDK application.
Image description

First add the dependency in POM.XML

        <dependency>
            <groupId>software.amazon.awscdk</groupId>
            <artifactId>rds</artifactId>
            <version>${cdk.version}</version>
        </dependency>
Enter fullscreen mode Exit fullscreen mode
package com.myorg;

import software.amazon.awscdk.core.*;
import software.amazon.awscdk.services.ec2.*;
import software.amazon.awscdk.services.rds.*;

import java.util.Collections;

public class RdsStack extends Stack {

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

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

        //Cloud Formation Parameter, we're going use that to send parameters to RDS in our template.
        CfnParameter dabasePassword = CfnParameter.Builder.create(this, "databasePassword")
                .type("String")
                .description("password for our database RDS")
                .build();

        //Configuring Security Group to use port 3306
        ISecurityGroup iSecurityGroup = SecurityGroup.fromSecurityGroupId(this, id, vpc.getVpcDefaultSecurityGroup());
        iSecurityGroup.addEgressRule(Peer.anyIpv4(), Port.tcp(3306));

        DatabaseInstance databaseInstance = DatabaseInstance.Builder
                .create(this, "Rds01")
                //identifier our database to see in aws console
                .instanceIdentifier("aws-spring01-db")
                //instance of our database
                .engine(DatabaseInstanceEngine.mysql(MySqlInstanceEngineProps.builder()
                        .version(MysqlEngineVersion.VER_5_6)
                        .build()))
                //vpc
                .vpc(vpc)
                //database credentials
                .credentials(Credentials.fromUsername("admin",
                        CredentialsFromUsernameOptions.builder()
                                .password(SecretValue.plainText(dabasePassword.getValueAsString()))
                                .build()))
                //instance type, as i use aws educate i just can use the minimal configuration
                .instanceType(InstanceType.of(InstanceClass.BURSTABLE2, InstanceSize.SMALL))
                .multiAz(false)
                .allocatedStorage(5) //storage
                //securityGroups and Vpc subnet
                .securityGroups(Collections.singletonList(iSecurityGroup))
                .vpcSubnets(SubnetSelection.builder()
                        .subnets(vpc.getPrivateSubnets())
                        .build())
                .build();


        // exporting our parameters, if others stacks need

        //exporting the database endpoint
        CfnOutput.Builder.create(this, "rds-endpoint")
                .exportName("rds-endpoint")
                .value(databaseInstance.getDbInstanceEndpointAddress())
                .build();

        //export the password
        CfnOutput.Builder.create(this, "rds-password")
                .exportName("rds-password")
                .value(dabasePassword.getValueAsString())
                .build();
    }
}

Enter fullscreen mode Exit fullscreen mode

first, we configurate the security group to can use the 3306 port, remember, just services inside VPC can see our database, external access not.

Then, lets change the CdkApp class

package com.myorg;

import software.amazon.awscdk.core.App;
import software.amazon.awscdk.core.Environment;
import software.amazon.awscdk.core.StackProps;

import java.util.Arrays;

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);

        RdsStack rdsStack = new RdsStack(app, "Rds", vpcStack.getVpc());
        rdsStack.addDependency(vpcStack);

        Service01Stack service01Stack = new Service01Stack(app, "Service01", clusterStack.getCluster());
        service01Stack.addDependency(clusterStack);
        service01Stack.addDependency(rdsStack); // depends rds

        app.synth();
    }
}
Enter fullscreen mode Exit fullscreen mode

Next, we need change the Service01Stack to add RDS parameters

package com.myorg;

import software.amazon.awscdk.core.*;
import software.amazon.awscdk.services.applicationautoscaling.EnableScalingProps;
import software.amazon.awscdk.services.ec2.Vpc;
import software.amazon.awscdk.services.ecs.*;
import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedFargateService;
import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedTaskImageOptions;
import software.amazon.awscdk.services.elasticloadbalancingv2.HealthCheck;
import software.amazon.awscdk.services.logs.LogGroup;

import java.util.HashMap;
import java.util.Map;

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);


        /*
        *Adding Database Username, Endpoint and password in our enviroments
        *
         */
        Map<String, String> envVariables = new HashMap<>();
        envVariables.put("SPRING_DATASOURCE_URL", "jdbc:mariadb://"
                + Fn.importValue("rds-endpoint")
                + ":3306/aws_spring01?createDatabaseIfNotExist=true");
        envVariables.put("SPRING_DATASOURCE_USERNAME", "admin");
        envVariables.put("SPRING_DATASOURCE_PASSWORD", Fn.importValue("rds-password"));

        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()))
                                .environment(envVariables) // adding enviroments
                                .build()
                ).publicLoadBalancer(true)
                .build();



        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

Now, we make deploy with the command below:

cdk deploy --parameters Rds:databasePassword={your_password} Vpc Cluster Rds Service01
Image description

It Works.

You can see the diferences in RDS console on AWS.

bye bye.

Top comments (0)

🌚 Life is too short to browse without dark mode