Why Learn Cloud/AWS? Provisioning AWS EC2s in VPC using Terraform with Hands-on Sample ☁️

Mastering AWS and Infrastructure as Code (IaC) tools like Terraform/OpenTofuunlocks endless opportunities in modern cloud computing. Whether you aim to advance your career, optimize cloud operations, or innovate with cutting-edge technologies, cloud skills are an invaluable asset in today’s tech-driven world. Motivation: Where Do Cloud Skills Help Us? Cloud expertise extends beyond IT professionals, it's valuable across various domains: DevOps & SRE Roles: Automating infrastructure, CI/CD pipelines, and monitoring applications. Software Development: Deploying, scaling, and managing cloud-native applications. Data Science & AI/ML: Leveraging cloud-based data lakes, analytics, and AI services. Cybersecurity & Compliance: Securing cloud resources and ensuring regulatory compliance. Enterprise IT & Digital Transformation: Driving business innovation with cloud-first strategies. Freelancers & Entrepreneurs: Hosting applications, automating deployments, and reducing operational costs. Why Learn to Provision with Terraform/OpenTofu? As cloud environments grow more complex, managing infrastructure manually becomes inefficient and error-prone. Infrastructure as Code (IaC) tools like Terraform and OpenTofu simpfly cloud provisioning, making infrastructure deployment reproducible, scalable, and automated. What are EC2, VPC, Subnet, Route Table, IGW, SG, Key Pairs? AWS Elastic Compute Cloud (EC2): EC2 is a web service that provides scalable, on-demand virtual servers in the cloud (virtual machines). It enables users to run applications, host websites, and process workloads without needing physical hardware, offering flexibility, security, and cost-effective computing power. AWS Virtual Private Cloud (VPC): VPC is a secure, isolated network within AWS that allows users to define and control their cloud networking environment. It enables custom IP ranges, subnets, routing, and security settings to securely connect AWS resources to the internet or on-premises networks. VPC Subnets: Logical subdivisions within a VPC that help organize and isolate resources. Subnets can be public (internet-accessible) or private (internal-only). Route Table: A set of rules that determinehow network traffic is directed within a VPC. It controls communication between subnets, the internet, and on-premises networks. Internet Gateway (IGW): A component that enables communication between AWS resources in a VPC and the public internet, allowing public-facing applications to function. Key Pairs: A cryptographic authentication mechanism (public & private keys) used to securely connect to EC2 instances via SSH or RDP. AWS Security Groups (SG): Virtual firewalls that control inbound and outbound traffic for AWS resources, such as EC2 instances. Hands-on Sample This sample shows: how to create Key-pairs (public and private keys) on AWS. how to create EC2s (Ubuntu 20.04, Windows 2019 Server). how to create Virtual Private Cloud (VPC), VPC Components (Public Subnet, Internet Gateway, Route Table) and link to each others. how to create Security Groups (for SSH and Remote Desktop). Code: https://github.com/omerbsezer/Fast-AWS/blob/main/hands-out-labs-code/hands-on-001-ec2-vpc-connect-ec2/main.tf Steps SSH key-pairs (public and private key) are used to connect remote server. Public key (xx.pub) is on the remote server, with private key, user can connect using SSH. There are 2 ways of creating key-pairs (public and private key): Creating them on cloud (AWS) EC2 > Key-pairs > Create Key-Pair Creating them on on-premise "ssh-keygen -t rsa -b 2048" Creating key-pairs on AWS: Go to EC2 > Key-pairs After creating key-pairs, public key will be listed on AWS. Private key (testkey.pem) should be downloaded on your PC. Copy this testkey.pem into your directory on which main.tf exists. Create main.tf under count directory and copy the code: # main.tf terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.81.0" } } required_version = ">= 1.2.0" } provider "aws" { region = "eu-central-1" } resource "aws_vpc" "my_vpc" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags = { Name = "My VPC" } } resource "aws_subnet" "public" { vpc_id = aws_vpc.my_vpc.id cidr_block = "10.0.0.0/24" availability_zone = "eu-central-1c" tags = { Name = "Public Subnet" } } resource "aws_internet_gateway" "my_vpc_igw" { vpc_id = aws_vpc.my_vpc.id tags = { Name = "My VPC - Internet Gateway" } } resource "aws_route_table" "my_vpc_eu_central_1c_public" { vpc_id = aws_vpc.my_vpc.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.my_vpc_igw.id } tags = { Name = "Public Subnet Route Table" } } resource "aws_route_table_association" "my_vpc_eu_central_1c_public" { subnet_id = aws_subnet.p

Apr 3, 2025 - 10:03
 0
