How to shut down and restore an Elastic Beanstalk environment.

Let's say you're running an Elastic Beanstalk application. You might want to stop it so that you're not paying money for it. There's one way to do this by running commands. You can use eb terminate and eb restore, but if you terminate a setup with a database and you restore it, the contents of the database won't be restored. You can also only restore an environment that has been terminated within the last 6 weeks.

Let's see how we can terminate and restore without the 6 weeks restriction and let's also see how does the database backup and restore look like.

The first thing that you have to do is to save your environment, which pretty much consists of:

  • Elastic Beanstalk configuration. This is located in the .elasticbeanstalk directory.
  • Environment customizations. They're located in the .ebextensions directory.
  • Your source code. Located in your base directory.
  • A database (optional).

My particular app is a single instance Python/Django application with a MySQL database hosted in RDS.

So let's get started.

Backing up your environment.

First, get the name of your environment. Mine is neatlinks-dev. Run the following commands after that:

export EB_DATE_LABEL=`date +"D%F-T%H-%M-%S"`

# Name of saved config.

# Name of database snapshot.

# Instance id for our current database.
export EB_DB="aaeag9ndvxonft"

# Save the environment cname, we'll need it later.
export EB_CNAME='neatlinks-dev-www'

# Save current config.
eb config save neatlinks-dev --cfg $EB_CONFIG

# Create and wait for database snapshot.
aws rds create-db-snapshot \
    --db-instance-identifier $EB_DB \
    --db-snapshot-identifier $EB_SNAPSHOT_NAME
time aws rds wait db-snapshot-completed \
    --db-instance-identifier $EB_DB \
    --db-snapshot-identifier $EB_SNAPSHOT_NAME

So we did two things:

  1. We saved the environment configuration. You can list your saved configurations by running eb config list.
  2. We created a snapshot of the database.

At this point we can terminate our environment by calling eb terminate. And that's it - Amazon is not charging you anymore - your EC2 instance, RDS instance, load balancers, etc. are down. I don't have a load balancer, but I can verify that everything else is gone.

You should now commit your configs to your source control so that you have them saved when you come back.

Now, your application is sitting safely saved for a while and you decide to restore it.

Restoring your environment.

If you have deleted your application, you'll need to run eb init. After that, we'll run the following commands:

# Create environment. It's important to specify a cname, so that we don't have to
# change our DNS config. This takes a lot of time, so I bump the timeout.
# This command will print the name of your new database instance.
time eb create neatlinks-dev --cfg $EB_CONFIG --cname $EB_CNAME --timeout 30

# Get this id from the printed output of "eb create".
export EB_NEW_DB="aa1q3no37rzd407"

# Delete DB instance. We'll replace it with the snapshot.
aws rds delete-db-instance --db-instance-identifier $EB_NEW_DB --skip-final-snapshot
aws rds wait db-instance-deleted --db-instance-identifier $EB_NEW_DB

# Restore from snapshot.
aws rds restore-db-instance-from-db-snapshot \
        --db-instance-identifier $EB_NEW_DB \
        --db-snapshot-identifier $EB_SNAPSHOT_NAME
aws rds wait db-instance-available --db-instance-identifier $EB_NEW_DB

Your production setup is ready now! Your application probably won't work though, because your DB endpoint is different. Edit your source code or your own configuration files so that your application connects to the new database. Once done, call eb deploy.

That's it. Your application should be running now. You can use this procedure to rename your Elastic Beanstalk application and environment as well, which is a feature that's missing from the eb CLI app.