How to schedule EC2 instances easily (start/stop)
Tags: aws, ec2, lambda, python
Published: 2022-01-24 13:24:05

Everyone would like to schedule _EC2_ instances and save a couple of bucks. Today, I'm bringing you a small _Python_ that can help you. The steps are the following ones:

**Step 1.** Create a lambda function called: **ec2_scheduler**

**Step 2.** Copy and paste the following code:

```python
import boto3
import os
import json

region = os.environ['REGION']
ec2 = boto3.client('ec2', region_name=region)

instances = []

def lambda_handler(event, context):
    action = event['Action']
    response = ec2.describe_instances(Filters=[{'Name' : 'instance-state-name','Values' : [action]}, {'Name': 'tag-key', 'Values': ['auto-scheduled']}])
    reservations = response['Reservations']
    for reservation in reservations:
        for instance in reservation['Instances']:
            instanceId = instance['InstanceId']
            for tag in instance['Tags']:
                if tag['Key'] == 'auto-scheduled' and tag['Value'] == 'true':
                    instances.append(instanceId)

    if (action == 'stopped'):
        if (len(instances) > 0):
            ec2.start_instances(InstanceIds=instances)
    else
        if (len(instances) > 0):
            ec2.stop_instances(InstanceIds=instances)
```

**Step 3.** Set a tag to your EC2 instance called: **auto-scheduled** that has a value assigned as **true**.

**Step 4.** Add a new **Policy** in the configuration and permission section of your `Lambda` that contains:

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:Start*",
                "ec2:Stop*",
                "ec2:Describe*"
            ],
            "Resource": "*"
        }
    ]
}
```

**Step 5.** Schedule your `Lambda` as triggers with cron expressions like these ones:

- For **starting**: `cron(0 6 ? * MON-FRI *)`
- For **stopping**: `cron(0 16 ? * MON-FRI *)`

**Step 6.** Set a `JSON` that contains the following expression to know if it's starting or stopping:

- For **starting**:

```json
{
    "Action": "stopped"
}
```

- For **stopping**:

```json
{
    "Action": "running"
}
```

And that's all!

### Follow me on:

|  Personal  |  LinkedIn  |YouTube|Instagram|Cyber Prophets|Sharing Your Stories|
|:----------|:----------|:------------:|:------------:|:------------:|:------------:|
|[![Personal](https://raw.githubusercontent.com/FANMixco/federiconavarrete/master/img/favicons/favicon.png)](https://federiconavarrete.com)|[![LinkedIn](https://i.stack.imgur.com/idQWu.png)](https://www.linkedin.com/in/federiconavarrete)|[![YouTube](https://i.stack.imgur.com/CFPMR.png)](https://youtube.com/c/FedericoNavarrete)|[![Instagram](https://i.stack.imgur.com/PIfqY.png)](https://www.instagram.com/federico_the_consultant)|[![RedCircle Podcast](https://i.stack.imgur.com/4XICF.png)](https://redcircle.com/shows/cyber-prophets)|[![RedCircle Podcast](https://i.stack.imgur.com/4XICF.png)](https://redcircle.com/shows/sharing-your-stories)|

[![sponsor me](https://raw.githubusercontent.com/FANMixco/Xamarin-SearchBar/master/bmc-rezr5vpd.gif)](https://www.buymeacoffee.com/fanmixco)

_Banner credits:_

https://tridentsys.net/howto-schedule-ec2/