0
votes

I have a Lambda and an CloudWatch Rule that triggers the lambda. When I set these via the web console, I can see in the Lambda console that it's trigger is indeed the CloudWatch rule.

Now I want to set it from the AWS SAM YAML template, and the trigger is indeed being created as expected, but in the lambda web console it does not show the CloudWatch rule as a trigger.

Also, I need to set the lambda's VPC in the YAML, but there is no effect on the lambda.

I would appriciate if someone can have a look at the YAML and point me to the right directions:

Resources:

checkNoSessionLambda:
    Type: AWS::Serverless::Function
    Properties:
        Description: 'checkNoSessionLambda at every 1 minute'
        Handler: checkNoSessionLambda.handler
        Runtime: nodejs8.10
        Timeout: 60
        CodeUri: ./src
        Role: ***   
    VpcConfig:
        SecurityGroupIds:
            - "***"
        SubnetIds:
            - "***"
            - "***"
    Events:
        CheckNoSessionClouadwatchRule:
            Properties:
                    EventPattern: 
                        source: 
                            - "aws.events"
            Type: AWS::Events::Rule




CheckNoSessionClouadwatchRule:
    Type: AWS::Events::Rule
    Properties:
        Description: "Invoke checkNoSession lambda every 1 minute"
        ScheduleExpression: "rate(1 minute)"
        State: "ENABLED"
        Targets:                    
            -
                Arn: "***"
                Id: "checkNoSessionLambdaTargetId"

EDIT:

The Lambad is in a stack, so using simply the GetAtt isn't helping

2
I've done this recently. You shouldn't set the event on the function, just delete that whole Events section on the function. All you need are 3 resources: AWS::Serverless::Function, AWS::Events::Rule as you've done (use !GetAtt as per the answer below), and an AWS::Lambda::Permission to grant the rule access to invoke your function.404
@404 We don't need AWS::Events::Rule. Instead we can use Events in Serverless::Function resource. This would create an events rule when the template is deployed. Details: github.com/awslabs/serverless-application-model/blob/master/…krishna_mee2004

2 Answers

1
votes

You need to allow cloudwatch to invoke the lambda function, Check in the doc. Usual flow is

  • Lambda function
  • Event rule
  • Grant Lambda Invoke Permission to Event

Something like below is missing!

  Type: AWS::Lambda::Permission
  Properties: 
    FunctionName: 
      Ref: "checkNoSessionLambda"
    Action: "lambda:InvokeFunction"
    Principal: "events.amazonaws.com"
    SourceArn: 
      Fn::GetAtt: 
        - "CheckNoSessionClouadwatchRule"
        - "Arn"

1
votes

Are you hardcoding the ARN? This will not work since the resource (lambda function) you are intending to point to, doesn't yet exist, and will be created by the CFN template itself.

You have to use the intrinsic function Fn::GetAtt with the logical ID of the defined serverless function to get the ARN instead.

Targets:                    
        -
            Arn: !GetAtt checkNoSessionLambda.Arn
            Id: "checkNoSessionLambdaTargetId"