🚀 Launching an EC2 Instance with Terraform – A Complete Guide

BinereetDevopsBinereetDevops
3 min read

In this blog, we'll walk through how to launch an EC2 instance using Terraform from scratch. We’ll include everything—from generating key pairs to configuring security groups, writing Terraform configurations, and finally deploying the EC2 instance.


✅ Step 1: Creating a Key Pair

First, generate an SSH key pair to securely access your EC2 instance.

Generate SSH Key:

ssh-keygen -f terra-key-ec2

This command will generate two files:

  • terra-key-ec2.pub (public key)

  • terra-key-ec2 (private key)

🔐 Public key will be added to EC2 so that it knows to trust you. 🗝️ Private key must be stored safely on your local machine (e.g., in ~/.ssh/) and used for SSH.


✅ Step 2: Provider Configuration (providers.tf)

provider "aws" {
  region = "us-east-1"
  access_key = "<your-access-key>"
  secret_key = "<your-secret-key>"
}

This file tells Terraform which cloud provider to use and sets your credentials and region.


✅ Step 3: Writing EC2 Resources (ec2.tf)

🔑 Key Pair Resource

resource "aws_key_pair" "my_key" {
  key_name   = "terra-key-ec2"
  public_key = file("terra-key-ec2.pub")
}

This uploads your public key to AWS under the name terra-key-ec2. The instance will use this for SSH authentication.

🌐 Default VPC

resource "aws_default_vpc" "default" {}

This creates (or fetches) the default AWS VPC so that we can attach EC2 and security groups to it.

🔒 Security Group

resource "aws_security_group" "my_security_group" {
  name        = "automate-sg"
  description = "this will add a TF generated Security group"
  vpc_id      = aws_default_vpc.default.id

➕ Inbound Rules

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "SSH open"
  }

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

  ingress {
    from_port   = 8000
    to_port     = 8000
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Flask app"
  }

These rules allow traffic to your instance:

  • Port 22: SSH

  • Port 80: Web server (HTTP)

  • Port 8000: Flask app or custom app

🔁 Outbound Rule

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    description = "all access open outbound"
  }

Allows all outgoing traffic from your EC2.

🏷️ Tags

  tags = {
    Name = "automate-sg"
  }
}

Adds a name tag to your SG for easy identification.

💻 EC2 Instance

resource "aws_instance" "my_instance" {
  key_name        = aws_key_pair.my_key.key_name
  security_groups = [aws_security_group.my_security_group.name]
  instance_type   = "t2.micro"
  ami             = "ami-0cb91c7de36eed2cb"  # Ubuntu AMI

Specifies the EC2 instance details:

  • Uses your key pair

  • Uses the created security group

  • t2.micro is free-tier eligible

  • Ubuntu AMI

💾 Storage Configuration

  root_block_device {
    volume_size = 15
    volume_type = "gp3"
  }

Defines the volume (disk) configuration:

  • 15 GB size

  • gp3 type (general purpose SSD)

🏷️ Tags

  tags = {
    Name = "TWS-Junoon-automate"
  }
}

Tags help you organize and manage resources.


🧪 Terraform Commands

Run the following commands:

terraform init      # Initialize Terraform
terraform plan      # See what Terraform will do
terraform apply     # Apply and create resources
terraform destroy   # Destroy everything

🔐 SSH into EC2

Once the EC2 is up, SSH into it using the private key:

chmod 400 terra-key-ec2
ssh -i terra-key-ec2 ubuntu@<ec2-public-ip>

🎉 Conclusion

You’ve now successfully deployed an EC2 instance with Terraform from scratch—including key pair, security group, and storage settings. This is a great starting point for automating your infrastructure!

Happy Terraforming! 💻🌍

My LinkedIn Profile - https://www.linkedin.com/in/binereet-singh/

0
Subscribe to my newsletter

Read articles from BinereetDevops directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

BinereetDevops
BinereetDevops