Hey everyone! 👋 I just spent a few hours working through an AWS lab that taught me three different ways to deploy resources. I wanted to document everything I did while it's fresh in my mind - both to solidify my own understanding and to share the knowledge. Let's dive in!
Part 1: Creating a VPC in the AWS Console
So today I dived into creating a Virtual Private Cloud (VPC) from scratch. If you're like me and wondered what a VPC actually is - it's basically your own private section of the AWS cloud where you can launch resources in a network, you control. Think of it as your own little island in the vast AWS ocean!
First, I navigated to the VPC dashboard (just search "VPC" in the search bar) and created a new VPC named "Lab VPC A" with the CIDR block 10.0.0.0/16. If CIDR blocks confuse you as much as they confused me at first, just think of them as defining the range of IP addresses your VPC can use.
Next came the public subnet, which I named "Public Subnet 1" with CIDR block 10.0.0.0/24. Subnets are smaller chunks of your VPC network - kind of like dividing your island into neighborhoods.
The most interesting part was setting up the internet gateway. Without this, your VPC would be completely isolated from the internet - not very useful for most applications! After creating the gateway, I had to attach it to my VPC.
It's like building a bridge from your island to the mainland and putting up road signs to tell traffic where to go! For complete guide to create VPC check here.
Creating and Configuring a Route Table
Now I needed to create a route table and configure it to use the internet gateway:
- In the VPC dashboard, I clicked on "Route tables"
- I clicked "Create route table"
- I named it "Public Route Table", selected "Lab VPC A" for the VPC, and clicked "Create route table"
- Once created, I needed to add a route to the internet:
- I selected my "Public Route Table" then on the "Routes" tab clicked "Edit routes".
- Then I clicked "Add route" for Route 2.
- For Destination, I entered 0.0.0.0/0 (which means "all traffic")
- For Target, I selected "Internet Gateway" and then chose my internet gateway from the dropdown
- I clicked "Save changes"
- Finally, I associated my subnet with this route table:
- On the "Subnet associations" tab I clicked "Edit subnet associations"
- I selected the checkbox for "Public Subnet 1" and clicked "Save associations"
At this point, I had successfully created a VPC with a public subnet that had internet connectivity! I double-checked everything by looking at the VPC dashboard and confirming my resources were created correctly.
Part 2: Using CloudShell to Prepare for CloudFormation
Now it was time to use the AWS CLI through CloudShell to gather some information I'd need for the next part.
Finding the Latest Amazon Linux AMI ID
- I opened CloudShell by clicking the CloudShell icon in the AWS Management Console
- Once it loaded, I ran this command to get the latest Amazon Linux 2023 AMI ID:
Bash aws ssm get-parameters \ --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 \ --region us-east-2 --query "Parameters[0].Value" \ --output text
- The command returned something like
ami-01810676724171ee44a4
(your actual AMI ID will likely be different) - Still in CloudShell, I ran this command to find the ID of the subnet I created earlier:
This returned something likeBash aws ec2 describe-subnets \ --filters "Name=tag:Name,Values=Public Subnet 1" \ --query "Subnets[0].SubnetId" --output text
subnet-0a028d42122daa4ba5
Finally, I needed to find a specific security group ID:
Bash aws ec2 describe-security-groups \ --filters "Name=group-name,Values=WebSG-55043156" \ --query "SecurityGroups[0].GroupId" --output text
- This returned something like
sg-0b985w2b3a8gc8155
What's cool about using the CLI this way is that it's much faster than clicking around the console trying to find these IDs. I could see how this would be super useful for automation.
Part 3: Deploying EC2 Resources Using CloudFormation
Now for the most exciting part - using Infrastructure as Code to deploy an EC2 instance!
Opening CloudFormation
- I went back to the AWS Management Console and searched for "CloudFormation"
- I clicked on the CloudFormation service
- In the navigation pane, I clicked "Infrastructure Composer".
Creating a CloudFormation Template
- In the Infrastructure Composer, I clicked on the "Template" tab
- I entered the following JSON code (substituting my actual IDs that I collected earlier):
JSON { "AWSTemplateFormatVersion": "2025-09-09", "Description": "EC2 Instance with Security Group", "Resources": { "WebServer1Instance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": "ami-018106724171ee44a4", "InstanceType": "t2.micro", "SubnetId": "subnet-0a028d42122daa4ba5", "SecurityGroupIds": ["sg-0b985w2b3a8gc8155"], "Tags": [ { "Key": "Name", "Value": "WebServer1" } ] } } } }
- I clicked "Create template"
- In the dialog that appeared, I clicked "Confirm and continue to CloudFormation"
Deploying the CloudFormation Stack
- On the "Create stack" page, I verified that my template was successfully imported
- For "Stack name", I entered "DeployEC2"
- I clicked "Next" on the "Configure stack options" page
- On the "Review and create" page, I reviewed all settings
- I clicked "Submit" to create the stack
- I monitored the stack creation process on the CloudFormation console
- After a few minutes, I saw the status change to "CREATE_COMPLETE"
Verifying the EC2 Instance
- I went to the EC2 console by searching for "EC2" in the AWS Management Console
- I clicked on "Instances" in the navigation pane
- I found my new instance named "WebServer1"
- I waited until:
- The "Instance state" showed "Running"
- The "Status check" showed "2/2 checks passed"
And with that, I had successfully deployed an EC2 instance using CloudFormation! The whole process took me about 30-40 minutes from start to finish, including the time I spent trying to understand each step.
What I Learned
-
Using the Console feels beginner-friendly, but it can get repetitive.
-
The CLI is faster once you know the commands.
-
CloudFormation is like infrastructure automation—you write once, deploy many times.
This lab was a neat way to see how all three approaches connect. It felt like leveling up from "clicking around" to "writing code that builds stuff automatically."
👉 If I had more time, I’d definitely try tweaking the CloudFormation template to launch multiple instances or add more resources. But for today, I’m just happy my little WebServer1 came to life inside AWS.