AWS Instance Profile不适用于Spring Cloud AWS

Jac*_*cia 9 java amazon-web-services spring-boot spring-cloud

我有一个小的Spring Boot应用程序,使用Spring Cloud AWS(1.0.0.RELEASE)来访问SQS队列.它部署在具有实例配置文件集的EC2实例上.似乎AWS的一面正在发挥作用,因为我可以访问两个相关的元数据链接:iam/info并且iam/security-credentials/role-name,它们确实包含正确的信息.只是为了确定,我已经使用了aws cmdline实用程序(aws sqs list-queues)并且确实有效,所以我猜设置正常.但是,当应用程序启动时,它会读取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
Run Code Online (Sandbox Code Playgroud)

...这意味着由于某种原因,Spring Cloud AWS没有获得实例配置文件凭据.我已启用debug日志级别,com.amazonaws.request看起来没有访问密钥和密钥发送请求.

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, )
Run Code Online (Sandbox Code Playgroud)

任何人都知道我缺少什么或至少有任何提示如何进一步调试这个?

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

Jac*_*cia 9

这个问题的解决方案来自两个截然不同的事实.

  1. 实例档凭证,将要只用和如果application.properties已经instanceProfile属性设置为true accessKey设置null(ContextCredentialsAutoConfiguration).

  2. 即使您将提供自定义application.properties文件,Spring也会读取application.properties与app jar捆绑在一起的文件(如果确实存在).如果是这种情况,两个文件中的属性将总结为创建执行环境.我怀疑首先解析捆绑文件,然后自定义第二个,覆盖捆绑文件中存在的任何属性.

在我的例子中,捆绑的application.properties是accessKey和secretKey占位符(带有虚假值),只要他想在EC2环境之外进行一些测试,就会由开发人员填写.这使得accessKey不为null,因此排除了实例配置文件路径.我刚从jar中删除了application.properties文件,解决了这个问题.