Serverless: Validation error ... Member must satisfy regular expression pattern: tablename - amazon-web-services

I am trying to deploy a serverless app on AWS cloud formation but I am getting a regular expression pattern error
Error:
CREATE_FAILED: UsersDynamoDBTable (AWS::DynamoDB::Table)
1 validation error detected:Value 'users-table-dev'' at 'tableName' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-zA-Z0-9_.-]+** (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 9OBFJ6RG2SKVIE58UTVAMNV7V7VV4KQNSO5AEMVJF66Q9ASUAAJG; Proxy: null)
What I can do to fix this?
# serverless.yml
service: serverless-flask
plugins:
- serverless-python-requirements
- serverless-wsgi
custom:
tableName: 'users-table-${self:provider.stage}'
wsgi:
app: app.app
packRequirements: false
pythonRequirements:
dockerizePip: non-linux
provider:
name: aws
runtime: python3.6
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": ["UsersDynamoDBTable", "Arn" ] }
environment:
USERS_TABLE: ${self:custom.tableName}
functions:
app:
handler: wsgi.handler
events:
- http: ANY /
- http: 'ANY {proxy+}'
resources:
Resources:
UsersDynamoDBTable:
Type: 'AWS::DynamoDB::Table'
Properties:
AttributeDefinitions:
-
AttributeName: userId
AttributeType: S
KeySchema:
-
AttributeName: userId
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:custom.tableName}
I am trying to implement the code here build a rest api with serverless lambda dynamo

For anybody experiencing the same issue, take a look at the tableName property. Instead of having the single quotes the line should look like that
tableName: `users-table-${self:provider.stage}`
Had the same minor error, it is easy to be overlooked.

Related

Runtime.ImportModuleError: Error: Cannot find module 'onCreateRadonData'

I am trying to deploy a DynamoDB stream as a lambda function using AppSync and Serverless. The deployment goes well, without any error. But when I trigger the lambda creating a new instance in my DynamoDB table, it fails throwing this error:
{
"errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module 'onCreateRadonData'\nRequire stack:\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js",
"stack": [
"Runtime.ImportModuleError: Error: Cannot find module 'onCreateRadonData'",
"Require stack:",
"- /var/runtime/UserFunction.js",
"- /var/runtime/index.js",
" at _loadUserApp (/var/runtime/UserFunction.js:100:13)",
" at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
" at Object.<anonymous> (/var/runtime/index.js:43:30)",
" at Module._compile (internal/modules/cjs/loader.js:999:30)",
" at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)",
" at Module.load (internal/modules/cjs/loader.js:863:32)",
" at Function.Module._load (internal/modules/cjs/loader.js:708:14)",
" at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)",
" at internal/main/run_main_module.js:17:47"
]
}
It is strange because, usually, I see this happens when importing some modules/dependencies in a bad way. But the function mentioned in the error onCreateRadonData is the name of the lambda itself, and in the deployment process, it is clearly shown that the deployment of the function went well, so I do not know what is going on...
The serverless.yaml file:
service: aws
plugins:
- serverless-appsync-plugin
- serverless-offline
provider:
name: aws
runtime: nodejs12.x
region: eu-west-1
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Scan
- dynamodb:Query
- dynamodb:PutItem
Resource:
- !GetAtt RadonDataTable.Arn
- !Join [ '', [ !GetAtt RadonDataTable.Arn, '/*' ] ]
- Effect: Allow
Action:
- appsync:GraphQL
Resource:
- !GetAtt GraphQlApi.Arn
- !Join [ '/', [ !GetAtt GraphQlApi.Arn, 'types', 'Mutation', 'fields', 'createRadonData' ] ]
custom:
appSync:
name: ${self:service}
authenticationType: AWS_IAM
mappingTemplates:
- dataSource: RadonData
type: Query
field: listRadonData
request: Query.listRadonData.request.vtl
response: Query.listRadonData.response.vtl
- dataSource: None
type: Mutation
field: createRadonData
request: Mutation.createRadonData.request.vtl
response: Mutation.createRadonData.response.vtl
schema: src/schema.graphql
dataSources:
- type: NONE
name: None
- type: AMAZON_DYNAMODB
name: RadonData
description: 'DynamoDB Radon Data table'
config:
tableName: !Ref RadonDataTable
functions:
handleDynamoDbStream:
maximumRetryAttempts: 1
maximumRecordAgeInSeconds: 1
handler: src/handlers/onCreateRadonData.handler
environment:
APP_SYNC_API_URL: !GetAtt GraphQlApi.GraphQLUrl
events:
- stream:
type: dynamodb
arn: !GetAtt RadonDataTable.StreamArn
resources:
Resources:
RadonDataTable:
Type: AWS::DynamoDB::Table
Properties:
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
StreamSpecification:
StreamViewType: NEW_IMAGE
And the lambda function onCreateRadonData.ts:
export const handler = (event) => {
console.log('Hello from lambda')
return;
}
NOTE: I've also tried the exports.handler = (event) ... way, but I throws the same error.
The code structure goes like this:
- src/handlers/onCreateRadonData.ts
- mapping-templates/files with mapping templates.vtl
- serverless.yml
- package.json
As You can see I have only one file named onCreateRadonData.ts inside the handlers folder in src. Thats all, the rest of the files are in the root directory.
Any ideas of what I am doing wrong? thank You all!
Okey guys I got it. Since I am using typescript I have to import the serverless-typescript plugin to convert all the ts files to js.

