Search code examples
spring-bootdockeramazon-ec2amazon-ecsaws-ssm

Using SSM Parameter Store with a Containerised Spring Boot running on EC2 through ECS


I've been working on containerising an application with the intention of using ECS to manage the creation and deployment of the application to EC2.

Guides I've followed include:

The Spring guide for containerising applications

Deploying Spring Boot on ECS

A guide on adding Parameter Store

Another guide on adding Parameter Store

This hasn't panned out entirely, and I believe I've narrowed it down to the Parameter Store config as the source of the issue.

Right now, pom.xml is pretty light-touch, though I've seen more config needed depending on the scenario:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
    <version>3.1.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

Running locally, outside of a container, I can access parameters with very minimal bootstrap config:

spring.application.name=PxTest
#I would usually provide this...
#cloud.aws.credentials.profile-name=default
#...but it seems like Spring assumes this.

As soon as I containerise it, it fails. I then added:

cloud.aws.stack.auto=false
cloud.aws.region.static=us-east-1
cloud.aws.region.auto=false

As I understand it, this should help Spring find the appropriate parameters - but I've seen very little in the way of documentation or articles describing passing SSM Parameter Store properties into a Spring Boot application running on an ECS-provisioned EC2.

The error messages I can access on the EC2 talk about Docker entering promiscuous state, followed by blocking state, and repeating. Given it works fine without SSM, I suspect this is the Spring application starting up, failing, and then being retriggered repeatedly.

Running locally, the errors I get are:

com.amazonaws.SdkClientException: Failed to connect to service endpoint:
(short version, at EC2ResourceFetcher readResource)
Caused by: java.net.ConnectException: Connection refused
Factory method 'ssmClient' threw Exception; nested exception is com.amazonaws.SdkClientException: Unable to find a region via the region provider chain. Must provide an explicit region in the builder or setup environment to supply a region.

And then a knock-on exception about not being able to instantiate beans because it can't get to the SSM service.

As above, I am providing a region in bootstrap.properties but it seems to be ignoring this locally - but as it will be part of an application stack when deployed, it seems unlikely to me that it'll be the same error locally that is seen on AWS?

Has anyone accomplished this before, or have any resources which may be useful on what information I need to pass into the container to allow it to talk to SSM?


Solution

  • I suggest using the built-in support ECS has for injecting secrets from SSM Parameter Store (or Secrets Manager) as environment variables. That way your code is more environment agnostic, and you can run it locally by just setting environment variables instead of connecting it to an external dependency like SSM Parameter Store.