AWS CloudFormation template with Kinesis Event Consumer - amazon-web-services

I am trying to create a Lambda which is invoked when there are records in a Kinesis Stream. For this, in the template.yaml for the lambda, I have added a Kinesis Consumer in the following way -
EventStreamConsumer:
Type: AWS::Kinesis::StreamConsumer
Properties:
StreamARN: !Sub arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/${EventsKinesisStream}
ConsumerName: !Ref KinesisConsumerName
EventSourceMapping:
Type: 'AWS::Lambda::EventSourceMapping'
Properties:
BatchSize: 100
MaximumBatchingWindowInSeconds: 15
Enabled: true
EventSourceArn: !Ref EventStreamConsumer
FunctionName: !GetAtt Function.Arn
StartingPosition: LATEST
When I deploy this template using the SAM CLI, I see errors saying -
Unsupported MaximumBatchingWindowInSecond parameter for given event source mapping type. (Service: AWSLambda; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: xxxxxxxxxx)
Observe the Error message for the parameter name.
Can someone explain why this is occurring and how this can be mitigated?

Batch window, error handling, and concurrency settings are not available for HTTP/2 stream consumers.
To understand completely you can refer the link below.
Using AWS Lambda with Amazon Kinesis
What you are trying to do will be supported with HTTP/1 not with HTTP/2.

Related

how to provide multiple SQS queue name in AWS Lambda trigger cloud formation template

I want to trigger two different SQS queue from my lambda, in my cloud formation template I gave like this - but my stack is not getting created. I'm getting below error message:
Events:
SQSEvent:
Type: SQS
Properties:
Queues:
- !Sub arn:aws:sqs:${AWS::Region}:${AccountId}:${QueueName}
- !Sub arn:aws:sqs:${AWS::Region}:${AccountId}:${DLQQueueName}
BatchSize: 1
Enabled: true
Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document.
Number of errors found: 1. Resource with id [MyLambda] is invalid. Event with id [SQSEvent] is invalid. No Queue (for SQS) or Stream (for Kinesis, DynamoDB or MSK) or Broker (for Amazon MQ) provided.04/27/22 06:09:18 - UPDATE_ROLLBACK_IN_PROGRESS - AWS::CloudFormation::Stack) -
Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document.
Number of errors found: 1. Resource with id [MyLambda] is invalid. Event with id [SQSEvent] is invalid. No Queue (for SQS) or Stream (for Kinesis, DynamoDB or MSK) or Broker (for Amazon MQ) provided.
Can someone please help me to resolve this issue. Appreciated your help!
Thanks!
You will want to use Queues (plural):
Events:
SQSEvent:
Type: SQS
Properties:
Queues:
- !Sub arn:aws:sqs:${AWS::Region}:${AccountId}:${QueueName}
- !Sub arn:aws:sqs:${AWS::Region}:${AccountId}:${DLQQueueName}
BatchSize: 1
Enabled: true
You could check your serverless setup against these templates
https://carova.io/snippets/serverless-aws-create-sqs-queue-template
This one shows the whole setup with your SQS Queue being subscribed to and SNS topic and then triggering the AWS Lambda Function.
https://carova.io/snippets/serverless-aws-sqs-queue-subscribed-to-sns-topic
You can write your template as given below -
Events:
SQSEvent1:
Type: SQS
Properties:
Queue: !Sub arn:aws:sqs:${AWS::Region}:${AccountId}:${QueueName}
BatchSize: 1
Enabled: true
SQSEvent2:
Type: SQS
Properties:
Queue: !Sub arn:aws:sqs:${AWS::Region}:${AccountId}:${DLQQueueName}
BatchSize: 1
Enabled: true

CloudFormation template for lambda-based service, S3Key does not exist

