【问题标题】:Error when AWS Lambda trying to list DynamoDb tablesAWS Lambda 尝试列出 DynamoDb 表时出错
【发布时间】:2015-10-12 12:11:00
【问题描述】:

我未能让以下逻辑在使用 Java 的 AWS Lambda 上工作:

1)当S3桶中有新对象创建时,触发lambda函数(java编写)

2) 在此 lambda 函数中,列出所有 DynamoDB 表。

3) 如果没有,则创建一个表。

4) 将 S3 对象的详细信息作为项目写入 DynamoDB。

我只让第 1 项工作。当它到达第 2 项时,我在下面遇到与权限相关的错误。

有什么帮助或建议吗?

我使用的权限是“Basic with DynamoDB”,具有以下权限:

START 请求 ID:e9ab5aba-307b-11e5-9663-3188c327cf5e 文件大小:1024,日期时间:1970-01-01T00:00:00.000Zs3Key:HappyFace.jpgAWS 凭证配置文件在给定路径中找不到:/home/sbx_user1052/.aws/credentials:java.lang.IllegalArgumentException java.lang.IllegalArgumentException:在给定路径中找不到 AWS 凭证配置文件:/home/sbx_user1052/.aws/credentials 在 com.amazonaws.auth.profile.internal.ProfilesConfigFileLoader.loadProfiles(ProfilesConfigFileLoader.java:45) 在 com.amazonaws.auth.profile.ProfilesConfigFile.loadProfiles(ProfilesConfigFile.java:176) 在 com.amazonaws.auth.profile.ProfilesConfigFile.(ProfilesConfigFile.java:112) 在 com.amazonaws.auth.profile.ProfilesConfigFile.(ProfilesConfigFile.java:92) 在 com.amazonaws.auth.profile.ProfileCredentialsProvider.getCredentials(ProfileCredentialsProvider.java:123) 在 com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:1763) 在 com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.listTables(AmazonDynamoDBClient.java:1208) 在 com.amazonaws.services.dynamodbv2.document.internal.ListTablesCollection.firstPage(ListTablesCollection.java:46) 在 com.amazonaws.services.dynamodbv2.document.internal.PageIterator.next(PageIterator.java:45) 在 com.amazonaws.services.dynamodbv2.document.internal.IteratorSupport.nextResource(IteratorSupport.java:79) 在 com.amazonaws.services.dynamodbv2.document.internal.IteratorSupport.hasNext(IteratorSupport.java:47) 在 com.TriggerDynamoDB.handleRequest(TriggerDynamoDB.java:68) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:497)

END 请求 ID:e9ab5aba-307b-11e5-9663-3188c327cf5e 报告请求 ID:e9ab5aba-307b-11e5-9663-3188c327cf5e 持续时间:3294.97 毫秒计费持续时间:3300 毫秒内存大小:512 MB 使用的最大内存:51 MB

代码如下:

public class TriggerDynamoDB implements RequestHandler<S3Event, String> {

public String handleRequest(S3Event s3event, Context context) {
     LambdaLogger logger = context.getLogger();
     try {           
         S3EventNotificationRecord record = s3event.getRecords().get(0);
         // Object key may have spaces or unicode non-ASCII characters.
         String srcKey = record.getS3().getObject().getKey().replace('+', ' ');
            srcKey = URLDecoder.decode(srcKey, "UTF-8");

         long fileSize = record.getS3().getObject().getSizeAsLong();
         DateTime datetime = record.getEventTime(); 

         logger.log("fileSize: " + fileSize + ", DateTime:" + datetime);
         logger.log("s3Key   : " + srcKey);

         DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
         //Table table = dynamoDB.getTable("dimensionFile");

         TableCollection<ListTablesResult> tables = dynamoDB.listTables();
         Iterator<Table> iterator = tables.iterator();

         while (iterator.hasNext()) { // this is where the error was thrown
             Table table = iterator.next();
             System.out.println(table.getTableName());
         }                    
         return "Ok";
     } catch (Exception e) {
         throw new RuntimeException(e);
     }
}
}