Why Learn Cloud/AWS? Provisioning AWS EC2s in VPC using Terraform with Hands-on Sample ☁️

Mastering AWS and Infrastructure as Code (IaC) tools like Terraform/OpenTofuunlocks endless opportunities in modern cloud computing. Whether you aim to advance your career, optimize cloud operations, or innovate with cutting-edge technologies, cloud skills are an invaluable asset in today’s tech-driven world.

Motivation: Where Do Cloud Skills Help Us?

Cloud expertise extends beyond IT professionals, it's valuable across various domains:

  • DevOps & SRE Roles: Automating infrastructure, CI/CD pipelines, and monitoring applications.
  • Software Development: Deploying, scaling, and managing cloud-native applications.
  • Data Science & AI/ML: Leveraging cloud-based data lakes, analytics, and AI services.
  • Cybersecurity & Compliance: Securing cloud resources and ensuring regulatory compliance.
  • Enterprise IT & Digital Transformation: Driving business innovation with cloud-first strategies.
  • Freelancers & Entrepreneurs: Hosting applications, automating deployments, and reducing operational costs.

Why Learn to Provision with Terraform/OpenTofu?

As cloud environments grow more complex, managing infrastructure manually becomes inefficient and error-prone. Infrastructure as Code (IaC) tools like Terraform and OpenTofu simpfly cloud provisioning, making infrastructure deployment reproducible, scalable, and automated.

What are EC2, VPC, Subnet, Route Table, IGW, SG, Key Pairs?

  • AWS Elastic Compute Cloud (EC2): EC2 is a web service that provides scalable, on-demand virtual servers in the cloud (virtual machines). It enables users to run applications, host websites, and process workloads without needing physical hardware, offering flexibility, security, and cost-effective computing power.
  • AWS Virtual Private Cloud (VPC): VPC is a secure, isolated network within AWS that allows users to define and control their cloud networking environment. It enables custom IP ranges, subnets, routing, and security settings to securely connect AWS resources to the internet or on-premises networks.
  • VPC Subnets: Logical subdivisions within a VPC that help organize and isolate resources. Subnets can be public (internet-accessible) or private (internal-only).
  • Route Table: A set of rules that determinehow network traffic is directed within a VPC. It controls communication between subnets, the internet, and on-premises networks.
  • Internet Gateway (IGW): A component that enables communication between AWS resources in a VPC and the public internet, allowing public-facing applications to function.
  • Key Pairs: A cryptographic authentication mechanism (public & private keys) used to securely connect to EC2 instances via SSH or RDP.
  • AWS Security Groups (SG): Virtual firewalls that control inbound and outbound traffic for AWS resources, such as EC2 instances.

Hands-on Sample

This sample shows:

  • how to create Key-pairs (public and private keys) on AWS.
  • how to create EC2s (Ubuntu 20.04, Windows 2019 Server).
  • how to create Virtual Private Cloud (VPC), VPC Components (Public Subnet, Internet Gateway, Route Table) and link to each others.
  • how to create Security Groups (for SSH and Remote Desktop).

Code: https://github.com/omerbsezer/Fast-AWS/blob/main/hands-out-labs-code/hands-on-001-ec2-vpc-connect-ec2/main.tf

ec2-vpc

Steps

  • SSH key-pairs (public and private key) are used to connect remote server. Public key (xx.pub) is on the remote server, with private key, user can connect using SSH.

  • There are 2 ways of creating key-pairs (public and private key):

    • Creating them on cloud (AWS)
    • EC2 > Key-pairs > Create Key-Pair
    • Creating them on on-premise
    • "ssh-keygen -t rsa -b 2048"
  • Creating key-pairs on AWS: Go to EC2 > Key-pairs

Image description

  • After creating key-pairs, public key will be listed on AWS. Private key (testkey.pem) should be downloaded on your PC. Copy this testkey.pem into your directory on which main.tf exists.

Image description

  • Create main.tf under count directory and copy the code:
# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.81.0"
    }
  }
  required_version = ">= 1.2.0"
}

provider "aws" {
    region = "eu-central-1"
}

resource "aws_vpc" "my_vpc" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  tags = {
    Name = "My VPC"
  }
}

resource "aws_subnet" "public" {
  vpc_id            = aws_vpc.my_vpc.id
  cidr_block        = "10.0.0.0/24"
  availability_zone = "eu-central-1c"
  tags = {
    Name = "Public Subnet"
  }
}

resource "aws_internet_gateway" "my_vpc_igw" {
  vpc_id = aws_vpc.my_vpc.id
  tags = {
    Name = "My VPC - Internet Gateway"
  }
}

