jmkgreen
jmkgreen

Reputation: 1643

Spring Cloud AWS and Fargate

I moved an application using Spring Cloud AWS (2.1.0.RELEASE) from an ECS/EC2 instance to ECS/Fargate and it crashes on boot, unable to retrieve credentials from the instance.

The EC2 instance did not have credentials, so this was a surprise. In both cases, the role should provide all the permissions required. The application essentially requires access to the parameter store, nothing else.

Can anyone confirm that this is supposed to work / is working properly? I am uncertain what to debug otherwise.

Edit: I am being asked for sample code. There is no Java code that I have written, so it's down to configuration which I share below.

My pom.xml includes:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-aws-autoconfigure</artifactId>
        </dependency>

Within src/main/resources/bootstrap.yml I have:

spring:
  application:
    name: myapp
  cloud:
    consul:
      enabled: false
      config:
        enabled: false
aws:
  paramstore:
    enabled: false
cloud:
  aws:
    stack:
      auto: false
    credentials:
      instance-profile: false
    region:
      static: eu-west-2
      auto: false

Within src/main/resources/bootstrap-aws.yml (which is activated via a profile of aws on the command line):

aws:
  paramstore:
    prefix: /services/app
    default-context: common
    profile-separator: '_'
    fail-fast: true
    enabled: true

Upvotes: 0

Views: 2119

Answers (1)

jmkgreen
jmkgreen

Reputation: 1643

I now have this working with Fargate. It had nothing to do with the Java application, it had everything to do with the ECS deployment rights, as I will try to explain.

ECS: EC2

ECS by default uses EC2 instances to deploy tasks (holding containers) to. It uses an ECS agent on each EC2 instance to do this which in turn liaises with the Docker engine; this ECS agent by default has no rights which means it cannot download private images (from ECR, for instance) nor write logs to CloudWatch (for instance).

To fix this we create an IAM role and launch the task with an ExecutionRoleArn (in CloudFormation) referencing this. The IAM role needs ecr rights and logs rights.

Now, in a hurry, I had added parameter store rights to this without thinking much more about it, and hey presto my application was happily running and obtaining parameter store values. It turns out that in EC2 mode the rights bestowed on the ECS agent are inherited by the running container (my app).

ECS: Fargate

Switch to Fargate, the above breaks. The ExecutionRoleArn remains relevant, but is not inherited by the running container. So there's no point providing it parameter store rights.

Add into the task definition TaskRoleArn and point it at another role. This time provide the rights in this new role to call the AWS services your container (application) wants - parameter store, S3, SQS, etc.

With this done, my application is happy. Feel free to update with any corrections, as this is written by my understanding and experience thus far.

It may have been better to name ExecutionRoleArn as AgentRoleArn and TaskRoleArn as ApplicationRoleArn but that's just my perspective.

Upvotes: 3

Related Questions