首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >DynamoDB w/ Serverless,使用Fn::GetRef引用全局二级索引

DynamoDB w/ Serverless,使用Fn::GetRef引用全局二级索引
EN

Stack Overflow用户
提问于 2018-06-03 06:43:20
回答 3查看 4K关注 0票数 7

我有一个用DynamoDB表定义的API/服务。我有几个索引(定义为全局二级索引)来支持几个查询。我设计了表,带有GSI定义,以及看起来正确的查询。然而,在执行查询时,我得到了这个异常:

代码语言:javascript
复制
{ AccessDeniedException: User: arn:aws:sts::OBSCURED:assumed-role/chatroom-application-dev-us-east-1-lambdaRole/chatroom-application-dev-getRoomMessages is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-east-1:OBSCURED:table/messages-table-dev/index/roomIndex
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/json.js:48:27)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
message: 'User: arn:aws:sts::OBSCURED:assumed-role/chatroom-application-dev-us-east-1-lambdaRole/chatroom-application-dev-getRoomMessages is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-east-1:OBSCURED:table/messages-table-dev/index/roomIndex',
code: 'AccessDeniedException',
time: 2018-06-02T22:05:46.110Z,
requestId: 'OBSCURED',
statusCode: 400,
retryable: false,
retryDelay: 30.704899664776054 }

在异常的顶部,它显示了我的getRoomMessages方法is not authorized to perform: dynamodb:Query on resource:的ARN,并显示了全局二级索引的ARN。

很明显,我需要定义策略来授予访问全局二级索引的权限。但目前还不清楚是如何做到的。我还看到过其他关于DynamoDB的StackOverflow问题,他们抱怨文档很零散,很难找到任何东西。我不得不同意。“碎片化”这个词说得太温和了。

我使用的是无服务器框架。provider部分显示此策略/角色定义:

代码语言:javascript
复制
provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: us-east-1
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource:
        - { "Fn::GetAtt": ["MessagesDynamoDBTable", "Arn" ] }
        - { "Fn::GetAtt": ["#roomIndex", "Arn" ] }
        - { "Fn::GetAtt": ["#userIndex", "Arn" ] }
  environment:
    MESSAGES_TABLE: ${self:custom.tableName}

Resource部分,我想我应该列出声明了权限的资源。第一个引用表作为一个整体。最后两个是我刚刚添加的,并引用了索引。

编辑:当我运行serverless deploy时,打印以下消息:

代码语言:javascript
复制
The CloudFormation template is invalid: Template error: instance of Fn::GetAtt references undefined resource #roomIndex

我对此尝试了几个变体,但都得到了相同的错误。这可以归结为-如何在使用Cloudfront语法的 serverless.yml**,中获取索引的ARN **。ARN确实存在,因为它显示在异常中。

DynamoDB表定义:

代码语言:javascript
复制
resources:
  Resources:
    MessagesDynamoDBTable:
      Type: AWS::DynamoDB::Table
      Properties:
        AttributeDefinitions:
          - AttributeName: messageId
            AttributeType: S
          - AttributeName: room
            AttributeType: S
          - AttributeName: userId
            AttributeType: S
        KeySchema:
          - AttributeName: messageId
            KeyType: HASH
        GlobalSecondaryIndexes:
          - IndexName: roomIndex
            KeySchema:
              - AttributeName: room
                KeyType: HASH
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 1
              WriteCapacityUnits: 1
          - IndexName: userIndex
            KeySchema:
              - AttributeName: userId
                KeyType: HASH
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 1
              WriteCapacityUnits: 1
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: ${self:custom.tableName}

以上异常所对应的查询:

代码语言:javascript
复制
{
    "TableName": "messages-table-dev",
    "IndexName": "roomIndex",
    "KeyConditionExpression": "#roomIndex = :room",
    "ExpressionAttributeNames": {
        "#roomIndex": "room"
    },
    "ExpressionAttributeValues": {
        ":room": {
            "S": "everyone"
        }
    }
}

以及生成查询的Lambda函数代码片段:

代码语言:javascript
复制
app.get('/messages/room/:room', (req, res) => {
    const params = {
        TableName: MESSAGES_TABLE,
        IndexName: "roomIndex",
        KeyConditionExpression: '#roomIndex = :room',
        ExpressionAttributeNames: { '#roomIndex': 'room' },
        ExpressionAttributeValues: {
            ":room": { S: `${req.params.room}` }
        },
    };
    console.log(`QUERY ROOM ${JSON.stringify(params)}`);
    dynamoDb.query(params, (error, result) => {
        if (error) {
            console.log(error);
            res.status(400).json({ error: 'Could not get messages' });
        } else {
            res.json(result.Items);
        }
    });
});
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50661792

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档