resource "aws_route_table" "my_vpc_eu_central_1c_public" {
    vpc_id = aws_vpc.my_vpc.id
    route {
        cidr_block = "0.0.0.0/0"
        gateway_id = aws_internet_gateway.my_vpc_igw.id
    }
    tags = {
        Name = "Public Subnet Route Table"
    }
}
resource "aws_route_table_association" "my_vpc_eu_central_1c_public" {
    subnet_id      = aws_subnet.public.id
    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id
}

resource "aws_security_group" "allow_ssh" {
  name        = "allow_ssh_sg"
  description = "Allow SSH inbound connections"
  vpc_id      = aws_vpc.my_vpc.id
  # for SSH
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  # for HTTP Apache Server
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  # for RDP
  ingress {
    from_port        = 3389
    to_port          = 3389
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }
  # for ping
  ingress {
    from_port        = -1
    to_port          = -1
    protocol         = "icmp"
    cidr_blocks      = ["10.0.0.0/16"]
  }
  egress {
    from_port       = 0
    to_port         = 0
    protocol        = "-1"
    cidr_blocks     = ["0.0.0.0/0"]
  }
  tags = {
    Name = "allow_ssh_sg"
  }
}

resource "aws_instance" "ubuntu2004" {
  ami                         = "ami-0e067cc8a2b58de59" # Ubuntu 20.04 eu-central-1 Frankfurt, you can also select newer version from AWS Console, shown below
  instance_type               = "t2.nano"
  key_name                    = "testkey"
  vpc_security_group_ids      = [aws_security_group.allow_ssh.id]
  subnet_id                   = aws_subnet.public.id
  associate_public_ip_address = true
  user_data = <<-EOF
                #! /bin/bash
                sudo apt-get update
                sudo apt-get install -y apache2
                sudo systemctl start apache2
                sudo systemctl enable apache2
                echo "

Deployed via Terraform from $(hostname -f)

" | sudo tee /var/www/html/index.html
EOF tags = { Name = "Ubuntu 20.04" } } resource "aws_instance" "win2019" { ami = "ami-02c2da541ae36c6fc" # Windows 2019 Server eu-central-1 Frankfurt, you can also select newer version from AWS Console, shown below instance_type = "t2.micro" key_name = "testkey" vpc_security_group_ids = [aws_security_group.allow_ssh.id] subnet_id = aws_subnet.public.id associate_public_ip_address = true tags = { Name = "Win 2019 Server" } } output "instance_ubuntu2004_public_ip" { value = "${aws_instance.ubuntu2004.public_ip}" } output "instance_win2019_public_ip" { value = "${aws_instance.win2019.public_ip}" }

Code: https://github.com/omerbsezer/Fast-AWS/tree/main/hands-out-labs-code/hands-on-001-ec2-vpc-connect-ec2/main.tf

  • Note: You can change the AMI from EC2 > Launch Instance

Image description

  • These AMI IDs vary depends on the region. Following image shows the region eu-central-1, Ubuntu AMIs.

Image description

  • Run init command:
terraform init

Image description

  • Validate file:
terraform validate
  • Run plan command:
terraform plan
  • Run apply command to create resources. Then, Terraform asks to confirm, write "yes":
terraform apply

Image description

  • On AWS EC2 > Instances, Ubuntu 20.04, Window 2019 Server:

Image description

  • Security groups (SSG), for SSH (port 22), RDP (port 3389), HTTP (80), ICMP (for ping) for Inbound rules:

Image description

  • Storage, Elastic Block Storage default:

Image description

  • On AWS VPC (Virtual Private Cloud) Service:

Image description

  • While installing Ubuntu20.04, userdata is used to install Apache Server on it. With SSG Port 80, using public IP, we can see the index.html, like hosting server:

Image description

  • SSH to Ubuntu 20.04 (ssh -i testkey.pem ubuntu@):

Image description

  • Run:
sudo apt install net-tools
ifconfig 
  • Private IP can be seen:

Image description

  • Make remote connection to Windows (RDP):

Image description

  • Download RDP App, to get password, upload testkey.pem file:

Image description

  • Now, we reach Windows using RDP, pinging to Ubuntu20.04 from Windows:

Image description

  • Destroy infrastructure:
terraform destroy 

Image description

  • Be sure that instances are terminated. Because if they works, it costs money.

Image description

Conclusion

In this post, we mentioned:

  • why should we learn Cloud/AWS, IaC/Terraform,
  • how to provision AWS EC2, VPC, IGW, Route Table, SG,
  • how to access Ubuntu and Windows EC2s.

If you found the tutorial interesting, I’d love to hear your thoughts in the blog post comments. Feel free to share your reactions or leave a comment. I truly value your input and engagement