I am attempting to create a CloudFormation template for an AWS lambda service and I'm running into a "chicken or the egg" scenario between the s3 bucket holding my lambda code, and the lambda function calling said bucket.
The intent is for our lambda code to be built to a jar, which will be hosted in an S3 Bucket, and our lambda function will reference that bucket. However when I run the template (using the CLI aws cloudformation create-stack --template-body "file://template.yaml"), I run into the following error creating the lambda function:
CREATE_FAILED Error occurred while GetObject. S3 Error Code: NoSuchKey. S3 Error Message: The specified key does not exist. (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: ...; Proxy: null)
I believe this is happening because cloudformation is building both the bucket and lambda in the same transaction, and I can't stop it in the middle to push content into the brand new bucket.
I can't be the only one that has this problem, so I'm wondering if there's a common practice for tackling it? I'd like to keep all my configuration in a single template file if possible, but the only solutions I'm coming up with would require splitting the stack creation into multiple steps. (e.g. build the bucket first, deploy my code to it, then create the rest of the stack.) Is there a better way to do this?
template.yaml (the relevant bits)
...
myS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "${AWS::StackName}"
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
AccessControl: Private
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
VersioningConfiguration:
Status: Enabled
myLambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub "${AWS::StackName}-dec"
Handler: "lambda.Handler"
Role: !GetAtt myLambdaExecutionRole.Arn
Code:
S3Bucket: !Ref myS3Bucket
S3Key: "emy-lambda-fn.jar"
Runtime: "java8"
Timeout: 90
MemorySize: 384
Environment:
Variables:
stackName: !Sub "${AWS::StackName}"
...
I'm coming up with would require splitting the stack creation into multiple steps. [...] Is there a better way to do this?
Splitting template into two is the most logical and easiest way of doing what you are trying to do.
There are some alternatives that would allow you to keep everything in one template, but they are more difficult to implement, manage and simply use. One alternative would be to develop a custom resources. The resource would be in the form of a lambda function that would get invoked after the bucket creation. The lambda would wait and check for existence of your emy-lambda-fn.jar in the bucket, and when the key is uploaded (within 15 min max), the function returns, and your stack creation continues. This means that your myLambdaFunction would be creating only after the custom resource returns, ensuring that emy-lambda-fn.jar exists.

AWS::Serverless::Function lambda version for Lambda#Edge event handler

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.

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

How To Rollback AWS CodeStar Lambda Functions Deployed Via CloudFormation?

I'm creating a Nodejs microservice for AWS Lambda. I scaffolded by project using AWS Codestar, and that set me up with a CI/CD pipeline that automatically deploys the lambda function. Nice.
The issue is that every time it deploys the lambda function it must delete and recreate the function, thus deleting any versions or aliases I made.
This means I really can't roll back to other releases. I basically have use git to actually revert the project, push to git, wait for the super-slow AWS Code Pipeline to flow through successfully, and then have it remake the function. To me that sounds like a pretty bad DR strategy, and I would think the right way to rollback should be simple and fast.
Unfortunately, it looks like the CloudFormation section of AWS doesn't offer any help here. When you drill into your stack on the first CloudFormation page it only shows you information about the latest formation that occurred. Dear engineers of AWS CloudFormation: if there was a page for each stack that showed a history of CloudFormation for this stack and an option to rollback to it, that would be really awesome. For now, though, there's not. There's just information about the latest formation that's been clouded. One initially promising option was "Rollback Triggers", but this is actually just something totally different that lets you send a SNS notification if your build doesn't pass.
When I try to change the CodePipeline stage for deploy from CREATE_CHANGE_SET to CREATE_UPDATE I then get this error when it tries to execute:
Action execution failed UpdateStack cannot be used with templates
containing Transforms. (Service: AmazonCloudFormation; Status Code:
400; Error Code: ValidationError; Request ID:
bea5f687-470b-11e8-a616-c791ebf3e8e1)
My template.yml looks like this by the way:
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::CodeStar
Parameters:
ProjectId:
Type: String
Description: AWS CodeStar projectID used to associate new resources to team members
Resources:
HelloWorld:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs8.10
Environment:
Variables:
NODE_ENV: staging
Role:
Fn::ImportValue:
!Join ['-', [!Ref 'ProjectId', !Ref 'AWS::Region', 'LambdaTrustRole']]
Events:
GetEvent:
Type: Api
Properties:
Path: /
Method: get
PostEvent:
Type: Api
Properties:
Path: /
Method: post
The only options in the CodePipeline "Deploy" action are these:
It would be really great if someone could help me to see how in AWS you can make Lambda functions with CodePipeline in a way that they are easy and fast to rollback. Thanks!