cloudFormation Template Validation Error: how to split serverless.yml file - amazon-web-services

I ran into the notorious pain in the A$$ error: The CloudFormation template is invalid: Template format error: Number of resources, 202, is greater than maximum allowed, 200.
how do I split this into two, and cross reference the resources?
Could someone possibly share an example with me or show me how to split mine? I've been looking at aws docs and a tons of forums over the past few days to figure this out but I cant quite grasp what I need to do. I just need to be able to add more functions/api calls.
Serverless.yml
service: p-app-api
# Create an optimized package for our functions
package:
individually: true
plugins:
- serverless-bundle # Package our functions with Webpack
- serverless-offline
- serverless-dotenv-plugin
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: us-east-2
environment:
stripeSecretKey: ${env:STRIPE_SECRET_KEY}
# 'iamRoleStatements' defines the permission policy for the Lambda function.
# In this case Lambda functions are granted with permissions to access DynamoDB.
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/data"
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/data/index/zipCode-packageSelected-index"
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/data/index/jobId-index"
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/Service"
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/Service/index/index"
- Effect: Allow
Action:
- s3:*
Resource: "arn:aws:s3:::service/public/*"
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/Service"
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/data/index/packageSelected"
functions:
# Defines an HTTP API endpoint that calls the main function in create.js
# - path: url path is /notes
# - method: POST request
# - cors: enabled CORS (Cross-Origin Resource Sharing) for browser cross
# domain api call
# - authorizer: authenticate using the AWS IAM role
create:
handler: create.main
events:
- http:
path: data
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
get:
# Defines an HTTP API endpoint that calls the main function in get.js
# - path: url path is /notes/{id}
# - method: GET request
handler: get.main
events:
- http:
path: data/{id}
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
list:
# Defines an HTTP API endpoint that calls the main function in list.js
# - path: url path is /notes
# - method: GET request
handler: list.main
events:
- http:
path: data
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
update:
# Defines an HTTP API endpoint that calls the main function in update.js
# - path: url path is /notes/{id}
# - method: PUT request
handler: update.main
events:
- http:
path: data/{id}
method: put
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
delete:
# Defines an HTTP API endpoint that calls the main function in delete.js
# - path: url path is /notes/{id}
# - method: DELETE request
handler: delete.main
events:
- http:
path: data/{id}
method: delete
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
createCustomer:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: createCustomer.main
events:
- http:
path: createCustomer
method: post
cors: true
authorizer:
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
updateCustomer:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: updateCustomer.main
events:
- http:
path: updateCustomer
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
listCustomerCard:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: listCustomerCard.main
events:
- http:
path: listCustomerCard/{id}
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
deleteCard:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: DeleteCard.main
events:
- http:
path: deleteCard/{id}/{card}
method: delete
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
getCustomerInfo:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: getCustomerInfo.main
events:
- http:
path: getCustomerInfo/{id}
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
updateCustomerCard:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: updateCustomerCard.main
events:
- http:
path: updateCustomerCard/{id}
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
createInvoice:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: createInvoice.main
events:
- http:
path: createInvoice
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
deleteInvoice:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: deleteInvoice.main
events:
- http:
path: deleteInvoice/{id}
method: delete
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
listInvoices:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: listInvoices.main
events:
- http:
path: listInvoices/{id}
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
ListNewJobs:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: ListNewJobs.main
events:
- http:
path: data/ListNewJobs
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
jobIndex:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: jobIndex.main
events:
- http:
path: data/jobIndex
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
updateJobStatus:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: updateJobStatus.main
events:
- http:
path: data/jobStatus
method: put
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
createNewJob:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: createNewJob.main
events:
- http:
path: ServiceJobs/createNewJob
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
listMyNewJobs:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: listMyNewJobs.main
events:
- http:
path: ServiceJobs/listMyNewJobs
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
DeleteMyNewJob:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: DeleteMyNewJob.main
events:
- http:
path: ServiceJobs/DeleteMyNewJob/{id}
method: delete
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
UpdateServiceJobList:
# Defines an HTTP API endpoint that calls the main function in update.js
# - path: url path is /notes/{id}
# - method: PUT request
handler: UpdateServiceJobList.main
events:
- http:
path: ServicesJobs/Update
method: put
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
ServiceIndex:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: ServiceIndex.main
events:
- http:
path: ServiceJobs/ServiceIndex
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
UpdateMyJob:
# Defines an HTTP API endpoint that calls the main function in update.js
# - path: url path is /notes/{id}
# - method: PUT request
handler: UpdateMyJob.main
events:
- http:
path: ServiceJobs/UpdateMyJob
method: put
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
PayInvoiceStripe:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: PayInvoiceStripe.main
events:
- http:
path: stripe/PayInvoice
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
StripeNewContractorAccount:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: StripeNewContractorAccount.main
events:
- http:
path: stripe/NewContractorAccount
method: post
cors: true
authorizer:
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
serviceInfoPut:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: serviceInfoPut.main
events:
- http:
path: serviceInfo/post
method: post
cors: true
authorizer:
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
ListJobsForEdit:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: ListJobsForEdit.main
events:
- http:
path: data/index/packageSelected
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
# Create our resources with separate CloudFormation templates
resources:
# API Gateway Errors
- ${file(resources/api-gateway-errors.yml)}