Amazon says I have a syntax error in this yml file, can anyone find it?

I am building a rest api with lambda and dynamodb.
I am typing sls deploy in the terminal which should deploy my function to aws but it gives me a syntax error and does not say where the error is.
Another file is create using the yml file which aws uses but I am posting the yml file as it is easier to read.
This is the yml file. I have been tinkering with it to get the syntax right but it still is not working.
The exact error is:
An error occurred: IamRoleLambdaExecution - Syntax errors in policy. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: b089926b-6d47-4111-9710-e3b6987fd8d7).
I can post the other file instead if that would make it easier to solve. Can anyone find the flaw in this file?
service: sls
custom:
settings:
POSTS_TABLE: posts
provider:
name: aws
runtime: nodejs12.x
environment: ${self:custom.settings}
region: eu-west-2
iamRoleStatements:
- Effect: "Allow"
Action:
- dynamodb: DescribeTable
- dynamodb: Scan
- dynamodb: GetItem
- dynamodb: PutItem
- dynamodb: UpdateItem
- dynamodb: DeleteItem
Resource:
- "arn:aws:dynamodb:${self:provider.region}:*:table/${self:custom.settings.POSTS_TABLE}"
functions:
createPost:
handler: handler.createPost
events:
- http:
path: /post
method: post
resources:
Resources:
PostsTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: "id"
AttributeType: "S"
KeySchema:
- AttributeName: "id"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:custom.settings.POSTS_TABLE}
A Likely reason is that correct actions names don't have spaces. Thus, instead of
- dynamodb: DescribeTable
- dynamodb: Scan
- dynamodb: GetItem
- dynamodb: PutItem
- dynamodb: UpdateItem
- dynamodb: DeleteItem
it should be
- dynamodb:DescribeTable
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem

IamRoleLambdaExecution - Syntax errors in policy

