Using AMIs to Recreate EC2 Instances in a Custom VPC

Once you’ve configured a Virtual Private Cloud (VPC) and launched an EC2 instance with everything working—from your application code to installed services—you may want to save that setup for future reuse. Amazon Machine Images (AMIs) allow you to preserve the exact state of your EC2 instance, so you can launch it again in the future without repeating all your setup steps.
This section explains what an AMI is, why it’s helpful, and how to create one. You’ll also learn how to launch a new EC2 instance from an AMI inside your custom VPC, along with important notes about what data carries over—and what doesn’t.
What is an AMI?
An Amazon Machine Image is a snapshot of an EC2 instance at a specific point in time. It captures the operating system, installed software, system configurations, and application files. It can also include environment settings, log files, and containerized applications if they reside on the root volume.
Think of an AMI as a full backup of your EC2 instance that you can use to recreate the same environment elsewhere—with just a few clicks.
Why use AMIs?
AMIs are useful in a number of everyday scenarios:
- Preserving a working server setup before making significant changes
- Cloning an environment for testing, staging, or training
- Creating identical application servers across multiple availability zones or regions
- Migrating an application between different VPCs or accounts
In short, AMIs help you move faster by allowing you to reuse a working setup, rather than rebuilding it each time.
What gets carried over
When creating and launching an AMI, it’s important to understand what parts of your instance are preserved—and what you’ll need to configure again.
Included in the AMI:
- Operating system and OS-level settings
- Installed packages and dependencies
- Application files and environment variables
- Docker containers and configurations
- Data stored on the root EBS volume—including application logs and database files
If your original EC2 instance runs a PostgreSQL database inside a Docker container, and that database stores its data on the root volume (e.g., in a volume mounted at /var/lib/postgresql/data
), then the database data will also be captured in the AMI. When you launch a new instance from the AMI, the Docker container will include the PostgreSQL data as it existed at the time the image was created.
Creating an AMI from an existing EC2 instance
Let’s walk through the steps to create an AMI using the AWS Management Console.
Open the EC2 service. Under “Instances,” locate the instance you want to create an image from.

Select your instance, click the “Actions” dropdown menu, go to “Image and templates,” and choose “Create image.”

You’ll be taken to the Create Image screen. Fill in the following:
- Image name: Use a descriptive name that helps you identify its purpose e.g.,
image-sharing-app-AMI
- Description: Optional but helpful if you're managing multiple AMIs
- No reboot: Leave this unchecked for this practice. AWS reboots the instance to ensure a clean image.
Keep other settings as they are. Click “Create image” to start the process.
Launching a new EC2 instance from an AMI
Once your AMI is available, you can launch a new EC2 instance based on it. This is especially helpful if you want to duplicate your setup within your custom VPC.
In the EC2 Dashboard, go to “AMIs,” select your image, and click “Launch instance from image.”

Name and tags
Enter a descriptive name for your new instance—for example, image-sharing-app-custom-VPC
. This helps you recognize it later in the instance list. You can skip the tags unless you want to organize resources by environment or owner.

Application and OS Images
You don’t need to change anything here. The AMI you selected is already filled in and includes your application code, Docker environment, and PostgreSQL database from the original setup.
Key pair (login)
Select the same key pair you used when launching your original instance—for example, image-sharing-app-key
. This allows you to securely connect to your server. If you no longer have access to it, create a new key and download it right away.

Network settings
Click the Edit link in this section. Set the network to the custom VPC you created earlier.
Then choose a public subnet within that VPC to ensure the instance can connect to the internet.
Make sure that Auto-assign public IP is enabled so you’ll be able to access the instance from your local machine or browser.
Firewall (security groups), controlling what kind of traffic can reach your instance. It’s important to know that security groups are specific to each VPC. If you created a group like launch-wizard-1
in your default VPC, it won’t be available when launching an instance inside your custom VPC.
If that group isn’t visible in the list, you’ll need to create a new one here. Choose Create security group, and allow the following inbound traffic:
- SSH (port 22) so you can log in to the server
- HTTP (port 80) and HTTPS (port 443) so your web application is accessible
By default, AWS will allow traffic from any IP address (0.0.0.0/0), which is acceptable for now. You can restrict access later as needed.

