AWS Snapstart Java抛出无法从链中的任何提供者加载AWS凭证



我尝试为我的lambda函数启用snapstart,该函数仅使用简单的java AWS SDK连接到仅将消息放入队列。没有snapstart代码工作正常,但是当它启用时,我得到这个错误

提交异常消息时出错:无法从链中的任何提供者加载AWS凭据

我已经附上了SQS的完整访问策略,它在没有snapstart的情况下工作得很好。

final Map<String, MessageAttributeValue> messageAttributes = new HashMap<>();
messageAttributes.put("testID", new MessageAttributeValue().withStringValue("id123").withDataType("String"));
final AmazonSQS sqs = AmazonSQSClientBuilder.standard().withRegion(Regions.EU_WEST_1).build();
final SendMessageRequest sendMessageStandardQueue = new SendMessageRequest().withQueueUrl("https://sqs.eu-west-1.amazonaws.com/111111/my-queue")
.withMessageBody("Test message from lambda")
.withMessageAttributes(messageAttributes);
sqs.sendMessage(sendMessageStandardQueue);

这段代码没有在lambda函数上启用snapstart也可以正常工作。启用snapstart后,我在代码中添加了以下代码:

@Override
public void beforeCheckpoint(org.crac.Context<? extends Resource> context) throws Exception {
System.out.println("Before Checkpoint");
}
@Override
public void afterRestore(org.crac.Context<? extends Resource> context) throws Exception {
System.out.println("After Restore");
}

你能帮我理解为什么它无法加载凭据吗?

?

如果您依赖于AWS SDK的环境凭证提供程序,则重新水合的SnapStart Lambda函数将无法找到AWS凭证。根据使用SnapStart与AWS sdk:

当SnapStart被激活时,Java运行时自动使用容器凭证(AWS_CONTAINER_CREDENTIALS_FULL_URI和AWS_CONTAINER_AUTHORIZATION_TOKEN)而不是访问键环境变量。这可以防止在恢复功能之前凭据过期。

所以,我认为这意味着:

  1. 始终通过IAM角色向Lambda函数提供IAM凭据
  2. 确保您的代码使用默认凭证提供程序链

如果这不是问题,那么尝试确定Lambda函数是否依赖于对快照和恢复操作不具有弹性的状态。考虑使用AWS Lambda SnapStart漏洞扫描器进行进一步调查。

特别是,兼容性考虑包括:

临时数据有些函数在初始化阶段下载或初始化临时数据,例如临时凭据或缓存的时间戳。在使用函数处理程序之前刷新它中的临时数据,即使不使用SnapStart。

此外,在发布时根据博客文章有一些限制:

  • 它目前只支持Java,特别是Corretto (java11)运行时
  • 不能将Lambda SnapStart用于较大的临时存储、弹性文件系统、预置并发性或gravon2
  • 缓存的快照在14天后被删除

如何放置?

使用AWS SDK v2:
SqsClient sqs = SqsClient.builder()
.credentialsProvider(SdkSystemSetting.AWS_CONTAINER_CREDENTIALS_FULL_URI
.getStringValue()
.isPresent()
? ContainerCredentialsProvider.builder().build()
: EnvironmentVariableCredentialsProvider.create())
.region(Region.of(SdkSystemSetting.AWS_REGION.getStringValueOrThrow()))
.build();

对于Snapstart环境,我们将使用SDK的容器凭据;对于普通的Lambda环境,我们可以为SDK使用环境凭据。确定我们所处环境的一种方法是检查容器URI:

public AwsCredentialsProvider provideAwsCredentials()
return System.getenv("AWS_CONTAINER_CREDENTIALS_FULL_URI") == null ?
EnvironmentVariableCredentialsProvider.create() : ContainerCredentialsProvider.builder().build();

相关内容

最新更新