damnhandy / springcloud-aws-example

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Spring Boot with Spring Cloud AWS Example

This small sample application uses a SpringBoot service with Spring Cloud AWS to source certain configuration elements. Additionally, it uses the AWS Cloud Development Kit (CDK) to provision the AWS resources that the application needs to deploy into AWS.

Objectives

This project defines a simple SpringBoot service that connects to a Postgres database. The deployment will handle the provisioning of credentials, such as passwords and certificates. The application will resolve the credentials differently depending on its deployed environment. The SpringBoot application uses Spring profiles to determine the right strategy. When using the local or docker profiles, it will use the Spring configtree to resolve the credentials. In AWS, the aws profile is used and the Spring Cloud AWS library handles the resolution of secrets.

When deployed to AWS, a codebuild job populates the database using the Flyway CLI. A Lambda trigger triggers the CodeBuild project whenever the data-migration.zip file is uploaded to S3. When running under Docker Compose, we leverage the Postgres containers bootstrap mechanism to create the table and provide data.

Strategy

This project is structured as a single project that builds and deploys all assets when deployed to either docker-compose or in AWS.

Provisioning Secrets for local development.

A vital element of this project is to promote proper credential handling. As such, the project attempts to simulate a hands-off credentials management approach. The DB credentials are generated and stored in the ./credentials directory in a local environment. When running under Docker Compose, these values are injected into the environment via the Docker Secrets mechanism. When deployed in AWS, the DB credentials are generated by AWS Secrets Manager and referenced in the application via Spring Cloud AWS. Before running the application in either local model, run the prepare_credentials.sh script. This will generate the following:

  • The Postgres root password
  • The Postgres appuser password (used by the SpringBoot application)
  • The Postgres certificates
  • A KeyStore that contains the self-signed Postgres root CA
  • A Keystore that contains the RDS certs for us-east-1.

You will only use these credentials locally except for the Keystore for RDS. When deployed to AWS, the credentials generated by AWS Secrets Manager are used.

Practically ALL SpringBoot/Postgres examples create a JDBC connection with sslMode=DISABLED as it is generally more accessible but fundamentally wrong. Because these examples make their way into production, this project demonstrates using TLS with Postgres.

The Postgres certificates are generated at startup so we can prepare a KeyStore with the generated root certificates to make a TLS connection work locally. When deployed to AWS, the application will use the Keystore that contains the RDS certificates.

Local Hybrid Deployment with Docker Compose

In this model, we use Docker Compose to bring up ONLY the Postgres DB so that we can run the SpringBoot application via an IDE on the Host OS. To do this, run the following:

$ ./prepare_credentials.sh
$ docker compose up postgres

In your IDE, use the local profile to connect to the database.

Local Deployment with Docker Compose

To run the stack locally, simply run the following commands:

$ ./prepare_credentials.sh
$ docker compose build
$ docker compose up

This will build the container with the SpringBoot application and launch the Postgres database and SpringBoot application. The depends_on attribute of Docker Compose does not force the SpringBoot app to wait until the Postgres instance is ready for requests. Upon running the stack for the first time, it is normal to see the SpringBoot app fail to connect to Postgres in the first few attempts. The SpringBoot app has a restart policy of always which will restart the app on failure. Eventually, the application will stabilize, and you should be able to hit the following URIs:

http://localhost:8080/cars/11

http://localhost:8081/actuator/info

http://localhost:8081/actuator/health

AWS CDK Deployment

Before deploying to AWS, run the build target:

npm run build

And then synthesize the stack by running:

npx cdk synth

And finally, deploy the stack:

npx cdk deploy --all

or if you don't want to deal with the prompts, run:

npm run deploy

Verifying the AWS Deployment

Once deployed, the AWS environment can be verified to ensure specific resources have been created and have been configured inline with expectations. The project uses CINC Auditor/InSpec to

cinc-auditor exec verification -t aws://

or with InSpec:

inspec exec verification -t aws://

About


Languages

Language:TypeScript 49.4%Language:Java 27.4%Language:Dockerfile 6.5%Language:CSS 4.7%Language:HTML 3.2%Language:Ruby 3.2%Language:JavaScript 3.1%Language:Shell 2.0%Language:Nix 0.4%