Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

EC2MetadataUtils used to determine if running on cloud environment does not work on ECS Fargate #734

Open
trouptelia opened this issue Nov 28, 2020 · 4 comments
Labels
component: core An issue related to core functionality - credentials, region resolution theme: ecs type: bug A general bug

Comments

@trouptelia
Copy link

Type: Bug

Describe the bug
Version of Spring Cloud:
org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR9
Which resolves to spring cloud aws version 2.2.5.RELEASE

When the application starts up the org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils attempts to determine if the code is running in a cloud environment by using com.amazonaws.util.EC2MetadataUtils. This does not appear to work if the code is deployed to ECS Fargate.

2020-11-28 00:34:36.424  WARN 1 --- [main] i.InstanceMetadataServiceResourceFetcher : Fail to retrieve token
--
com.amazonaws.SdkClientException: Failed to connect to service endpoint:
at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:100)
at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.getToken(InstanceMetadataServiceResourceFetcher.java:91)
at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.readResource(InstanceMetadataServiceResourceFetcher.java:69)
at com.amazonaws.internal.EC2ResourceFetcher.readResource(EC2ResourceFetcher.java:66)
at com.amazonaws.util.EC2MetadataUtils.getItems(EC2MetadataUtils.java:402)
at com.amazonaws.util.EC2MetadataUtils.getData(EC2MetadataUtils.java:371)
at org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38)
at org.springframework.cloud.aws.context.annotation.OnAwsCloudEnvironmentCondition.matches(OnAwsCloudEnvironmentCondition.java:38)
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$TrackedConditionEvaluator.shouldSkip(ConfigurationClassBeanDefinitionReader.java:477)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:131)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:280)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:707)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:533)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)

I have already set the following in my application.yml:

cloud:
  aws:
    region:
      auto: true
      use-default-aws-region-chain: true
    credentials:
      use-default-aws-credentials-chain: true

As described in PR: #559

But this seems to be yet another case where the class being used needs to be configurable based on the platform in AWS the code is deployed to EC2 vs ECS Fargate.

Sample
Deploy any spring app using the spring cloud aws version 2.2.5.RELEASE to ECS Fargate and you should see this issue

@github-actions github-actions bot added type: bug A general bug status: waiting-for-triage An issue we've not yet triaged labels Nov 28, 2020
@maciejwalkowiak
Copy link
Contributor

Thanks for the report. Indeed ConditionalOnAwsCloudEnvironment does not work on Fargate. In your setup, exclude ContextInstanceDataAutoConfiguration as this is the only one that uses this conditional annotation and the warning message will disappear, also, your application will startup faster.

Starting from 2.3.0 ContextInstanceDataAutoConfiguration will be disabled by default.

@maciejwalkowiak maciejwalkowiak added theme: ecs component: core An issue related to core functionality - credentials, region resolution and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 29, 2020
@buckett
Copy link

buckett commented Dec 1, 2020

Is the plan for this to improve org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils so that it understands the metadata endpoints documented in: https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-metadata-endpoint-fargate.html

@buckett
Copy link

buckett commented Dec 1, 2020

I had a look in the AWS v1 SDK (current SDK for Spring Cloud AWS) with https://github.com/aws/aws-sdk-java/search?q=169.254.170&type=code but there doesn't appear (only from 10 minutes looking) to be a way to get the ECS metadata, the only thing I found was a way to load the container credentials:
https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/auth/ContainerCredentialsProvider.java

@kbroadbent
Copy link

Under the hood the AwsCloudEnvironmentCheckUtils uses the SDK's EC2MetadataUtils. That util class calls an EC2-specific metadata endpoint that is present on EC2 instances. ECS has its own set of metadata endpoints (https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint.html). One option would be to create a helper class to retrieve data from those endpoints and see if it comes back with any data. Another option would be to check for the presence of an ECS_CONTAINER_METADATA_URI environment variable and, if it's set, assume we're running in ECS and isRunningOnCloudEnvironment should return true.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
component: core An issue related to core functionality - credentials, region resolution theme: ecs type: bug A general bug
Development

No branches or pull requests

4 participants