【问题讨论】:

    标签: java amazon-web-services amazon-s3 aws-lambda


    【解决方案1】:

    您传递给 AmazonDynamoDBClient 构造函数的 ProfileCredentialsProvider 尝试从 ~/.aws/credentials 文件加载凭证。此文件在运行 Lambda 函数的主机上不存在,因此出现异常。此提供程序主要用于在您的开发机器上运行并使用您的个人 IAM 用户凭证的集成测试等。

    在 Lambda 上,您需要 EnvironmentVariableCredentialsProvider。此提供程序将从 Lambda 在调用您的代码之前设置的环境变量中加载与您的 Lambda 函数关联的 IAM 角色的临时凭证。

    如果您对 Am​​azonDynamoDBClient 使用无参数构造函数,它将默认使用 DefaultAWSCredentialsProviderChain 来提取凭证。该提供程序检查环境变量、Java 系统属性、~/.aws/credentials 和 EC2 实例元数据服务(按此顺序),并且无论您是在本地运行还是在 Lambda 上运行,都应该获取凭证。

    【讨论】:

    • 嗨,大卫,没有参数的构造函数,我收到了一个不同的错误:com.amazonaws.AmazonServiceException:请求中包含的安全令牌无效。 (服务:AmazonDynamoDBv2;状态代码:400;错误代码:UnrecognizedClientException;请求 ID:BR5G9E5ITKCDCUAACUN17CRG93VV4KQNSO5AEMVJF66Q9ASUAAJG)
    • 如果我使用 InstanceProfileCredentialsProvider ,我收到另一个错误:com.amazonaws.AmazonClientException: Unable to load credentials from Amazon EC2 metadata service
    • 哦哦!我找到了根本原因和解决方案。在 lambda 容器中,凭据在 Environment 中可用,因此我只需要使用 EnvironmentVariableCredentialsProvider()。感谢大卫在这里提供线索!
    • 你能用“EnvironmentVariableCredentialsProvider()”帮助编辑你的答案吗?我会接受你的答案,因为你是在这个地方暗示的人。
    • 啊,太好了!我正在使用默认凭据提供程序链为我工作,所以我认为它是通过实例元数据服务获取它们的。编辑来了!
    【解决方案2】:

    您需要 dynamoDb listTables 操作权限。
    您还需要正确指定资源:作为 "*" 而不是 ""

    这是一个有效的策略,包括 ListTables:

    {“版本”:“2012-10-17”,“声明”:[{“Sid”: “Stmt1428341300017”,“动作”:[“dynamodb:DeleteItem”, “dynamodb:GetItem”、“dynamodb:PutItem”、“dynamodb:Query”、 “dynamodb:Scan”、“dynamodb:UpdateItem”、“dynamodb:ListTables”]、 “效果”:“允许”,“资源”:“”},{“Sid”:“”,“资源”:“”, “行动”:[“日志:CreateLogGroup”,“日志:CreateLogStream”, "logs:PutLogEvents" ], "Effect": "允许" } ] }

    另外,为了将来参考,请通读/尝试一下: http://docs.aws.amazon.com/IAM/latest/UserGuide/policies_testing-policies.html

    【讨论】:

    • 我在之前的测试中使用了“dynamoDb:ListTables”,但由于同样的原因它失败了。我认为这是一个不同的问题,因为错误消息听起来像是 lambda 根本找不到任何凭据文件。
    • “*”星号在那里,我想我用的是引号,它隐藏了*。我改为将 Json 更新为图片。不过,感谢您指出这一点。
    • 所以这对你来说仍然失败?
    • 是的,它失败了,仍然失败。我在下面的链接第 47 行检查了 aws 源代码,我想我一定有错误配置的东西,但我不知道它是什么:codatlas.com/github.com/aws/aws-sdk-java/HEAD/aws-java-sdk-core/…
    【解决方案3】:

    转到控制台主页 > IAM > 组 > 您的组 > 权限 > 附加策略

    添加 AmazonDynamoDBReadOnlyAccess、AWSLambdaInvocation-DynamoDB

    转到控制台主页 > IAM > 组 > 您的组 > 用户 > 将用户添加到组(在此处将您的用户添加到组)

    转到控制台主页 > IAM > 用户 > 您的用户 > 创建访问密钥

    BasicAWSCredentials b = new BasicAWSCredentials("Access Key ID","Secret Access Key");           
    AmazonDynamoDBClient client = new AmazonDynamoDBClient(b);
    

    【讨论】:

      【解决方案4】:

      相反

      new AmazonDynamoDBClient(new ProfileCredentialsProvider())
      

      使用

      AmazonDynamoDBClientBuilder.standard().build()
      

      此函数本身将从环境中获取凭据

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-05
        • 1970-01-01
        • 2016-05-04
        • 2020-03-09
        相关资源
        最近更新 更多