AWS::Serverless::Function lambda version for Lambda#Edge event handler - amazon-web-services

I am trying to use the AWS SAM framework to create a lambda to be used as a CloudFront event handler. It seems like the AWS::Serverless::Function doesn't support the Version attribute. The error I am seeing:
com.amazonaws.services.cloudfront.model.InvalidLambdaFunctionAssociationException: The function ARN must reference a specific function version. (The ARN must end with the version number.)
I found this answer that led me to try it. The relevant parts of my CloudFormation YAML file:
Resources:
CloudFrontFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: cloudfront-handler/hello_world/
Handler: app.lambda_handler
Runtime: python3.7
Outputs:
CloudFrontFunctionArn:
Description: CloudFront Function ARN with Version
Value: !Join [':', [!GetAtt CloudFrontFunction.Arn, !GetAtt CloudFrontFunction.Version]]
When I sam deploy I get the following error.
Waiting for changeset to be created..
Error: Failed to create changeset for the stack: my-sam-app, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Template error: resource CloudFrontFunction does not support attribute type Version in Fn::GetAtt
The properties available on AWS::Lambda::Function are documented here and it lists Version as one of the properties. So it seems AWS::Serverless::Function doesn't support getting the version. How can I get around this so I can deploy a CloudFront event handler implemented using the AWS SAM framework?
UPDATE
As per #mokugo-devops (thanks!), the fix for this was to add AutoPublishAlias: live like this:
Resources:
CloudFrontFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: cloudfront-handler/hello_world/
Handler: app.lambda_handler
Runtime: python3.7
AutoPublishAlias: live
Outputs:
CloudFrontFunctionVersion:
Description: CloudFront Function ARN with Version
Value: !Ref CloudFrontFunction.Version

By default the function will not automatically have a Version deployed. Instead you will need to specify the AutoPublishAlias attribute.
More information available here.
By doing this you will be unable to retrieve the version.
Instead you will need to create a resource of AWS::Lambda::Version and pass in the Arn from the CloudFrontFunction resource. Then you can get the Lambda version arn from this new resource and pass that to your CloudFrontFunctionArn output.

Related

aws sam build failing: property SnapStart not defined for resource of type AWS::Serverless::Function

AWS sam build failing after adding SnapStart property in function yaml file.
[InvalidResourceException('MyFunSnapstart', 'property SnapStart not defined for resource of type AWS::Serverless::Function'), InvalidResourceException('MyFunLamdaFunSnapstart', 'property SnapStart not defined for resource of type AWS::Serverless::Function')] ('MyFunSnapstart', 'property SnapStart not defined for resource of type AWS::Serverless::Function') ('MyFunSnapstart', 'property SnapStart not defined for resource of type AWS::Serverless::Function')
template.yaml file code:
MyFunSnapstart:
Type: AWS::Serverless::Function
Properties:
CodeUri: my-lamda-fun
Handler: com.poc.lambda.handler.MyLambda::handleRequest
Role: !GetAtt LambdaExecutionRole.Arn
SnapStart:
ApplyOn: PublishedVersions
Events:
MyEvent:
Type: Api
Properties:
Path: /api/snapstart/hello
RestApiId: !Ref MyRestApi
Method: GET
My sam cli version is : SAM CLI, version 1.65.0
SAM CLI actually released version 1.66 around an hour ago with support for this new property: https://github.com/aws/aws-sam-cli/releases/tag/v1.66.0 (and PyPI), so if you update now it should work correctly.

How do you get the API endpoint's URL when it's created within the Events property of Cloudformation's Lambda definition

I'm creating a Lambda function via CloudFormation (AWS' SAM: Serverless Application Model) and have defined an API endpoint via the Lambda-function's Events property.
...
MyFunction:
Type: AWS::Serverless::Function
Properties:
Description: Do amazing things
CodeUri: my_function/
Events:
Trigger:
Type: Api
Properties:
Path: /p1/{v1}
Method: post
Handler: app.run
...
I'd now like to use the URL of the endpoint that's been created in another part of the CloudFormation YAML file. I've tried to use the SAM documentation for Lambda but the only return values have to do with the Function's ARN and resource name.
Specifically, thought I think unrelated to the exact question, I want to use the API endpoint as a subscription for an SNS Topic.
¿How can I get the URL of the API Endpoint?
you can directly reference the RestApi resource like this.
Resources:
apiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Name: !Sub ${AWS::StackName}-my-api
Description: my-api-edge
Outputs:
apiGatewayInvokeURL:
Value: !Sub "https://${apiGateway}.execute-api.${AWS::Region}.amazonaws.com/${apiGatewayStageName}"
lambdaArn:
Value: !GetAtt "lambdaFunction.Arn"
I think I found the answer across a couple of places.
This Stack Overflow post shows that there is an implicit reference created that you can use as follows
!Ref ServerlessRestApi
This was supported in practice, by a SAM Respository App
And then I re-read, more closely, the SAM API documentation which shows the RestApiId Property. It says
...Typically, this is set to reference an AWS::Serverless::Api resource defined in this template. If not defined, a default AWS::Serverless::Api resource is created..."
So it looks like you can reference it as !Ref ServerlessRestApi without any modification to the YAML in the original question, or you could add the following Property, RestApiId: MyAPI, and reference it as !Ref MyAPI.
However, to get the actual URL, it looks like you have to use a Fn::Sub to glue together a couple of parts. Pahud Hsieh does it in his SAM Repository app above
Outputs:
APIUrlPrefix:
Value:
Fn::Sub:
- https://${ServerlessRestApi}.execute-api.${Region}.amazonaws.com/Prod/incomingwebhooks/
- Region:
Ref: AWS::Region
ServerlessRestApi:
Ref: ServerlessRestApi
...

