Java Lambda对接Localstack(AWS)时的凭证认证失败问题
强制指定Localstack端点与凭证
Lambda运行时不会自动读取本地aws configure的配置,必须在代码里显式指定Localstack的S3、Kinesis端点,以及Localstack默认的测试凭证test/test。示例代码:// 初始化S3客户端 AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration( "http://localhost:4566", "us-east-1")) .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test"))) .build(); // 初始化Kinesis客户端 AmazonKinesis kinesisClient = AmazonKinesisClientBuilder.standard() .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration( "http://localhost:4566", "us-east-1")) .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test"))) .build();配置Lambda执行角色权限
即使在Localstack环境,也要给Lambda关联的IAM角色配置S3读、Kinesis写权限。先创建权限策略文档(比如lambda-policy.json):{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject", "kinesis:PutRecord"], "Resource": ["*"] } ] }再通过CLI创建角色并关联策略,最后把角色绑定到Lambda。Localstack对ARN校验宽松,角色ARN可以用
arn:aws:iam::000000000000:role/任意名称。修正Lambda部署命令
用AWS CLI创建Lambda时,必须加上--endpoint-url=http://localhost:4566指定Localstack端点,否则会默认请求AWS生产环境,自然出现凭证错误。示例命令:aws lambda create-function --function-name S3ToKinesisLambda \ --runtime java11 \ --handler com.example.S3ToKinesisHandler::handleRequest \ --role arn:aws:iam::000000000000:role/lambda-s3-kinesis-role \ --zip-file fileb://target/s3-to-kinesis-lambda.jar \ --endpoint-url=http://localhost:4566排查网络问题
如果Localstack用Docker运行,代码里的localhost可能无法访问到Localstack服务,换成宿主机IP或者Docker容器名(比如localstack)试试,网络不通经常会被伪装成凭证无效的错误。用CLI直接验证服务连通性
先跳过Lambda,用CLI直接调用Localstack的S3和Kinesis接口:aws s3 ls --endpoint-url=http://localhost:4566 aws kinesis list-streams --endpoint-url=http://localhost:4566如果这些命令正常返回,说明Localstack服务没问题,问题肯定出在Lambda的代码配置或部署环节。
内容的提问来源于stack exchange,提问作者Angel Sanchez

