0

Following alongside the tutorials, but changing some semantic things, I'm getting this error from serverless when I deploy:

An error occurred: GraphQlDsUsersRole - Syntax errors in policy. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: 4b486514-e57d-4828-9edc-f9150d8806b4; Proxy: null).

Doing a search on my directory, this role seems to be autogenerated into the .serverless file. How is this generated, and what could I have done to mess it up?

My serverless.yml file:

service: graphql-api

plugins:
  - serverless-appsync-plugin
  - serverless-pseudo-parameters

package:
  exclude:
    - node_modules/**
    - ./node_modules/**

provider:
  name: aws
  runtime: nodejs12.x
  region: us-east-1

custom:
  stage: dev
  appSync:
    name: ${self:service}-${self:custom.stage}
    authenticationType: API_KEY
    mappingTemplates:
      - dataSource: Users
        type: Query
        field: getUsers
        request: 'getUsers-request-mapping-template.txt'
        response: 'getUsers-response-mapping-template.txt'
    schema: schema.graphql
    dataSources:
      - type: AMAZON_DYNAMODB
        name: Users
        description: User Table
        config:
          tableName: { Ref: UserTable }
          serviceRoleARN: { Fn::GetAtt: [AppSyncDynamoDBServiceRole, Arn]}
          iamRoleStatements:
            - Effect: Allow
              Action:
                - 'dynamodb:*'
              Resources:
                - 'arn:aws:dynamodb:${self:provider.region}:#{AWS::AccountId}:table/Users'
                - 'arn:aws:dynamodb:${self:provider.region}:#{AWS::AccountId}:table/Users/*'

resources:
  - ${file(resources/roles.yml)}
  - ${file(resources/dynamodb.yml)}

My roles.yml file:

  AppSyncDynamoDBServiceRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: "Dynamo-${self:service}-Role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "appsync.amazonaws.com"
                - "dynamodb.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Policies:
        - PolicyName: "Dynamo-${self:service}-Policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Action:
                  - "dynamodb:Query"
                  - "dynamodb:BatchWriteItem"
                  - "dynamodb:GetItem"
                  - "dynamodb:DeleteItem"
                  - "dynamodb:PutItem"
                  - "dynamodb:Scan"
                  - "dynamodb:UpdateItem"
                Resource:
                  - "arn:aws:dynamodb:${self:provider.region}:#{AWS::AccountId}:table/Users"
                  - "arn:aws:dynamodb:${self:provider.region}:#{AWS::AccountId}:table/Users/*"

1 Answers1

0

Sorry for late response. Not sure if you found a solution yet, but I will answer anyway if that helps anyone

I notice 2 things here:

  • serviceRoleARN is misspelled. It should be serviceRoleArn
  • serviceRoleArn and iamRoleStatements are mutually exclusive. serviceRoleArn takes the ARN of a full already-existing role, while iamRoleStatements auto-generates the role for you with the provided policy statement. When both are provided, serviceRoleArn takes precedence.

So here, what what used was iamRoleStatements (because serviceRoleArn was misspelled).

The name of the generated resource confirms that: GraphQlDsUsersRole

As for why the policy is malformed, this is because Resource is misspelled too. It has to be singular (even if you pass an array).

Dharman
  • 30,962
  • 25
  • 85
  • 135
Benoît Bouré
  • 1,017
  • 9
  • 18