What you want is using CloudFormation Nested Stacks, they allow you to reference another CloudFormation stack using the AWS::CloudFormation::Stack resource type.
You can then provide parameters as an input to your nested stacks and retrieve their outputs once they are deployed, this is how you communicate between main and sub stacks.
Below is an example of a nested stack reference.
AWSTemplateFormatVersion: "2010-09-09"
Resources:
MyNestedStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: "https://s3.amazonaws.com/cloudformation-templates-us-east-2/EC2ChooseAMI.template"
Parameters:
Param1: "a-value"
Param2: "another-value"
Note that TemplateURL can point to S3 Bucket links or to a file on your filesystem. Once you want to deploy your stacks, they need to be packaged using the AWS CLI.

serverless-plugin-split-stacks is the plugin to be use.
Docs is here : serverless split stack
it will help you to split the stack into nested stacks, max limit is 20.

Related

Serverless Framework How to Get Access, Id and Refresh Tokens from AWS Cognito

I am trying to secure my serverless NodeJS apis using AWS Cognito User Pools.
Below is a sample of my serverless framework configuration:
service: hello-world
frameworkVersion: '3'
provider:
name: aws
runtime: nodejs14.x
environment:
user_pool_id: { Ref: UserPool }
client_id: { Ref: UserClient }
iam:
role:
statements:
- Effect: Allow
Action:
- cognito-idp:AdminInitiateAuth
- cognito-idp:AdminCreateUser
- cognito-idp:AdminSetUserPassword
Resource: "*"
functions:
loginUser:
handler: ./auth/login.handler
events:
- http:
path: auth/login
method: post
cors: true
signupUser:
handler: ./auth/signup.handler
events:
- http:
path: auth/signup
method: post
cors: true
list:
handler: ./users/users.handler
events:
- http:
path: users/list
method: get
cors: true
authorizer:
type: COGNITO_USER_POOLS
authorizerId:
Ref: ApiGatewayAuthorizer
resources:
Resources:
ApiGatewayAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: CognitoUserPool
Type: COGNITO_USER_POOLS
IdentitySource: method.request.header.Authorization
RestApiId:
Ref: ApiGatewayRestApi
ProviderARNs:
- Fn::GetAtt:
- UserPool
- Arn
UserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: serverless-auth-pool
Schema:
- Name: email
Required: true
Mutable: true
Policies:
PasswordPolicy:
MinimumLength: 6
AutoVerifiedAttributes: ["email"]
UserClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: user-pool-ui
GenerateSecret: false
UserPoolId: { Ref: UserPool }
AccessTokenValidity: 1
IdTokenValidity: 1
ExplicitAuthFlows:
- "ADMIN_NO_SRP_AUTH"
I can successfully can call the signup and login endpoints to get a token and then use this token as an Authorization header to call my /users/list endpoint to get a list of users.
My problem is that I was expecting the login endpoint to return 3 tokens - an id token, an access token and a refresh token.
The login endpoint currently only returns one token that has a claim of:
"token_use": "id"
If I pass this token to the /users/list api then it is successfully validated, but I thought that the api would need the access token instead of the id token for authentication.
Does anyone know if my assumption is correct and how to fix the issue or have I misunderstood how the auth flow works ?

