DEV Community

Isaac Ntumpi
Isaac Ntumpi

Posted on

Set It and Forget It: Automate Daily EC2 Lifecycle with Python Like a Pro

A Cloud Engineer's Midnight Regret

Image description

It’s 00:12 AM.
You’re brushing your teeth, mentally preparing for tomorrow’s stand-up, when it hits you like a thunderbolt:

“Wait… did I forget to shut down the EC2 instances?”

You sprint back to your laptop, heart racing, praying your cloud bill isn’t already ballooning past reason.
The AWS Console loads… slowly.
You sigh in frustration.
Another night, another bill for machines you weren’t using.

If this scene feels familiar, you’re not alone. Many engineers — from solo devs to seasoned sysadmins — struggle to manage cloud resources with surgical precision, especially when those resources are needed only part of the day.

The good news?
There’s a fix — and it’s beautifully simple.

In this article, you’ll build a smart, Python-powered automation that shuts down all your EC2 instances at midnight and wakes them up at 5 AM — every day — without fail.
We’ll walk through the process step by step, with logs you can watch live and full control over your infrastructure. No serverless complexity, no expensive automation platforms.

Just you, Python, and a little crontab magic.
Let’s automate like professionals.

Prerequisites

Make sure you have the following ready:

  • An AWS account with programmatic access (Access Key & Secret)
  • A Linux environment (local machine, EC2 instance, or WSL on Windows)
  • Python 3 installed
  • boto3 and awscli installed

[Step 1: Install Required Tools]

Install the AWS SDK for Python:

pip install boto3
Enter fullscreen mode Exit fullscreen mode

Configure your AWS credentials:

aws configure
Enter fullscreen mode Exit fullscreen mode

You'll be prompted to enter:

  • Your Access Key ID
  • Your Secret Access Key
  • Default AWS region (e.g. us-east-1)
  • Default output format (e.g. json) This generates the necessary configuration under ~/.aws/credentials.

[Step 2: Write the Python Scripts]

We'll create two Python scripts:

  • stop_ec2.py → to stop instances at 00:00
  • start_ec2.py → to start instances at 05:00

Let’s get started.

stop_ec2.py

mkdir ~/ec2_scheduler
cd ~/ec2_scheduler
nano stop_ec2.py
Enter fullscreen mode Exit fullscreen mode

Paste the following code:

#!/usr/bin/env python3
import boto3

def stop_all_instances():
    ec2 = boto3.client('ec2')
    response = ec2.describe_instances(Filters=[{
        'Name': 'instance-state-name',
        'Values': ['running']
    }])

    instances_to_stop = []
    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            instances_to_stop.append(instance['InstanceId'])

    if instances_to_stop:
        print("Stopping instances:", instances_to_stop)
        ec2.stop_instances(InstanceIds=instances_to_stop)
    else:
        print("No running instances found.")

if __name__ == "__main__":
    stop_all_instances()
Enter fullscreen mode Exit fullscreen mode

Make it executable:

chmod +x stop_ec2.py
Enter fullscreen mode Exit fullscreen mode

start_ec2.py
Now let’s create the startup script:

nano start_ec2.py
Enter fullscreen mode Exit fullscreen mode

Paste this:

#!/usr/bin/env python3
import boto3

def start_all_instances():
    ec2 = boto3.client('ec2')
    response = ec2.describe_instances(Filters=[{
        'Name': 'instance-state-name',
        'Values': ['stopped']
    }])

    instances_to_start = []
    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            instances_to_start.append(instance['InstanceId'])

    if instances_to_start:
        print("Starting instances:", instances_to_start)
        ec2.start_instances(InstanceIds=instances_to_start)
    else:
        print("No stopped instances found.")

if __name__ == "__main__":
    start_all_instances()
Enter fullscreen mode Exit fullscreen mode

And make it executable too:

chmod +x start_ec2.py
Enter fullscreen mode Exit fullscreen mode

[Step 3: Schedule Scripts Using crontab]

Open the crontab editor:

crontab -e
Enter fullscreen mode Exit fullscreen mode

Add the following lines at the bottom:

0 0 * * * /usr/bin/python3 /home/isaac/ec2_scheduler/stop_ec2.py >> /home/your_user/ec2_scheduler/stop.log 2>&1
0 5 * * * /usr/bin/python3 /home/isaac/ec2_scheduler/start_ec2.py >> /home/your_user/ec2_scheduler/start.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Replace /home/isaac/ with your actual username or full path.

You can verify your crontab jobs were added:

crontab -l
Enter fullscreen mode Exit fullscreen mode

[Step 4: Monitor with tail -f]

To watch logs in real time:

tail -f ~/ec2_scheduler/stop.log
# or
tail -f ~/ec2_scheduler/start.log
Enter fullscreen mode Exit fullscreen mode

You'll see output like:

Stopping instances: ['i-01abcd2345efgh678']
Enter fullscreen mode Exit fullscreen mode

or

No stopped instances found.
Enter fullscreen mode Exit fullscreen mode

IAM Policy Required

Your IAM user or role should have the following minimum permissions:
It's a json file

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeInstances",
        "ec2:StartInstances",
        "ec2:StopInstances"
      ],
      "Resource": "*"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Manual Testing (Optional)

You can manually trigger the scripts to test them before relying on the cron jobs:

python3 stop_ec2.py
python3 start_ec2.py
Enter fullscreen mode Exit fullscreen mode

Then check the logs with:

tail ~/ec2_scheduler/stop.log
tail ~/ec2_scheduler/start.log
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this tutorial, we’ve built a clean, reliable automation to manage AWS EC2 instances using nothing but Python and Linux’s built-in cron scheduler. This setup is especially helpful for dev/test environments, overnight cost reduction, or any non-production workloads that don’t need to be running 24/7.

By combining boto3, crontab, and log monitoring with tail -f, you've gained fine-grained control over your cloud environment — no expensive scheduler tools, no overengineering. Just simple, effective DevOps.

Take it further by filtering EC2 instances by tags, regions, or instance types, or by sending email alerts on failures.

Automation isn't just about convenience — it's about discipline, consistency, and clarity in your operations.

Heroku

Built for developers, by developers.

Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you the simplest path to delivering apps quickly — using the tools and languages you already love!

Learn More

Top comments (0)

Sentry image

Make it make sense

Only get the information you need to fix your code that’s broken with Sentry.

Start debugging →