Configure storage
The storage settings will automatically match the root volume from your original instance. No changes are needed here unless your application has grown significantly. Since your PostgreSQL database and app data were stored on the root volume using Docker, everything will be carried over when the instance is launched.
After reviewing these settings, click Launch instance.
Once your instance reaches the Running state, you can connect to it and verify that your application, Docker services, and database are working as expected—just like they were on the original server.
Verifying the new instance and cleaning up old resources
After launching a new EC2 instance from your AMI, the next step is to confirm that everything is working as expected. This includes connecting to the instance, updating configuration values for the new IP address, verifying that your application and database are running, and finally removing old resources to avoid unnecessary charges.
Step 1: Update SSH configuration and connect
If you’re using an SSH config file, open it and update the HostName
field with your new instance’s public IP address. You can reuse the same host alias if you’re replacing the original instance, or create a new alias if you want to keep both entries for reference.
~/.ssh/config
Host image-sharing-new
HostName <your-NEW-ec2-ip>
User ec2-user
IdentityFile ~/.ssh/image-sharing-app-key.pem
Once updated, you can connect to the new instance just like before.
Step 2: Check running containers and update environment configuration
After connecting to your new instance, start by checking whether your application containers are running. Run the following command:
docker ps
You should see that your containers—including the Django app and PostgreSQL database—are already running. This happens because the AMI captured their state from the original instance, and Docker was configured to start automatically on system boot.
However, if you try to access the app by entering the new instance’s IP address in your browser, you may find that the site does not load. This is expected—and it’s due to a configuration setting in your application.
By default, Django uses the ALLOWED_HOSTS
setting to restrict access for security. In your project, this is likely configured in the .env.prod
file. If it still lists the old IP address, Django will block any requests coming from the new one.
Update the following parts in the .env.prod
file.
ALLOWED_HOSTS=localhost,127.0.0.1,NEW-IP-ADDRESS
# Server IP (for nginx)
SERVER_IP=NEW-IP-ADDRESS
Once the file is updated, you need to rebuild and restart the containers so the new environment settings take effect. Run the following commands from your project directory:
docker-compose -f docker-compose.prod.yml --env-file .env.prod down
docker-compose -f docker-compose.prod.yml --env-file .env.prod up --build -d
After a moment, the containers will restart with the new settings in place. Now, open the new instance’s IP address in your browser again—you should see your application load successfully.
This confirms that the app is now correctly bound to the new instance and accepting web traffic.
Step 3: Confirm the application and data
With the new settings in place, open your browser and go to the new instance’s public IP address.
Check that:
- The web application loads correctly
- Existing data (like uploaded images or user entries) is present
- Basic functionality, such as login or upload features, is working as expected
- The database is still connected and responding
Since the AMI preserved your original root volume, everything should carry over—including Docker containers, app code, and the PostgreSQL database stored inside the container.
If everything is functioning correctly, your migration was successful.
Cleaning up resources once practice is completed
After you've successfully launched and tested your new EC2 instance, it's a good idea to clean up any unused resources to avoid ongoing costs and keep your AWS environment tidy and secure.
Terminate or stop the original instance
If you no longer need the original EC2 instance, the easiest option is to terminate it.
Terminating an instance will permanently delete it. By default, the root volume (the one that holds the OS and app files) is also deleted when the instance is terminated.
To terminate:
- Go to the EC2 Dashboard.
- Click Instances
- Select the original instance
- Choose Instance state → Terminate instance, and confirm