Split serverless.yml file

How would I split this serverless.yml file into two .yml files?
I hit the cloudFormation template validation error... " Number of resources, 202, is greater than the maximum allowed, 200"
Ive been stuck on this for 5 days now and cant go any further with my application until I fix this issue.
How could I split up these services into different YML files with a main YML file?
Serverless.yml
service: p-app-api
# Create an optimized package for our functions
package:
individually: true
plugins:
- serverless-bundle # Package our functions with Webpack
- serverless-offline
- serverless-dotenv-plugin
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: us-east-2
environment:
stripeSecretKey: ${env:STRIPE_SECRET_KEY}
# 'iamRoleStatements' defines the permission policy for the Lambda function.
# In this case Lambda functions are granted with permissions to access DynamoDB.
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/data"
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/data/index/zipCode-packageSelected-index"
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/data/index/jobId-index"
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/Service"
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/Service/index/index"
- Effect: Allow
Action:
- s3:*
Resource: "arn:aws:s3:::service/public/*"
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/Service"
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
Resource: "arn:aws:dynamodb:us-east-2:433684495079:table/data/index/packageSelected"
functions:
# Defines an HTTP API endpoint that calls the main function in create.js
# - path: url path is /notes
# - method: POST request
# - cors: enabled CORS (Cross-Origin Resource Sharing) for browser cross
# domain api call
# - authorizer: authenticate using the AWS IAM role
create:
handler: create.main
events:
- http:
path: data
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
get:
# Defines an HTTP API endpoint that calls the main function in get.js
# - path: url path is /notes/{id}
# - method: GET request
handler: get.main
events:
- http:
path: data/{id}
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
list:
# Defines an HTTP API endpoint that calls the main function in list.js
# - path: url path is /notes
# - method: GET request
handler: list.main
events:
- http:
path: data
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
update:
# Defines an HTTP API endpoint that calls the main function in update.js
# - path: url path is /notes/{id}
# - method: PUT request
handler: update.main
events:
- http:
path: data/{id}
method: put
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
delete:
# Defines an HTTP API endpoint that calls the main function in delete.js
# - path: url path is /notes/{id}
# - method: DELETE request
handler: delete.main
events:
- http:
path: data/{id}
method: delete
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
createCustomer:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: createCustomer.main
events:
- http:
path: createCustomer
method: post
cors: true
authorizer:
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
updateCustomer:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: updateCustomer.main
events:
- http:
path: updateCustomer
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
listCustomerCard:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: listCustomerCard.main
events:
- http:
path: listCustomerCard/{id}
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
deleteCard:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: DeleteCard.main
events:
- http:
path: deleteCard/{id}/{card}
method: delete
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
getCustomerInfo:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: getCustomerInfo.main
events:
- http:
path: getCustomerInfo/{id}
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
updateCustomerCard:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: updateCustomerCard.main
events:
- http:
path: updateCustomerCard/{id}
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
createInvoice:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: createInvoice.main
events:
- http:
path: createInvoice
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
deleteInvoice:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: deleteInvoice.main
events:
- http:
path: deleteInvoice/{id}
method: delete
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
listInvoices:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: listInvoices.main
events:
- http:
path: listInvoices/{id}
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
ListNewJobs:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: ListNewJobs.main
events:
- http:
path: data/ListNewJobs
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
jobIndex:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: jobIndex.main
events:
- http:
path: data/jobIndex
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
updateJobStatus:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: updateJobStatus.main
events:
- http:
path: data/jobStatus
method: put
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
createNewJob:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: createNewJob.main
events:
- http:
path: ServiceJobs/createNewJob
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
listMyNewJobs:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: listMyNewJobs.main
events:
- http:
path: ServiceJobs/listMyNewJobs
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
DeleteMyNewJob:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: DeleteMyNewJob.main
events:
- http:
path: ServiceJobs/DeleteMyNewJob/{id}
method: delete
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
UpdateServiceJobList:
# Defines an HTTP API endpoint that calls the main function in update.js
# - path: url path is /notes/{id}
# - method: PUT request
handler: UpdateServiceJobList.main
events:
- http:
path: ServicesJobs/Update
method: put
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
ServiceIndex:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: ServiceIndex.main
events:
- http:
path: ServiceJobs/ServiceIndex
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
UpdateMyJob:
# Defines an HTTP API endpoint that calls the main function in update.js
# - path: url path is /notes/{id}
# - method: PUT request
handler: UpdateMyJob.main
events:
- http:
path: ServiceJobs/UpdateMyJob
method: put
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
PayInvoiceStripe:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: PayInvoiceStripe.main
events:
- http:
path: stripe/PayInvoice
method: post
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
StripeNewContractorAccount:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: StripeNewContractorAccount.main
events:
- http:
path: stripe/NewContractorAccount
method: post
cors: true
authorizer:
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
serviceInfoPut:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: serviceInfoPut.main
events:
- http:
path: serviceInfo/post
method: post
cors: true
authorizer:
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
ListJobsForEdit:
# Defines an HTTP API endpoint that calls the main function in billing.js
# - path: url path is /billing
# - method: POST request
handler: ListJobsForEdit.main
events:
- http:
path: data/index/packageSelected
method: get
cors: true
authorizer: aws_iam
arn: aws:cognito-idp:us-east-2:433684495079:userpool/us-east-2_Q0sUvw4Qy
# Create our resources with separate CloudFormation templates
resources:
# API Gateway Errors
- ${file(resources/api-gateway-errors.yml)}
I've had some good success using the serverless-plugin-split-stacks plugin.
You can split your stacks by a few methods, but I'd imagine for your situation, you'd want to split per Lambda