Facing Syntax IamRoleLambdaExecution - Syntax errors in policy. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: ********-****-****-****-************).
for the below serverless.yml file.
plugins:
- serverless-pseudo-parameters
provider:
name: aws
runtime: nodejs8.10
iamRoleStatements:
- Effect: Allow
Action:
- "dynamodb:PutItem"
- "dynamodb:GetItem"
Resource:
- arn:aws:dynamodb:#{AWS::Region}:#{AWS::AccountId}:table/ordersTable
- Effect: Allow
Action:
- kinesis: "PutRecord"
Resource:
- arn:aws:kinesis:#{AWS::Region}:#{AWS::AccountId}:stream/order-events
functions:
createOrder:
handler: handler.createOrder
events:
- http:
path: /order
method: post
environment:
orderTableName: ordersTable
orderStreamName: order-events
resources:
Resources:
orderEventsStream:
Type: AWS::Kinesis::Stream
Properties:
Name: order-events
ShardCount: 1
orderTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ordersTable
AttributeDefinitions:
- AttributeName: "orderId"
AttributeType: "S"
KeySchema:
- AttributeName: "orderId"
KeyType: "HASH"
BillingMode: PAY_PER_REQUEST```
serverless details:
- Framework Core: 1.71.3
- Plugin: 3.6.12
- SDK: 2.3.0
- Components: 2.30.11
Based on OP's feedback in the comment, changing kinesis: "PutRecord" to "kinesis: PutRecord" should work.

Serverless DynamoDB not showing in AWS Management Console

I'm learning the use of the Serverless framework to create and manage AWS services. I've stepped through deploying a Serverless project with the Docs on the Serverless site, but I'm not able to see the DynamoDB tables in the AWS Management Console for some reason.
I've checked that the AWS Profile I'm using is the correct one, and I'm able to post and get data from the table when I use the cURL from terminal, and am able to view data at those endpoints in a browser, but I'm not able to see any reference to the created table anywhere outside of serverless.yml file. Why is that? Please see the code below (full demo repo at this link: https://github.com/serverless/examples/tree/master/aws-node-rest-api-with-dynamodb).
Would appreciate your help in learning the nuances here. Thanks!
org: justinbell714
app: jb-test-from-docs
service: serverless-rest-api-with-dynamodb
frameworkVersion: ">=1.1.0 <2.0.0"
provider:
name: aws
runtime: nodejs10.x
environment:
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
functions:
create:
handler: todos/create.create
events:
- http:
path: todos
method: post
cors: true
list:
handler: todos/list.list
events:
- http:
path: todos
method: get
cors: true
get:
handler: todos/get.get
events:
- http:
path: todos/{id}
method: get
cors: true
update:
handler: todos/update.update
events:
- http:
path: todos/{id}
method: put
cors: true
delete:
handler: todos/delete.delete
events:
- http:
path: todos/{id}
method: delete
cors: true
resources:
Resources:
TodosDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
-
AttributeName: id
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE}
Make sure the region this is creating the tables in is the region you have selected in the AWS console.

UnhandledPromiseRejectionWarning: AccessDeniedException

provider:
name: aws
runtime: nodejs8.10
environment: ${self:custom.settings.${self:custom.myStage}}
plugins:
- serverless-webpack
- serverless-dynamodb-local
package:
individually: true
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
myStage: ${opt:stage, self:provider.stage}
settings:
dev:
ITEMS_DYNAMODB_TABLE: sls-basic-operations-items-dev
prod:
ITEMS_DYNAMODB_TABLE: sls-basic-operations-items-prod
iamRoleStatements:
- Effect: "Allow"
Action:
- "dynamodb:GetItem"
- "dynamodb:PutItem"
- "dynamodb:UpdateItem"
- "dynamodb:DeleteItem"
- "dynamodb:ListStreams"
Resource:
- "arn:aws:dynamodb:${self:provider.region}:*:table/${self:custom.settings.${self:custom.myStage}.ITEMS_DYNAMODB_TABLE}"
# you can overwrite defaults here
stage: dev
region: us-east-1
functions:
saveItem:
handler: handler.saveItem
events:
- http:
path: item
method: post
triggerStream:
handler: handler.triggerStream
events:
- stream:
type: dynamodb
batchSize: 1
startingPosition: LATEST
arn:
Fn::GetAtt:
- ImagesTable
- StreamArn
resources:
Resources:
ImagesTable:
Type: "AWS::DynamoDB::Table"
Properties:
AttributeDefinitions:
- AttributeName: "itemId"
AttributeType: "S"
KeySchema:
- AttributeName: "itemId"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:custom.settings.${self:custom.myStage}.ITEMS_DYNAMODB_TABLE}
StreamSpecification:
StreamViewType: NEW_IMAGE
The above YAML file I provided . I tried to connect with AWS Dynamo DB using AWS LAMBDA. But once I upload the project and tried to call save item function through postman it gives the following log on AWS cloud watch. I gave the both full administrative and dynamo DB access to the IAM User. Actually I am new to AWS and pardon my English
UnhandledPromiseRejectionWarning: AccessDeniedException: User: arn:aws:sts::247618643673:assumed-role/aws-nodejs-dev-us-east-1-lambdaRole/aws-nodejs-dev-saveItem is not authorized to perform: dynamodb:PutItem on resource: arn:aws:dynamodb:us-east-1:247618643673:table/sls-basic-operations-items-dev
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/json.js:51:27)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:78: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`enter code here`)
Your IAM role definitions should be configured under provider and not as a root property in your serverless.yml.
provider:
name: aws
runtime: nodejs8.10
environment: ${self:custom.settings.${self:custom.myStage}}
iamRoleStatements:
- Effect: "Allow"
Action:
- "dynamodb:GetItem"
- "dynamodb:PutItem"
- "dynamodb:UpdateItem"
- "dynamodb:DeleteItem"
- "dynamodb:ListStreams"
Resource:
- "arn:aws:dynamodb:${self:provider.region}:*:table/${self:custom.settings.${self:custom.myStage}.ITEMS_DYNAMODB_TABLE}"
If you want to be more granular, you can also put that in the function level.