I am developing an AWS Lambda application. This is a REST API, so i am using AWS Lambda, API Gateway and AWS RDS. I am using aws sam for the deployment and all.
I have 193 end points in my REST API, which means 193 Lambda functions. When i try to deploy this, I got the following error message.
Waiting for changeset to be created..
Error: Failed to create changeset for the stack: aaa-restapi, ex: Waiter ChangeSetCreateComplete failed:
Waiter encountered a terminal failure state: For expression "Status" we matched expected path:
"FAILED" Status: FAILED. Reason: Template format error:
Number of resources, 583, is greater than maximum allowed, 500
Below is a small part of my template.yaml. Please note in below code the only thing I am removing is over 100 Lambda functions. All Lambda functions looks the same and no difference except the end point they are opening for the REST API. Everything else is there.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
Globals:
Function:
Timeout: 30
VpcConfig:
SecurityGroupIds:
- sg-041f2459xxx921e8e
SubnetIds:
- subnet-03xxdb2d
- subnet-c4dxx4cb
- subnet-af5xxx8
- subnet-748xxf28
- subnet-d13xxx9c
- subnet-e9exxxx7
Resources:
GetAllAccountingTypesFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-getall.getallaccountingtypes
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api
Properties:
Path: /accountingtypes/getall
Method: get
GetAccountingTypeByIDFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-byid.getbyid
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api
Properties:
Path: /accountingtypes/getbyid
Method: get
GetUserRoleByIDFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-getbyid.getUserRoleByID
Runtime: nodejs14.x
Events:
GetUserRoleByIDAPIEvent:
Type: Api
Properties:
Path: /userrole/getbyid
Method: get
GetUserRoleByUserFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-getbyuser.getUserRoleByUser
Runtime: nodejs14.x
Events:
GetUserRoleByUserAPIEvent:
Type: Api
Properties:
Path: /userrole/getbyuser
Method: get
GetUserRoleByRoleFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-getbyrole.getAllUsersByRole
Runtime: nodejs14.x
Events:
GetUserRoleByRoleAPIEvent:
Type: Api
Properties:
Path: /userrole/getbyrole
Method: get
SaveUserRoleFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-save.saveUserRole
Runtime: nodejs14.x
Events:
SaveUserRoleAPIEvent:
Type: Api
Properties:
Path: /userrole/save
Method: post
UpdateUserRoleFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-update.updateeUserRole
Runtime: nodejs14.x
Events:
UpdateUserRoleAPIEvent:
Type: Api
Properties:
Path: /userrole/update
Method: post
LambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:DescribeNetworkInterfaces
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
- ec2:DescribeInstances
- ec2:AttachNetworkInterface
Resource: '*'
Outputs:
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for functions"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
I looked into the internet and figured out I need to do nested stacks. In all the tutorials I watched they are talking about dividing your stack into security, network, administration bla bla bla. I do not need any of them, this is a simple REST API and all what I need is to get this deployed without hitting the AWS Limit errors..
I do not understand how to implement nested stacks with my code. Taking my above code as an example, can someone show me how to implement nested stacks into that? Then I can look at the code, learn from the there and implement this to the complete application.
----------------UPDATE-------------------
As per the Robert's advice, I managed to make nested stacks. However we have a problem. It created different API Gateway URLs for each stack. But I want just a one API Gateway URL. Below is my code.
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2459dcd921e8e
SubnetIds:
- subnet-0381db2d
- subnet-c4d5c4cb
- subnet-af5c03c8
- subnet-7487df28
- subnet-d139d69c
- subnet-e9e88bd7
Resources:
GetAllAccountingTypesFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-getall.getallaccountingtypes
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /accountingtypes/getall
Method: get
GetAccountingTypeByIDFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-byid.getbyid
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /accountingtypes/getbyid
Method: get
# DependsOn: GetAllAccountingTypesFunction
NestedStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: template_user.yaml
LambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:DescribeNetworkInterfaces
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
- ec2:DescribeInstances
- ec2:AttachNetworkInterface
Resource: '*'
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for functions"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
template_user.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2****cd921e8e
SubnetIds:
- subnet-03***b2d
- subnet-c4d***cb
- subnet-af5***8
- subnet-74***f28
- subnet-d139***c
- subnet-e9***bd7
Resources:
GetUserRoleByIDFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-getbyid.getUserRoleByID
Runtime: nodejs14.x
Events:
GetUserRoleByIDAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/getbyid
Method: get
GetUserRoleByUserFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-getbyuser.getUserRoleByUser
Runtime: nodejs14.x
Events:
GetUserRoleByUserAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/getbyuser
Method: get
# DependsOn: GetUserRoleByIDFunction
GetUserRoleByRoleFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-getbyrole.getAllUsersByRole
Runtime: nodejs14.x
Events:
GetUserRoleByRoleAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/getbyrole
Method: get
#DependsOn: GetUserRoleByUserFunction
SaveUserRoleFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-save.saveUserRole
Runtime: nodejs14.x
Events:
SaveUserRoleAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/save
Method: post
# DependsOn: GetUserRoleByRoleFunction
UpdateUserRoleFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-update.updateeUserRole
Runtime: nodejs14.x
Events:
UpdateUserRoleAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/update
Method: post
#DependsOn: SaveUserRoleFunction
In this example I have two stacks and API Gateway did create 2 URLs.
template.yaml URL - https://ez5khz***.execute-api.us-east-1.amazonaws.com/Prod/
template_user.yaml URL - https://7imy9b6***.execute-api.us-east-1.amazonaws.com/Prod/
I want the URL that was made with template.yaml to be applied to all lambda functions, regardless of which nested stack it is in. I also have a plan to later assign a domain into this.
How I can get this to work under a one URL?
You can use the Cloudformation Stack Resource to implement nested Stacks in CloudFormation. The template url will be resolved by using the Cloudformation Package command.
CodeExample:
NestedStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: ./src/nested-stack/infrastructure.yml
Edit: And maybe you should merge some endpoints into one Lambda and use something like express for the routing.
Related
I am using Cloudformation and aws-sam. When building/deploying the app, is there any way to count the number of resources being created? For an example, I have a REST API project following serverless architecture, it only has 193 functions under the Resources element. But this actually generated 583 resources. I also got to know this because it hit the aws stack resource limit and AWS displayed an error message.
Therefor I am wondering whether there is a way we can know the number of real resources being created.
Below is a sample template I made.
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2xxxd921e8e
SubnetIds:
- subnet-03xxxb2d
- subnet-c4dxxxcb
Resources:
GetAllAccountingTypesFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-getall.getallaccountingtypes
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /accountingtypes/getall
Method: get
RestApiId:
Ref: ApiGatewayApi
GetAccountingTypeByIDFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-byid.getbyid
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /accountingtypes/getbyid
Method: get
RestApiId:
Ref: ApiGatewayApi
LambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:DescribeNetworkInterfaces
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
- ec2:DescribeInstances
- ec2:AttachNetworkInterface
Resource: '*'
Outputs:
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for functions"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
You can use the sam CLI to transform the template via sam validate --debug --template yourtempatefile.yaml The transformed template is output to stderr along with other debug messages.
This bash oneliner works for me to count the resources.
$ sam validate --debug --template mytemplate.yaml 2>&1 | egrep '^ Properties:' | wc -l
Not to my knowledge, but what may help you is this SAM Serverless Function reference, which tells you which resources will be generated implicitly when some properties are not specified.
With this in mind you can calculate the amount of resources actually being created.
I am developing a REST API using AWS Lambda, API Gateway and CloudFormation. I hit the Cloudformation 500 resources limit, so I had to go for nested stacks. Below is what I tried.
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2459dcd921e8e
SubnetIds:
- subnet-0381db2d
- subnet-c4d5c4cb
- subnet-af5c03c8
- subnet-7487df28
- subnet-d139d69c
- subnet-e9e88bd7
Resources:
GetAllAccountingTypesFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-getall.getallaccountingtypes
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /accountingtypes/getall
Method: get
GetAccountingTypeByIDFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-byid.getbyid
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /accountingtypes/getbyid
Method: get
# DependsOn: GetAllAccountingTypesFunction
NestedStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: template_user.yaml
NestedStackTwo:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: template_two.yaml
LambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:DescribeNetworkInterfaces
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
- ec2:DescribeInstances
- ec2:AttachNetworkInterface
Resource: '*'
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for functions"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
template_user.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2****cd921e8e
SubnetIds:
- subnet-03***b2d
- subnet-c4d***cb
- subnet-af5***8
- subnet-74***f28
- subnet-d139***c
- subnet-e9***bd7
Resources:
GetUserRoleByIDFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-getbyid.getUserRoleByID
Runtime: nodejs14.x
Events:
GetUserRoleByIDAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/getbyid
Method: get
GetUserRoleByUserFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-getbyuser.getUserRoleByUser
Runtime: nodejs14.x
Events:
GetUserRoleByUserAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/getbyuser
Method: get
# DependsOn: GetUserRoleByIDFunction
GetUserRoleByRoleFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-getbyrole.getAllUsersByRole
Runtime: nodejs14.x
Events:
GetUserRoleByRoleAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/getbyrole
Method: get
#DependsOn: GetUserRoleByUserFunction
SaveUserRoleFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-save.saveUserRole
Runtime: nodejs14.x
Events:
SaveUserRoleAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/save
Method: post
# DependsOn: GetUserRoleByRoleFunction
UpdateUserRoleFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/user-role/userrole-update.updateeUserRole
Runtime: nodejs14.x
Events:
UpdateUserRoleAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /userrole/update
Method: post
#DependsOn: SaveUserRoleFunction
template_two.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f24xxxxd921e8e
SubnetIds:
- subnet-0381xxxd
- subnet-c4dxxxcb
- subnet-af5xxxc8
- subnet-748xxx28
- subnet-d139xxx9c
- subnet-e9e8xxx7
Resources:
GetAllPromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-getall.getAllPromotions
Runtime: nodejs14.x
Events:
GetAllPromotionsAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/getall
Method: get
SavePromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-save.savePromotions
Runtime: nodejs14.x
Events:
SavePromotionsAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/save
Method: post
UpdatePromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-update.updatePromotions
Runtime: nodejs14.x
Events:
UpdatePromotionsAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/update
Method: post
GetAllStaticInfoFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/static-info/staticinfo-getall.getAllStaticInfo
Runtime: nodejs14.x
Events:
GetAllStaticInfoAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /staticinfo/getall
Method: get
SaveStaticInfoFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/static-info/staticinfo-save.saveStaticInfo
Runtime: nodejs14.x
Events:
SaveStaticInfoAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /staticinfo/save
Method: post
UpdateStaticInfoFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/static-info/staticinfo-update.updateStaticInfo
Runtime: nodejs14.x
Events:
UpdateStaticInfoAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /staticinfo/update
Method: post
This worked, but I noticed that API Gateway assigned different URLs for each stack I create. In this example I have two stacks and API Gateway did create 2 URLs.
template.yaml URL - https://ez5khz***.execute-api.us-east-1.amazonaws.com/Prod/
template_user.yaml URL - https://7imy9b6***.execute-api.us-east-1.amazonaws.com/Prod/
. template_two.yaml URL - https://8awey9b6***.execute-api.us-east-1.amazonaws.com/Prod/
I want the URL that was made with template.yaml to be applied to all lambda functions, regardless of which nested stack it is in. I also have a plan to later assign a domain into this.
How I can get this to work under a one URL?
---------------UPDATE-------------------
Following the advices provided by LRutten, i updated my code as below.
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2xxxd921e8e
SubnetIds:
- subnet-03xxxb2d
- subnet-c4dxxxcb
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: prod
GetAllAccountingTypesFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-getall.getallaccountingtypes
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /accountingtypes/getall
Method: get
RestApiId:
Ref: ApiGatewayApi
GetAccountingTypeByIDFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-byid.getbyid
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /accountingtypes/getbyid
Method: get
RestApiId:
Ref: ApiGatewayApi
NestedStackTwo:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: nestedstack.yaml
LambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:DescribeNetworkInterfaces
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
- ec2:DescribeInstances
- ec2:AttachNetworkInterface
Resource: '*'
Outputs:
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for functions"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
netedstack.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2459dcd921e8e
SubnetIds:
- subnet-03xxxx2d
- subnet-c4dxxxxcb
Parameters:
ApiId: ApiGatewayApi
Resources:
GetAllPromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-getall.getAllPromotions
Runtime: nodejs14.x
Events:
GetAllPromotionsAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/getall
Method: get
RestApiId:
Ref: !Ref ApiId
SavePromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-save.savePromotions
Runtime: nodejs14.x
Events:
SavePromotionsAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/save
Method: post
RestApiId:
Ref: !Ref ApiId
UpdatePromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-update.updatePromotions
Runtime: nodejs14.x
Events:
UpdatePromotionsAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/update
Method: post
RestApiId:
Ref: !Ref ApiId
GetAllStaticInfoFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/static-info/staticinfo-getall.getAllStaticInfo
Runtime: nodejs14.x
Events:
GetAllStaticInfoAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /staticinfo/getall
Method: get
RestApiId:
Ref: !Ref ApiId
SaveStaticInfoFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/static-info/staticinfo-save.saveStaticInfo
Runtime: nodejs14.x
Events:
SaveStaticInfoAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /staticinfo/save
Method: post
RestApiId:
Ref: !Ref ApiId
UpdateStaticInfoFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/static-info/staticinfo-update.updateStaticInfo
Runtime: nodejs14.x
Events:
UpdateStaticInfoAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /staticinfo/update
Method: post
RestApiId:
Ref: !Ref ApiId
However, I can't build this project with sam build. I get the following error.
InvalidSamDocumentException(
samcli.commands.validate.lib.exceptions.InvalidSamDocumentException: [InvalidResourceException('GetAllPromotionsFunction', 'Event with id [GetAllPromotionsAPIEvent] is invalid. Api Event must reference an Api in the same template.')
Above error is generated for all the functions in the nested stack. How can I fix this?
I think Marcin is right in the sense that in your top-level stack you can define your own AWS::Serverless::Api resource. Its a bit more effort than letting SAM do everything for you but it gives you the flexibility you want.
You can pass on the Api ID to other nested stacks using a simple !Ref.
For this to work, in the nested stack you need an ApiId parameter, which you then use in all of your defined lambdas:
Parameters:
ApiId: ....
.....
Resources:
.....
Events:
UpdatePromotionsAPIEvent:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/update
Method: post
RestApiId: !Ref ApiId
I haven't tried this myself, but I think it should work?
I'm trying to invoke the lambda ReplySms through the Api Gateway Trigger
This is my template.yaml:
Resources:
SmsRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${Environment}-${Application}-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
- apigateway.amazonaws.com
Effect: Allow
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/SecretsManagerReadWrite
SmsApi:
Type: AWS::Serverless::Api
Tags:
username: !Ref UserName
Application: !Ref Application
Properties:
Name: !Sub ${Environment}-sms-service
StageName: !Ref Environment
MethodSettings:
- LoggingLevel: INFO
DataTraceEnabled: false
ResourcePath: "/*"
HttpMethod: "*"
ReplySms:
Type: AWS::Serverless::Function
Properties:
ReservedConcurrentExecutions: 100
FunctionName: !Sub ${Environment}-${Application}-reply-sms
CodeUri: target
Handler: replySms.handler
Runtime: nodejs12.x
MemorySize: 128
Timeout: 30
Role: !GetAtt SmsRole.Arn
ReplySmsResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref SmsApi
ParentId: !GetAtt SmsApi.RootResourceId
PathPart: replysms
EmptyModel:
Type: AWS::ApiGateway::Model
Properties:
RestApiId: !Ref SmsApi
ContentType: application/xml
Description: Empty schema to map lambda response
Name: EmptyModel
Schema: {}
ReplyMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: POST
Integration:
Type: AWS
Credentials: !GetAtt SmsRole.Arn
IntegrationHttpMethod: POST
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ReplySms.Arn}/invocations'
PassthroughBehavior: WHEN_NO_TEMPLATES
RequestTemplates:
application/x-www-form-urlencoded: |
#set($httpPost = $input.path('$').split("&"))
{
#foreach( $kvPair in $httpPost )
#set($kvTokenised = $kvPair.split("="))
#if( $kvTokenised.size() > 1 )
"$kvTokenised[0]" : "$kvTokenised[1]"#if( $foreach.hasNext ),#end
#else
"$kvTokenised[0]" : ""#if( $foreach.hasNext ),#end
#end
#end
}
IntegrationResponses:
- StatusCode: 200
ResponseTemplates: {"application/xml": "$input.path('$')"}
MethodResponses:
- StatusCode: 200
ResponseModels:
application/xml: !Ref EmptyModel
ResourceId: !Ref ReplySmsResource
RestApiId: !Ref SmsApi
InvokeReplySmsLambda:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt ReplySms.Arn
Principal: apigateway.amazonaws.com
SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SmsApi}/*/POST/replysms"
# SmsApiDeployment:
# Type: "AWS::ApiGateway::Deployment"
# DependsOn:
# - ReplyMethod
# Properties:
# RestApiId: !Ref SmsApi
# StageName: !Ref Environment
Outputs:
ApiResourceUrl:
Value: !Sub https://${SmsApi}.execute-api.${AWS::Region}.amazonaws.com/${Environment}/
I've been on this since 3 days and still cannot figure out what's wrong. From the other answers I figured out I need to add a Permission resource so I added InvokeReplySmsLambda which should have fixed the error.
But still getting Execution failed due to configuration error: Invalid permissions on Lambda function
(66c44450-af76-4c93-accd-xxxxxxxxxxxx) Extended Request Id: RKHI5FEMIAMFc-w=
(66c44450-af76-4c93-accd-b659d3c8f2ee) Verifying Usage Plan for request: 66c44450-af76-4c93-accd-b659d3c8f2ee. API Key: API Stage: dhrcl2tzqa/sandbox
(66c44450-af76-4c93-accd-b659d3c8f2ee) API Key authorized because method 'POST /replysms' does not require API Key. Request will not contribute to throttle or quota limits
(66c44450-af76-4c93-accd-b659d3c8f2ee) Usage Plan check succeeded for API Key and API Stage dhrcl2tzqa/sandbox
(66c44450-af76-4c93-accd-b659d3c8f2ee) Starting execution for request: 66c44450-af76-4c93-accd-b659d3c8f2ee
(66c44450-af76-4c93-accd-b659d3c8f2ee) HTTP Method: POST, Resource Path: /replysms
(66c44450-af76-4c93-accd-b659d3c8f2ee) Execution failed due to configuration error: Invalid permissions on Lambda function
(66c44450-af76-4c93-accd-b659d3c8f2ee) Method completed with status: 500
Any help would be appreciated.
First,
Remove your InvokeReplySmsLambda AWS::Lambda::Permission resource. You won't need it as SAM CLI will create a policy that can invoke your Lambda implicitly (docs reference).
Should you need the Arn of the implicitly created role it is always: FunctionNameRole.Arn (with usage like !GetAtt ReplySmsRole.Arn in yaml). You can confirm this value in one of the resources tabs of the stack details (cloudformation) or Roles section (IAM) of the aws console.
Second,
Edit your Lambda function to
remove the Role property
Include a Policies property with the the extra policies you want (SecretsManagerReadWrite) .
ReplySms:
Type: AWS::Serverless::Function
Properties:
ReservedConcurrentExecutions: 100
FunctionName: !Sub ${Environment}-${Application}-reply-sms
CodeUri: target
Handler: replySms.handler
Runtime: nodejs12.x
MemorySize: 128
Timeout: 30
Policies:
- SecretsManagerReadWrite
Notes :
I'll also mention you could use the Events (EventSource)'s property of API type and merge away the AWS::ApiGateway::Method resource. An example can be found here :
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-resource-function--examples
hths!
I've got an app deployed to Lambda and I'm using API Gateway to forward HTTP requests over to the app.
My problem is that it looks like API Gateway isn't forwarding requests that aren't to the base URL of the app.
In other words, the code inside my Lambda handler gets executed when there's an HTTP request to https://blabblahblah.execute-api.us-west-2.amazonaws.com/Prod/. However, an HTTP request to https://blabblahblah.execute-api.us-west-2.amazonaws.com/Prod/pong throws a 500 and no code gets executed. I've got some logging statements inside my handler and they don't log anything for non-base-URL requests.
I've narrowed the problem down to a permissions issue.
I have 2 sets of permission that aren't working well together.
I need to allow the API Gateway to invoke my lambda function
The lambda function needs to be able to call itself.
I thought I had both these permissions working correctly but any HTTP requests that aren't aimed at the base URL throw a 500 in the API Gateway (i.e. I see no Cloudwatch log entries for the request but the response is 500).
I think that means that there must be some error in my SAM template.
Resources:
IAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: ['sts:AssumeRole']
Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Version: 2012-10-17
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: lambda.handler
Role: !GetAtt IAMRole.Arn
Runtime: ruby2.5
CodeUri: "./src/"
MemorySize: 512
Timeout: 30
Events:
MyAppApi:
Type: Api
Properties:
Path: /
Method: ANY
RestApiId: !Ref MyAppAPI
MyAppAPI:
Type: AWS::Serverless::Api
Properties:
Name: MyAppAPI
StageName: Prod
DefinitionBody:
swagger: '2.0'
basePath: '/'
info:
title: !Ref AWS::StackName
paths:
/{proxy+}:
x-amazon-apigateway-any-method:
responses: {}
x-amazon-apigateway-integration:
uri:
!Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations'
passthroughBehavior: "when_no_match"
httpMethod: POST
type: "aws_proxy"
/:
post:
responses: {}
x-amazon-apigateway-integration:
uri:
!Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations'
passthroughBehavior: "when_no_match"
httpMethod: POST
type: "aws_proxy"
ConfigLambdaPermission:
Type: "AWS::Lambda::Permission"
DependsOn:
- MyFunction
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref MyFunction
Principal: apigateway.amazonaws.com
ConfigLambdaPermission:
Type: "AWS::Lambda::Permission"
DependsOn:
- MyFunction
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref MyFunction
Principal: !GetAtt IAMRole.Arn
Outputs:
MyFunction:
Description: Lambda Function for interacting with Slack
Value:
Fn::GetAtt:
- MyFunction
- Arn
MyAppAppUrl:
Description: App endpoint URL
Value: !Sub "https://${MyAppAPI}.execute-api.${AWS::Region}.amazonaws.com/"
Any idea how I can get things working right?
Yes, you need to add the other resource as well as a event trigger. And you lambda permissions have no use in the above template. Here's how it worked for me.
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Resources:
IAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: ['sts:AssumeRole']
Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Version: 2012-10-17
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: roleTest.roleTest
Role: !GetAtt IAMRole.Arn
Runtime: nodejs8.10
CodeUri: s3://apicfn/roleTest.zip
MemorySize: 512
Timeout: 30
Events:
MyAppApi1:
Type: Api
Properties:
Path: /
Method: ANY
MyAppApi2:
Type: Api
Properties:
Path: /{proxy+}
Method: ANY
Outputs:
MyFunction:
Description: Lambda Function for interacting with Slack
Value:
Fn::GetAtt:
- MyFunction
- Arn
PS: do not even need the Serverless::Api section for this template.
I'm totally lost on this circular dependency issue with Cloudformation. I wrote this template, and it works great with run from the CLI, but when I try to launch it from the browser as a Stack, I get this circular dependency issue.
Can someone tell me where the dependency is coming from ?
This is the Error I get
Circular dependency between resources: [VehiclesLambda, HelloAPI, AuthorizerFuncPerm]
Here is my template
AWSTemplateFormatVersion: '2010-09-09'
Description: Yes you can use SAM to create an Authorizer
Parameters:
Environment:
Type: String
Default: dev
Outputs:
ExampleAPIUrl:
Value: !Sub "https://${HelloAPI}.execute-api.${AWS::Region}.amazonaws.com/${Environment}/"
Resources:
HelloAPI:
Type: AWS::Serverless::Api
Properties:
StageName: !Sub ${Environment}
DefinitionBody:
swagger: 2.0
info:
title:
Ref: AWS::StackName
securityDefinitions:
test-authorizer:
type: apiKey
name: Authorization
in: header
x-amazon-apigateway-authtype: custom
x-amazon-apigateway-authorizer:
type: token
authorizerUri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthorizerFunc.Arn}/invocations
authorizerResultTtlInSeconds: 5
paths:
/vehicles:
get:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
!Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${VehiclesLambda.Arn}/invocations
responses: {}
security:
- test-authorizer: []
VehiclesLambda:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs4.3
CodeUri: 's3://companyrentalaws/vehicles.zip'
MemorySize: 128
Timeout: 30
Policies:
- AWSLambdaBasicExecutionRole
Events:
MyEndpoint:
Type: Api
Properties:
Path: /vehicles
Method: GET
RestApiId:
Ref: HelloAPI
AuthorizerFunc:
Type: AWS::Serverless::Function
Properties:
Handler: authorizer.authorizer
Runtime: nodejs4.3
CodeUri: 's3://companyrentalaws/authorizer.zip'
AuthorizerFuncPerm:
Type: AWS::Lambda::Permission
DependsOn:
- HelloAPI
- AuthorizerFunc
Properties:
Action: lambda:InvokeFunction
FunctionName:
Ref: AuthorizerFunc
Principal: apigateway.amazonaws.com
Sorry for posting so much code, but didn't want to leave anything out.
VehiclesLambda has a property RestApiId which refs HelloAPI.
RestApiId:
Ref: HelloAPI
HelloAPI Fn:GetAttr's VehiclesLambda's Arn
!Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${VehiclesLambda.Arn}/invocations
There is your circular dependency.