How to create a resourse of API-Gatway authorizer, in serverless

I using a cognito authorizer im my API, and using serverless to configure the api. For add a autorizer to a funcitions, i found this code (How to configure my Serverless YML to use my API Gateway Authorizer?):
teste:
handler: handler.teste
memorySize: 128
events:
- http:
path: teste
method: get
authorizer:
name: api-authorizer
arn: arn:aws:cognito-idp:XXXXXXXXX:XXXXXXXXXX:userpool/XXXXXXX_XXXXXXX
type: token
this code works very nice, but i need repeat a same authorizer in multiple functions, and using this code, for each function a new authorizer is create.... this is a waste of resourse and generete a mess in AWS console
For resolve this problem i try this:
teste:
handler: handler.teste
memorySize: 128
events:
- http:
path: teste
method: get
authorizer: myAuthorizer
resources:
Resources:
myAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: "testing"
arn: arn:aws:cognito-idp:XXXXXXXXX:XXXXXXXXXX:userpool/XXXXXXX_XXXXXXX
authorizerId:
Ref: api-authorizer
But don't have success, and i didn't found documentations or guides for this.
In my opinion, it's not big of a deal to have the authorizer section repeated. In my case, it makes sense to have it repeated since we are using scopes.
listItems:
handler: handler.listItems
events:
- http:
method: get
path: /list-items
authorizer:
arn: ${self:custom.vars.${self:custom.vars.stage}.userPoolArn}
scopes:
- transactions/read
writeItem:
handler: handler.writeItem
events:
- http:
method: post
path: /write-item
authorizer:
arn: ${self:custom.vars.${self:custom.vars.stage}.userPoolArn}
scopes:
- transactions/write
But if you would like to share an authorizer it's here.
resources:
Resources:
ApiGatewayAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
AuthorizerResultTtlInSeconds: 300
IdentitySource: method.request.header.Authorization
Name: Cognito
RestApiId:
Ref: YourApiGatewayName
Type: COGNITO_USER_POOLS
ProviderARNs:
- arn:aws:cognito-idp:${self:provider.region}:xxxxxx:userpool/abcdef
functions:
deleteUser:
...
events:
- http:
path: /users/{userId}
...
# Provide both type and authorizerId
type: COGNITO_USER_POOLS # TOKEN or REQUEST or COGNITO_USER_POOLS, same as AWS Cloudformation documentation
authorizerId:
Ref: ApiGatewayAuthorizer # or hard-code Authorizer ID
Reference:
https://serverless.com/framework/docs/providers/aws/events/apigateway/#share-authorizer
What you are looking for is a certain type of API Gateway Authorizer, a Cognito Authorizer. These are specifically for authenticating users from a Cognito User Pool.
To use a Cognito Authorizer with serverless your serverless.yml could look something like this:
teste:
handler: handler.teste
memorySize: 128
events:
- http:
path: teste
method: get
authorizer:
arn: arn:aws:cognito-idp:XXXXXXXXX:XXXXXXXXXX:userpool/XXXXXXX_XXXXXXX
You aren't required to send the authorizer name or type when using a Cogntio Authorizer. Additionally, the arn should be pointing to your Cognito User Pool, which the one in your example appears to be.
Checkout the serverless documentation topic on custom authorizers if you want any more information or examples.

