Error deploying serverless : An error occurred: IamRoleLambdaExecution - Actions/Conditions must be prefaced by a vendor

I am using Serverless version 1.52, node version 10.16.

I am getting the below error while deploying the serverless app.

An error occurred: IamRoleLambdaExecution - Actions/Conditions must be prefaced by a vendor, e.g., iam, sdb, ec2, etc. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: 811c02ba-da31-11e9-812d-d97d855c6c5b).

Not sure from where it is coming. In cloudformation console also it is showing the same error. Please help.

I am using sls deploy command to deploy the app.

Below is my serverless.yaml file. Please help.

service: sls-notes-backend

plugins:
  - serverless-offline

custom:
  allowedHeaders:
    - Accept
    - Content-Type
    - Content-Length
    - app_user_id
    - app_user_name
    - Authorization

provider:
  name: aws
  runtime: nodejs10.x
  region: us-east-1
  stage: dev
  timeout: 6
  memorySize: 128
  endpointType: regional
  
  environment:
    NOTES_TABLE: ${self:service}-${opt.stage,self:provider.stage}
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb.Query
        - dynamodb.PutItem
        - dynamodb.DeleteItem
      Resource: "arn:aws:dynamodb:${opt:region,self:provider.region}:*:table/${self:provider.environment.NOTES_TABLE}"
functions:
  add-note:
    handler: api/add-note.handler
    description: POST /note
    events:
      - http:
          path: note
          method: post
          cors:
            origin: '*'
            headers: ${self:custom.allowedHeaders}
  update-note:
    handler: api/update-note.handler
    description: PATCH /note
    events:
      - http:
          path: note
          method: patch
          cors:
            origin: '*'
            headers: ${self:custom.allowedHeaders}
  get-notes:
    handler: api/get-notes.handler
    description: GET /notes
    events:
      - http:
          path: notes
          method: get
          cors:
            origin: '*'
            headers: ${self:custom.allowedHeaders}
  get-note:
    handler: api/get-note.handler
    description: GET /note/n/{note_id}
    events:
      - http:
          path: note/n/{note_id}
          method: get
          cors:
            origin: '*'
            headers: ${self:custom.allowedHeaders}
  delete-note:
    handler: api/delete-note.handler
    description: DELETE /note/t/{timestamp}
    events:
      - http:
          path: note/t/{timestamp}
          method: delete
          cors:
            origin: '*'
            headers: ${self:custom.allowedHeaders}

resources:
  Resources:
    NotesTable:
      Type: AWS::DynamoDB::Table
      DeletionPolicy: Retain
      Properties:
        TableName: ${self:provider.environment.NOTES_TABLE}
        AttributeDefinitions:
          - AttributeName: user_id
            AttributeType: S
          - AttributeName: timestamp
            AttributeType: N
          - AttributeName: note_id
            AttributeType: S
        KeySchema:
          - AttributeName: user_id
            KeyType: HASH
          - AttributeName: timestamp
            KeyType: RANGE
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        GlobalSecondaryIndexes:
          - IndexName: note_id-index
            KeySchema:
              - AttributeName: note_id
                KeyType: HASH
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 1
              WriteCapacityUnits: 1
1 Like

I’m guessing OP has figured this out since 2019, but for anyone facing this issue…

The Action specification uses colons (:slight_smile: and not period (.) to separate the service name and the specific action. The OP had this code:

Action:
        - dynamodb.Query
        - dynamodb.PutItem
        - dynamodb.DeleteItem

And that should have been this:

Action:
        - dynamodb:Query
        - dynamodb:PutItem
        - dynamodb:DeleteItem
2 Likes