I want to trigger my AWS lambda function on 15th of every month but my function is triggering after every 30 minutes. My function in Serverless.yml is
monthlyTbAlert:
warmup: true
handler: handlers/monthly-tbalert/index.monthlyTbAlert
timeout: 60
events:
- schedule: cron(0 0 10 15 1/1 ? *)
enabled: true
If you want to debug your cron expressions before deploying them, you can go to CloudWatch -> Rules and test them there. It's a very useful playground if you're unsure about what may be going on.
If we grab the expression provided in #Stargazer's answer (which, by the way, is very accurate) and paste it in CloudWatch Rules, we can see when the next triggers will happen:
By using yours, however, we can see no events are shown. If you say it is running every 30 minutes, then there potentially is a bug in CloudWatch rules that triggers invalid expressions every 30 minutes:
According to aws docs, the format is cron(Minutes Hours Day-of-month Month Day-of-week Year)
So you should use this:
0 - Minute 0 of the hours
10- Hours of the day. So, 10:00
15- 15th day of the month
* - Execute it every month
? - Regardless of the day of the week
*- Every year
So, your cron expression should be 0 10 15 * ? * To execute your cron every 15th day of the month at 10:00AM
Related
I want to run my AWS Lambda from 3PM EST to 4:05 PM EST in every 13 mins interval from Monday to Friday. I've used this expression as scheduled pattern Amazon EventBridge Rules in my trigger:
0/13 20 ? * MON-FRI *
Minutes Hours Day of Month Month Day of Week Year
It runs from 3pm to 4 PM in 13 mins interval and stops at 3:52 PM but I want to run one more time at 4:05 PM. How can I change the Hour pattern to achieve this?
I tried hour as 20-21 but this only takes a full hour not first 5 min after 4 pm. My expectation is to change the hour so it take 4:05 PM schedule as per 13 min interval time.
You can not do it in a single cron expression you need to use more than one cron expression to handle exception cases.
0/13 20 ? * MON-FRI * -> 2000, 2013, 2026, 2039, 2052
5 ? * MON-FRI *. -> 2105
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?
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.
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:
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);
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}`;
Create the schedule expression
const futureEvent = events.schedule.expression('cron(' + dateToCron(future) + ')');
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.
I have a Cloudwatch Alarm which receives data from a Canary. My canary attempts to visit a website, and if the website is up and responding, then the datapoint is 0, if the server returns some sort of error then the datapoint is 1. Pretty standard canary stuff I hope. This canary runs every 30 minutes.
My Cloudwatch alarm is configured as follows:
With the expected behaviour that if my canary cannot reach the website 3 times in a row, then the alarm should go off.
Unfortunately, this is not what's happening. My alarm was triggered with the following canary data:
Feb 8 # 7:51 PM (MST)
Feb 8 # 8:22 PM (MST)
Feb 8 # 9:52 PM (MST)
How is it possible that these three datapoints would trigger my alarm?
My actual email was received as follows:
You are receiving this email because your Amazon CloudWatch Alarm "...." in the US West (Oregon) region has entered the ALARM state, because "Threshold Crossed: 3 out of the last 3 datapoints [1.0 (09/02/21 04:23:00), 1.0 (09/02/21 02:53:00), 1.0 (09/02/21 02:23:00)] were greater than or equal to the threshold (1.0) (minimum 3 datapoints for OK -> ALARM transition)." at "Tuesday 09 February, 2021 04:53:30 UTC".
I am even more confused because the times on these datapoints do not align. If I convert these times to MST, we have:
Feb 8 # 7:23 PM
Feb 8 # 7:53 PM
Feb 8 # 9:23 PM
The time range on the reported datapoints is a two hour window, when I have clearly specified my evaluation period as 1.5 hours.
If I view the "metrics" chart in cloudwatch for my alarm it makes even less sense:
The points in this chart as shown as:
Feb 9 # 2:30 UTC
Feb 9 # 3:00 UTC
Feb 9 # 4:30 UTC
Which, again, appears to be a 2 hour evaluation period.
Help? I don't understand this.
How can I configure my alarm to fire if my canary cannot reach the website 3 times in a row (waiting 30 minutes in-between checks)?
I have two things to answer this:
Every time a canary runs 1 datapoint is sent to cloudwatch. So if within 30 mins you are checking for 3 failures for alarms to be triggered then your canary should run at a interval for 10 mins. So in 30 mins 3 data point and all 3 failed data points for alarm to be triggered.
For some reasons statistics was not working for me so I used count option. May be this might help.
My suggestion to run canary every 5 mins. So in 30 mins 6 data points and create alarm for if count=4.
The way i read your config, your alarm is expecting to find 3 data points within a 30 minute window - but your metric is only updated every 30 minutes so this condition will never be true.
You need to increase the period so there is 3 or more metrics available in order to trigger the alarm.
I want a to write an AWS cloudwatch event rule that fires at 1:00, 7:00, 13:00 and 19:00 hrs every day, this can be a cron or rate expression.
I also have a similar requirement for another event rule that fires every day at 2:00, 8:00, 14:00, 20:00 hrs
# will be writing the expressions in terraform scripts like this
resource "aws_cloudwatch_event_rule" "stop_instances" {
name = "StopInstance"
description = "Stop instances nightly"
schedule_expression = "cron(0 0 * * ? *)"
}
You could do this as either
cron(0 1,7,13,19 * * ? *) or cron(0 1/6 * * ? *)
The first option simply specifies the hours to run at, the second says to run every 6 hours with an offset of 1 hour.
For more information about cron expressions with CloudWatch events read the docs here
I have a use case where I need to run a function daily at 12:00:00 am. My Python code takes 3-4 seconds to initialize and 3 seconds to execute. It would still be fine if my function is triggered within 1 second after 12:00:00 am, but I can't do it with AWS Lambda triggered by AWS CloudWatch.
I have created a AWS Lambda function and it's being triggered every 11:59 pm using AWS CloudWatch Events because it does not provide second level precision. So, it's wasting computing time averaging between 15 - 45 seconds after initializing just to sleep until 12:00:00 am.
Although the price is still quite low, but I just felt annoyed that the majority (>75%) of the computing time taken is used to Sleep. Anyone else has a better idea?
Have you tried scheduling lambda execution using cron expression?
This expression 0 0 * * ? * would run your lambda every day at midnight GMT.
Adjust accordingly to your time zone.