Attach bucket policy to bucket generated by serverless

I'm attempting to create an S3 bucket with serverless, which works, however in order to manipulate files in it I need a bucket policy. I'm having a hard time understanding where and how to add a policy that uses the generated S3bucket name created when serverless deploys for the first time
##serverless.yml##
service: vcc-nametags-api
# Use the serverless-webpack plugin to transpile ES6
plugins:
- serverless-webpack
- serverless-offline
- serverless-ding
# serverless-webpack configuration
# Enable auto-packing of external modules
custom:
# Our stage is based on what is passed in when running serverless
# commands. Or fallsback to what we have set in the provider section.
stage: ${opt:stage, self:provider.stage}
# Set our DynamoDB throughput for prod and all other non-prod stages.
# Load our webpack config
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
environment: ${file(env.yml):${self:custom.stage}, file(env.yml):default}
provider:
name: aws
runtime: nodejs8.10
stage: dev
region: us-east-1
# These environment variables are made available to our functions
# under process.env.
environment:
S3DBBucketName:
Ref: NametagsDatabaseBucket
functions:
# Defines an HTTP API endpoint that calls the main function in create.js
# - path: url path is /tags
# - method: POST request
# - cors: enabled CORS (Cross-Origin Resource Sharing) for browser cross
# domain api call
# - authorizer: authenticate using the AWS IAM role
create:
handler: create.main
events:
- http:
path: tags
method: post
cors: true
get:
# Defines an HTTP API endpoint that calls the main function in get.js
# - path: url path is /tags/{id}
# - method: GET request
handler: get.main
events:
- http:
path: tags/{id}
method: get
cors: true
list:
# Defines an HTTP API endpoint that calls the main function in list.js
# - path: url path is /tags
# - method: GET request
handler: list.main
events:
- http:
path: tags
method: get
cors: true
update:
# Defines an HTTP API endpoint that calls the main function in update.js
# - path: url path is /tags/{id}
# - method: PUT request
handler: update.main
events:
- http:
path: tags/{id}
method: put
cors: true
delete:
# Defines an HTTP API endpoint that calls the main function in delete.js
# - path: url path is /tags/{id}
# - method: DELETE request
handler: delete.main
events:
- http:
path: tags/{id}
method: delete
cors: true
# Create our resources with separate CloudFormation templates
resources:
# S3DB
- ${file(resources/s3-database.yml)}
##s3-database.yml##
Resources:
NametagsDatabaseBucket:
Type: AWS::S3::Bucket
Properties:
# Set the CORS policy
CorsConfiguration:
CorsRules:
-
AllowedOrigins:
- '*'
AllowedHeaders:
- '*'
AllowedMethods:
- GET
- PUT
- POST
- DELETE
- HEAD
MaxAge: 3000
NametagsDatabaseBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: NametagsDatabaseBucket
PolicyDocument:
Statement:
- Sid: PublicReadGetObject
Effect: Allow
Principal: "*"
Action:
- "s3:DeleteObject"
- "s3:GetObject"
- "s3:ListBucket"
- "s3:PutObject"
Resource:
Fn::Join: [
"", [
"arn:aws:s3:::",
{
"Ref": "NametagsDatabaseBucket"
},
"/*"
]
]
# Print out the name of the bucket that is created
Outputs:
NametagsDatabaseBucketName:
Value:
Ref: NametagsDatabaseBucket
I've tried various combinations I've found on the internet as well as adding it to an iamroles property in the serverless.yml file but I can't seem to get anything to work
The Resource Reference Name seems to matter, I have always had to use the name of the bucket in the resource name. For example, a bucket with www.example.com needs a reference name of S3BucketWwwexamplecom.
However I also notice that the BucketName element is missing from your example.
This is from working example for a static website with a Bucket Policy:
resources:
Resources:
S3BucketWwwexamplecom:
Type: AWS::S3::Bucket
DeletionPolicy: Delete
Properties:
BucketName: ${self:custom.s3WwwBucket}
CorsConfiguration:
CorsRules:
- AllowedMethods:
- PUT
- GET
- POST
- HEAD
AllowedOrigins:
- "https://${self:custom.myDomain}"
AllowedHeaders:
- "*"
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html
BucketPolicyWwwexamplecom:
Type: 'AWS::S3::BucketPolicy'
Properties:
PolicyDocument:
Statement:
- Sid: PublicReadForGetBucketObjects
Effect: Allow
Principal: '*'
Action:
- 's3:GetObject'
Resource: arn:aws:s3:::${self:custom.s3WwwBucket}/*
Bucket:
Ref: S3BucketWwwexamplecom
Since you are using a lambda to upload you should create an IAM Role for your Lambda and an IAM Policy with only the permissions required for operation. You might accomplish this by using the following excerpt in your cloud formation:
AWSTemplateFormatVersion: '2010-09-09'
Description: My Template
Resources:
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
RoleName: !Sub ${AWS::StackName}-LambdaRole
S3Policy:
Type: AWS::IAM::Policy
Properties:
PolicyName: S3_Writer
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:*
Resource: !Sub
- arn:aws:s3:::${BucketName}/*
- BucketName: !Ref NametagsDatabaseBucket
Roles:
- !Ref TaskRole
Outputs:
LambdaRole:
Value: !Sub "${LambdaRole.Arn}"
Export:
Name: !Sub ${AWS::StackName}-LambdaRole
Then in your serverless.yml just refer to the task role created using something like this to reference the execution role:
service: vcc-nametags-api
provider:
role: ${cf:${env:YOUR_STACK_ENV, 'YOUR_STACK_NAME'}.LambdaRole}
We have a setup like this working in several projects, I hope it works for you.

Is it possible to set request authorization in 'serverless.yml' file with Serverless 1.0.0-beta.1.1?

I just tried version .1.0.0-beta.1.1 of Serverless, which looks very promising.
I wish to authentify requests, using AWS_IAM.
I can use the AWS Gateway API console, and change each method request from none to AWS_IAM. By hand, I can make it work.
However, I would rather change the serverless.yml file in my Serverless services.
I tried to add an authorizationType field like so:
- http:
path: greet
method: get
authorizationType: AWS_IAM
but it did not update the authorization settings of API Gateway, and unauthorized requests are still accepted.
Any idea if the serverless.yml file can be set to use AWS_IAM?
In serverless 1.0.0-RC2 you can set the authorizationType as follows
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
resources:
Resources:
ApiGatewayMethodHelloGet:
Properties:
AuthorizationType: AWS_IAM
Checkout the following link for the closest I found on help with authentication:
https://github.com/serverless/serverless/blob/85f4084e6b0fd4a6d763ace8cd0db82817bbc712/lib/plugins/aws/deploy/compile/events/apiGateway/README.md#http-setup-with-custom-authorizer
I have not used AWS_IAM, but here is how I define a CUSTOM authentication, which should indicate the overall format.
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
authorizer:
arn: arn:aws:lambda:us-east-1:xxxxxx:function:jwtAuthorize
resultTtlInSeconds: 0
identitySource: method.request.header.Authorization
identityValidationExpression: JWT [^\.]+\.[^\.]+\.[^\.]+
Therefore, I think you need to add the authorizer section. I cannot test this, but let me know if it does not work this way:
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
authorizer:
authorizationType: AWS_IAM