Home > Software engineering >  Schedule AWS lambda in a interval with immediately trigger
Schedule AWS lambda in a interval with immediately trigger

Time:12-06

To run lambda in an interval, I could use EventBridge rule: https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html

For example, if I set the rule to 7 days, the lambda will execute at 7 days after the lambda is created.

What if I need to run this lambda immediately after its creation and also run this lambda in an interval?

How can I do this programmatically or in CDK?

CodePudding user response:

You can create a Cloudwatch Event Rule that occurs a single time using a very specific schedule expression thanks to the fact that Cloudwatch Events supports the Year for cron expressions. You would need to know, roughly, how long until deployment is complete. While this method wouldn't be instant it could be close enough to serve your purpose without complicated custom resources or post deployment triggering as long as a buffer of some minutes is okay.

For example in Typescript this might look like follows:

  1. Get the future date you'd like to target and add some minutes (10 in this case):
const date = new Date();
const minutesToAdd = 10;
const future = new Date(date.getTime()   minutesToAdd * 60000);
  1. Convert that future date to a cron expression for exactly the that single date then store the expression with the Day of Week set to ? for "no specific value" since we are setting the day of the month.
const minutes = future.getUTCMinutes();
const hours = future.getUTCHours();
const days = future.getUTCDay();
const months = future.getUTCMonth()   1;
const years = future.getUTCFullYear();

let futureCron = `${minutes} ${hours} ${days} ${months} ? ${years}`;
  1. Create the schedule expression
const futureEvent = events.schedule.expression('cron('   dateToCron(future)   ')');
  1. Use the expression to schedule an event rule
new events.Rule(this, 'immediateTrigger', {
  schedule: futureEvent
  targets: [new targets.LambdaFunction(someHandler)]
}

This would result in a scheduled event that occurs only at a single point in UTC time. For example if it was 2:55PM on Dec 5th 2021 when you deployed it would create an expression for 03:05 PM, on day 5 of the month, only in December, only in 2021

I had a need for this exact type of setup so I created a library for this purpose that simplifies the above process to generate schedule expressions for both one time OnDeploy or one time At a given future date. While anyone is free to use this you should understand why it works and if it's the right choice for your needs.

CodePudding user response:

Note: This solution only works for those who use AWS CodeBuild to deploy their Lambdas.

In this sample project (https://github.com/dashmug/us-covid-stats) I did a while back, I configured the Lambda to also have another trigger based on CodeBuild's "Build Succeeded" event.

In https://github.com/dashmug/us-covid-stats/blob/main/backend/serverless.yml#L71,

RefreshDataFromSources:
    handler: us_covid_stats/etl/handler.refresh_data_from_sources
    events:
      - schedule:
          enabled: false
          rate: rate(1 day)
      - cloudwatchEvent:
          enabled: false
          event:
            source:
              - aws.codebuild
            detail-type:
              - CodeBuild Build State Change
            detail:
              build-status:
                - SUCCEEDED
              project-name:
                - us-covid-stats-deployment-backend

you'll see that the Lambda is normally triggered once daily. But also on top of the daily schedule, it is triggered when the deployment succeeds.

  • Related