Skip to main content

AWS EC2 and VPC: Building Your First Cloud Infrastructure

Step-by-step guide to building your first AWS infrastructure — VPCs, subnets, security groups, EC2 instances, and networking fundamentals.

N
Neeraj Jha
·Updated September 11, 2026·5 min read
AWS EC2 and VPC: Building Your First Cloud Infrastructure

Amazon Web Services is the most widely used cloud platform. This guide walks you through setting up your first production-ready infrastructure with EC2 instances inside a properly configured VPC.

What Is a VPC?

A Virtual Private Cloud (VPC) is your own isolated network within AWS. You control the IP address range, subnets, route tables, and security rules.

Creating a VPC

bash
# Using AWS CLI
aws ec2 create-vpc --cidr-block 10.0.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=my-vpc}]'

Or in Terraform:

hcl
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "my-vpc"
  }
}

Subnets

Divide your VPC into public and private subnets across availability zones:

SubnetCIDRTypeAZ
Public A10.0.1.0/24Publicus-east-1a
Public B10.0.2.0/24Publicus-east-1b
Private A10.0.10.0/24Privateus-east-1a
Private B10.0.20.0/24Privateus-east-1b

Public subnets have a route to an Internet Gateway. Private subnets use a NAT Gateway for outbound internet access.

hcl
resource "aws_subnet" "public_a" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "us-east-1a"
  map_public_ip_on_launch = true

  tags = { Name = "public-a" }
}

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.gw.id
  }
}

Security Groups

Security groups act as virtual firewalls for your instances:

hcl
resource "aws_security_group" "web" {
  name   = "web-sg"
  vpc_id = aws_vpc.main.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["YOUR_IP/32"]  # Restrict SSH to your IP
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Key rules: allow HTTP/HTTPS from anywhere, restrict SSH to your IP only.

Launching an EC2 Instance

hcl
resource "aws_instance" "web" {
  ami                    = "ami-0c55b159cbfafe1f0"  # Amazon Linux 2023
  instance_type          = "t3.micro"
  subnet_id              = aws_subnet.public_a.id
  vpc_security_group_ids = [aws_security_group.web.id]
  key_name               = aws_key_pair.deployer.key_name

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  user_data = <<-EOF
    #!/bin/bash
    yum update -y
    yum install -y docker
    systemctl start docker
    systemctl enable docker
    usermod -aG docker ec2-user
  EOF

  tags = { Name = "web-server" }
}

Key Pairs

Create a key pair for SSH access:

bash
# Generate locally
ssh-keygen -t ed25519 -f ~/.ssh/aws-key -C "deploy@myorg"

# Import to AWS
aws ec2 import-key-pair --key-name deployer --public-key-material fileb://~/.ssh/aws-key.pub

Connect:

bash
ssh -i ~/.ssh/aws-key ec2-user@<public-ip>

Elastic IPs

Assign a static public IP so it survives instance restarts:

bash
aws ec2 allocate-address --domain vpc
aws ec2 associate-address --instance-id i-1234567890 --allocation-id eipalloc-abc123

Best Practices

  • Place application servers in private subnets behind a load balancer
  • Use IAM roles instead of access keys on EC2 instances
  • Enable VPC Flow Logs for network monitoring
  • Use multiple availability zones for high availability
  • Encrypt all EBS volumes
  • Tag every resource for cost tracking
  • Use Systems Manager Session Manager instead of direct SSH when possible

Cost Tips

  • Use Spot Instances for non-critical workloads (up to 90% savings)
  • Right-size instances based on CloudWatch metrics
  • Use Reserved Instances or Savings Plans for predictable workloads
  • Set up billing alerts in AWS Budgets

AWS infrastructure starts with a solid VPC foundation. Get the networking right, and everything else — EC2, RDS, ECS, Lambda — builds on top of it.

Tagged with

Enjoyed this article?

Get more DevOps insights delivered to your inbox.

Get new posts by email

Subscribe to get an email when a new blog post is published. Skip anytime.

No spam, unsubscribe anytime.

N

Written by

Neeraj Jha

Platform administrator and lead writer.

View all posts

Discussion

0 comments

Sign in to join the conversation.

Be the first to comment

Start a conversation about this post

Share: