# Scheduling Tasks with CloudWatch and .NET Lambda

A common use case when working with AWS Lambda and .NET is running code on a schedule, similar to a cron job. AWS makes this easy with **Amazon CloudWatch Events** (now part of **Amazon EventBridge**), allowing you to **repeatedly trigger Lambda functions**.

In this post, we’ll walk through how to schedule a .NET Lambda function using CloudWatch and how to structure your code for maintainability.

---

## Prerequisites

Before you begin, make sure you have the following:

* An **AWS Account** with permission to create Lambda functions and CloudWatch rules
    
* The **.NET SDK** is installed (preferably .NET 6 or later)
    
* The **AWS CLI** is installed and configured (`aws configure`)
    
* **Amazon.Lambda.Tools** installed via the .NET CLI:
    
    ```bash
    dotnet tool install -g Amazon.Lambda.Tools
    ```
    
* Basic familiarity with AWS Lambda and the .NET CLI
    

---

## Step 1: Create the .NET Lambda Function

You can use the AWS-provided templates with the `Amazon.Lambda.Templates` package.

```bash
dotnet new lambda.EmptyFunction --name ScheduledTaskLambda
cd ScheduledTaskLambda
```

Edit the `Function.cs` file:

```csharp
public class Function
{
    public async Task FunctionHandler(ILambdaContext context)
    {
        context.Logger.LogLine("Scheduled task triggered at: " + DateTime.UtcNow);
        
        // Your logic here
        await DoScheduledWork();
    }

    private Task DoScheduledWork()
    {
        // Simulate a task like cleanup, email reminder, or sync
        Console.WriteLine("Running scheduled task...");
        return Task.CompletedTask;
    }
}
```

---

## Step 2: Deploy the Lambda Function

Deploy the Lambda:

```csharp
dotnet lambda deploy-function ScheduledTaskLambda
```

You’ll be prompted for AWS credentials and region during the deployment.

---

## Step 3: Schedule with CloudWatch Event Rule

You can use the AWS Console or the AWS CLI:

```bash
aws events put-rule \
  --schedule-expression "rate(5 minutes)" \
  --name MyScheduledLambdaRule
```

Add the Lambda target:

```bash
aws events put-targets \
  --rule MyScheduledLambdaRule \
  --targets "Id"="1","Arn"="arn:aws:lambda:<region>:<account-id>:function:ScheduledTaskLambda"
```

Grant CloudWatch permission to invoke the Lambda:

```bash
aws lambda add-permission \
  --function-name ScheduledTaskLambda \
  --statement-id MyScheduledEventPermission \
  --action 'lambda:InvokeFunction' \
  --principal events.amazonaws.com \
  --source-arn arn:aws:events:<region>:<account-id>:rule/MyScheduledLambdaRule
```

## Using Cron Expressions

Instead of `rate()`You can use cron expressions:

```bash
--schedule-expression "cron(0 12 * * ? *)"
```

This triggers at 12:00 PM UTC every day. AWS cron format:

```bash
cron(Minutes Hours Day-of-month Month Day-of-week Year)
```

## Real-World Example: Sending a Daily Email Report

Let’s say your system collects usage metrics or user activity throughout the day. Every morning at 8 AM UTC, you want to email a summary report to your team. You’ll:

* Query a database or analytics source
    
* Generate a report, either plain text or HTML
    
* Send the report using Amazon SES or another email provider
    

This is a great use case for a scheduled Lambda function.

### Example Code

```csharp
public class Function
{
    public async Task FunctionHandler(ILambdaContext context)
    {
        var report = await GenerateReport();
        await SendEmail(report);

        context.Logger.LogLine("Daily report sent at: " + DateTime.UtcNow);
    }

    private Task<string> GenerateReport()
    {
        // Query a DB or metrics API. Simulated output:
        return Task.FromResult("User signups: 42\nErrors: 3\nSales: $1280");
    }

    private Task SendEmail(string report)
    {
        // Integrate with Amazon SES, SendGrid, or another provider
        Console.WriteLine("Sending email with report:\n" + report);
        return Task.CompletedTask;
    }
}
```

This Lambda can be scheduled using the following cron expression:

```csharp
bashCopy code--schedule-expression "cron(0 8 * * ? *)"
```

This means 8:00 AM UTC every day.

## Logging and Monitoring

* View logs in **CloudWatch Logs**
    
* Add custom logging using `context.Logger.LogLine(...)`
    
* Use structured logging libraries like [Serilog](https://serilog.net/) for better insights
    

## Summary

With just a few commands and a bit of .NET code, you can schedule tasks using CloudWatch Events and AWS Lambda. This approach is scalable, cost-effective, and fully serverless.

### Benefits Recap:

* No server maintenance
    
* Pay only for executions
    
* Integrated with the AWS ecosystem
    
* Ideal for recurring jobs like cleanup, reporting, data sync, and reminders
    

---

## References

* [AWS Lambda Developer Guide (.NET)](https://docs.aws.amazon.com/lambda/latest/dg/csharp-handler.html)
    
* [Schedule expressions for rules - EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html)
    
* [Amazon.Lambda.Tools GitHub](https://github.com/aws/aws-extensions-for-dotnet-cli)
    
* [AWS Schedule Expressions](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduler-expressions.html)
