AccessDenied on DynamoDB GSI Index

for those in search of cloud formation

  PolicyDocument:
    Version: 2012-10-17
    Statement:
    - Effect: Allow
      Action:
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:DeleteItem
        - dynamodb:UpdateItem
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:BatchGetItem
        - dynamodb:BatchWriteItem
      Resource: [!GetAtt DialerDynamoDbTable.Arn, !Join [ '/',[!GetAtt DialerDynamoDbTable.Arn,index/*]]]

Resource: 
    - arn:aws:dynamodb:*:*:table/${self:custom.myTable}
    - arn:aws:dynamodb:*:*:table/${self:custom.myTable}/index/*

Your IAM role does not cover the indexes. Try to add them in the role's ressources:

iamRoleStatements:
   - Effect: Allow
     Action:
       - dynamodb:Query
       - dynamodb:Scan
       - dynamodb:GetItem
       - dynamodb:PutItem
       - dynamodb:UpdateItem
       - dynamodb:DeleteItem 
     Resource:        
       - { "Fn::GetAtt": ["DialerDynamoDbTable", "Arn" ] }
       - Fn::Join:
         - "/"
         -
           - { "Fn::GetAtt": ["DialerDynamoDbTable", "Arn" ] }
           - "index/*"

For reference, the Fn::Join will append /index/* to DialerDynamoDbTable's ARN.

It worked locally because Serverless uses the "admin" IAM user you configured it with.