If you’re not ready to delete it yet, you can stop the instance instead. A stopped instance won’t incur compute charges; however, the attached volumes will still be billed as long as they exist. Be mindful that volumes from stopped instances continue to accumulate storage costs until explicitly deleted
Deregister the AMI and Delete Its Snapshot
If you've created an AMI as part of your migration or backup, you may want to deregister it once you're confident that the new instance is stable. While creating an AMI is free, AWS stores it using a snapshot, which does incur a monthly fee.
To clean it up:
Deregister the AMI
- Go to EC2 → AMIs
- Select the image you no longer need
- Click Actions → Deregister AMI, and confirm

Delete the Snapshot
- Go to EC2 → Snapshots
- Find the snapshot linked to that AMI (match by creation time or description)
- Select it, click Actions → Delete Snapshot, and confirm

Deregistering the AMI removes it from your account, but it doesn’t automatically delete the snapshot—so don’t skip the second step.
Security Tip
Remember, when you create an AMI, it includes everything on your instance’s root volume—your app files, Docker images, logs, and environment configuration like .env.prod
.
If that file contains API keys, database credentials, or other sensitive values, keeping unused AMIs or snapshots increases your exposure risk—especially if someone else in your team later reuses it without realizing what’s inside.
To stay safe, remove AMIs and snapshots you no longer need—especially after you’ve launched and verified the new instance.

Understanding AMI, Snapshot, Volume, and EC2 Instance
When you start using Amazon EC2, you'll quickly notice a few core terms that come up often: EC2 instance, volume, snapshot, and AMI. These parts all work together to make your cloud-based infrastructure run smoothly. Once you understand how they connect, managing and replicating your environments becomes much easier.

EC2 Instance
An EC2 instance is like a computer that lives in the cloud. You can install software on it, store files, run your web app, and access it from anywhere. Instead of sitting on a physical desk, this server runs in one of Amazon’s data centers.
To function, your EC2 instance needs storage—just like any computer. That’s where volumes come in.
Volume
A volume is the storage space your instance uses. The main one, called the root volume, contains everything the system needs to start up—like the operating system and your application files. If your project grows, you can also attach extra volumes.
Here’s the key idea:
A volume is live and dynamic. As your app runs, this is where data is saved, logs are written, and changes happen in real time. It’s always up to date—until you decide to freeze it in place.
Snapshot
A snapshot is a backup of a volume at a single point in time. It saves the entire state of your data and stores it in Amazon’s storage system (S3, behind the scenes).
If something breaks or you want to replicate that exact setup later, the snapshot lets you restore everything as it was at the moment you took it.
To picture it:
- A volume is like a working document you're actively editing.
- A snapshot is when you make a frozen copy to save that version—kind of like hitting “Save As” in a text editor.
Every time you create an AMI (coming next), AWS automatically takes a snapshot of your root volume.
AMI (Amazon Machine Image)
An AMI is a reusable template you can use to launch new EC2 instances. It includes:
- A snapshot of your root volume (so it has the OS, your app, and everything else already set up)
- Some basic instructions, like what type of instance to launch and how users can connect
When you start a new instance from an AMI, AWS takes that stored snapshot, turns it into a new volume, and attaches it to the fresh instance. You now have a fully configured server—just like the original—without doing any manual setup again.
Quick Summary
Here’s the basic flow:
- You run an EC2 instance, which stores data on a volume
- You create an AMI, which includes a snapshot of that volume
- Later, you launch a new EC2 instance from the AMI
- AWS restores the snapshot into a new volume and connects it to the new instance
In short..
- EC2 instance: your running server
- Volume: the live storage attached to it
- Snapshot: a frozen backup of that storage
- AMI: a ready-to-use image built from the snapshot, used to launch more instances
Wrapping up
AMIs make it easy to recreate your EC2 setup—complete with Docker, PostgreSQL, and application files—without starting from scratch. They're especially useful when migrating to a new VPC or duplicating environments.
Just remember to update IP-specific settings after launch, and clean up any unused AMIs and snapshots to reduce cost and limit security risk from files like .env.prod
.
Next, we’ll move your database out of the EC2 instance and into Amazon RDS, a fully managed relational database service that’s built for scalability and easier long-term maintenance.