AWS 实例配置文件不适用于 Spring Cloud AWS



我有一个小的Spring Boot应用程序,使用Spring Cloud AWS (1.0.0.RELEASE)访问SQS队列。它被部署在具有instance Profile集的EC2实例上。看起来AWS方面的东西正在工作,因为我可以访问两个相关的元数据链接:iam/infoiam/security-credentials/role-name,它们确实包含正确的信息。只是为了确定,我已经使用了aws cmdline实用程序(aws sqs列表-队列),它确实工作,所以我想设置是好的。然而,当应用程序启动时,它读取application.properties(其中包含cloud.aws.credentials.instanceProfile=true行),然后放弃以下警告:com.amazonaws.util.EC2MetadataUtils: Unable to retrieve the requested metadata,最后抛出以下异常:

Caused by: com.amazonaws.AmazonServiceException: The security token included in the request is invalid. (Service: AmazonSQS; Status Code: 403; Error Code: InvalidClientTokenId; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
        at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1071)
        at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:719)
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:454)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:294)
        at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:2291)
        at com.amazonaws.services.sqs.AmazonSQSClient.getQueueUrl(AmazonSQSClient.java:516)
        at com.amazonaws.services.sqs.buffered.AmazonSQSBufferedAsyncClient.getQueueUrl(AmazonSQSBufferedAsyncClient.java:278)
        at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.java:78)
        at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.java:37)
        at org.springframework.messaging.core.CachingDestinationResolverProxy.resolveDestination(CachingDestinationResolverProxy.java:88)
        at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.start(AbstractMessageListenerContainer.java:295)
        at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.start(SimpleMessageListenerContainer.java:38)
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
        ... 17 common frames omitted

…这意味着出于某种原因,Spring Cloud AWS没有获取实例配置文件凭证。我在com.amazonaws.request上启用了debug日志级别,似乎请求是在没有访问密钥和密钥的情况下发送的。

DEBUG --- com.amazonaws.request                    : Sending Request: POST https://sqs.eu-west-1.amazonaws.com / Parameters: (Action: GetQueueUrl, Version: 2012-11-05, QueueName: xxxxxxxxxxxxx, ) Headers: (User-Agent: aws-sdk-java/1.9.3 Linux/3.14.35-28.38.amzn1.x86_64 Java_HotSpot(TM)_64-Bit_Server_VM/25.45-b02/1.8.0_45 AmazonSQSBufferedAsyncClient/1.9.3, )

有人知道我错过了什么,或者至少有任何提示如何进一步调试这个?

EDIT:在浏览了spring-cloud-aws代码之后,我已经向前迈进了一步。与jar捆绑的配置文件application.properties有一些accessKeysecretKey的文本值。我自定义的application.properties没有这些属性,这可能导致spring使用捆绑文件中的值作为默认值。我将它们包含在空值中,这将异常更改为com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain。似乎AWS SDK配置了DefaultProviderChain,但它仍然无法获取实例配置文件凭据。

这个问题的答案来自两个不同的事实。

  1. 如果application.propertiesinstanceProfile属性设置为true accessKey设置为null (ContextCredentialsAutoConfiguration),则仅使用实例配置文件凭据。

  2. 即使你提供自定义的application.properties文件,Spring也会读取与app jar捆绑的application.properties文件(如果它存在)。如果是这种情况,这两个文件的属性将相加以创建一个执行环境。我怀疑捆绑文件首先被解析,然后是自定义文件,覆盖捆绑文件中存在的任何属性。

在我的例子中,绑定的application.properties有accessKey和secretKey占位符(带有假值),当开发人员想要在EC2环境之外进行测试时,可以填写这些占位符。这使得accessKey不为空,因此排除了实例配置文件路径。我刚刚删除了应用程序。

cloud:
  aws:
    credentials:
      accessKey:
      secretKey:
      instanceProfile: true
      useDefaultAwsCredentialsChain: true
如果您使用的是最新的(2.X.X) Spring AWS云,

相关内容

  • 没有找到相关文章

最新更新