AWS SAM Function AutoPublishAlias "Invalid function version"

I am using AWS SAM to deploy a Lambda function. I'am using the AutoPublishAlias property to automatically publish a new version when I deploy the function but I'm getting the following error: Invalid function version 9. Function version 9 is already included in routing configuration. (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: 56b59a6b-6c57-434e-a505-ce7aa27c99b6). Every time I delete and create the stack the function gets created successfully, but when I try to update the stack I get the error. I'm also wondering why is the version number not starting from 1 after deleting the Lambda?
The Lambda definition:
ApiLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub '${TagApplication}-${TagEnvironment}-api-lambda'
CodeUri: ../build
Handler: lambda.handler
MemorySize: 256
Role: !GetAtt LambdaExecutionRole.Arn
Runtime: nodejs10.x
Timeout: 30
AutoPublishAlias: 'live'
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: '1'
Screenshot of AWS Lambda console Alias menu:
Looks like you need to configure the DeploymentPreference property as well - see this link - https://github.com/awslabs/serverless-application-model/issues/1296 and https://github.com/jcts3/sam-pc-experiment/blob/master/template.yaml#L22

Lambda Resource in CloudFormation Template Reports CodeUri as Invalid

Given the following CloudFormation template snippet:
AWSTemplateFormatVersion: 2010-09-09
Resources:
PrototypeCreateOrderFDM4:
Type: "AWS::Lambda::Function"
Properties:
CodeUri: "../Lambda/"
Handler: "PrototypeCreateOrder.handler"
Timeout: 15
Runtime: "nodejs10.x"
Role: arn:aws:iam::123456789012:role/deezNutz-Role-1ABC8DDEFGHI
I'm getting a warning saying that the CodeURI isn't a valid property:
I have lots of other Lambda's structure like this. I've never gotten this before. What am I missing?
You're using the AWS::Lambda::Function resource, which doesn't have a CodeUri property.
You're probably thinking of the AWS::Serverless::Function from SAM, which supports a CodeUri property.
However, with SAM, you can omit the CodeUri property if your Lambda code is local to your template (and if your handler is under Lambda/index.js, then you can just point the Handler: property to the path directly). Can't say for sure if this will work with AWS::Lambda::Function, but will definitely with SAM's AWS::Serverless::Function.

AWS SAM - Template does not have any APIs connected to Lambda functions

So I'm trying to convert an existing spring boot application to an AWS lambda and using SAM.
I'm trying to use aws-sam-cli to try my lambda locally, however with my SAM setup I am getting: Template does not have any APIs connected to Lambda functions
When I do: sam local start-api
My template.yml:
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: foo
Resources:
MailFunction:
Type: AWS::Serverless::Function
Properties:
Handler: bar.LambdaHandler::handleRequest
Runtime: java8
CodeUri: target/foo-bar-1.0.jar
Timeout: 300
MemorySize: 1024
Events:
Timer:
Type: Schedule
Properties:
Schedule: rate(1 day)
Any idea what I'm doing wrong? It looks correct as far as I can tell from https://blog.couchbase.com/aws-serverless-lambda-scheduled-events-tweets-couchbase/ + https://docs.aws.amazon.com/lambda/latest/dg/tutorial-scheduled-events-schedule-expressions.html
You didn't add any API Gateway event to your function. And start-api spawn a local API Gateway.
You need to add at least one Api event to your Events section.
Events:
[...]
Api:
Type: Api
Properties:
Path: /myresource
Method: get
If you just have a Schedule event, try to use generate-event to create such an event.
sam local generate-event schedule ...
and invoke function e.g. sam local invoke function-name -e event_file.json (see)
For Googlers:
Check whether you have an Event with Type: Api
ALSO check whether you have run sam build (very important)
Use the --debug flag so you will know what is going on
As of 2020/7/13, Type: HttpApi does not work with sam local start-api. See issue.
This error message also displays if you are trying to test a websocket API locally. Unfortunately, local testing of websockets is not currently supported - see https://github.com/awslabs/aws-sam-cli/issues/896.
I ran into this error too even when I did have an Api event defined in my SAM template. The problem was that I had a previous template in my .aws-sam/build/ directory which didn't have the Api event defined (from a previous run of sam build). Cleaning out the build directory fixed it.
I am getting this error, but I have function that is working with the HttpApi, it appears that current version of sam does not support HttpApi.
CLI Version
SAM CLI, version 0.52.0
Example Function
FeedsFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri:
Description: "Function that handles feeds"
Events:
Handler:
Type: HttpApi
Properties:
ApiId: !Ref FeedsApi
Path: /
Method: get
Handler: api
MemorySize: 1024
Runtime: go1.x
Timeout: 5
Tracing: Active
There is currently an open issue on GitHub for adding support: https://github.com/awslabs/aws-sam-cli/issues/1641
I got this error when I had a whitespace error in my AWS::Serverless::Function definition, specifically Environment needed to be a child of Properties but was on the same level. Correcting the whitespace made this error disappear. Nodejs 10.15.