Skip to content
Go back

Terraform - Create and SSH into an AWS EC2 Instance Using Terraform (Free Tier Guide for Beginners)

Published:

step-by-step to create a Virtual Machine (EC2 instance) on AWS Free Tier using Terraform and SSH to it.


Create a key pair in AWS Console (if you don’t have one)

aws key pair create

Download and move it to your project Directory and Check Permissions of the .pem File

chmod 400 my-key.pem

✅ Install Required Packages

1. Install AWS CLI

sudo apt update
sudo apt install awscli -y

Verify:

aws --version

2. Install Terraform

sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt install terraform -y

Verify:

terraform -version

✅ Configure AWS CLI

💡 Get access keys from: AWS Console > IAM > Users > Your Username > Security Credentials > Access Keys

terraform aws key

aws configure

Enter the following:

After this steps, two files are auto created inside /home/username/.aws

aws config


✅ Create Terraform Configuration

1. Create a folder

mkdir terraform-aws
cd terraform-aws

2. Create main.tf

nano main.tf

Paste the following:

# --------------------------------------------------
# Terraform block to specify required providers
# --------------------------------------------------
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"  # Using a stable version of AWS provider
    }
  }
}

# --------------------------------------------------
# AWS provider configuration
# --------------------------------------------------
provider "aws" {
  region = "us-east-1"  # AWS region to deploy resources
}

# --------------------------------------------------
# Data block to fetch default VPC (used by security group)
# --------------------------------------------------
data "aws_vpc" "default" {
  default = true
}

# --------------------------------------------------
# Security group resource to allow SSH access
# --------------------------------------------------
resource "aws_security_group" "ssh_access" {
  name        = "allow_ssh"
  description = "Allow SSH inbound traffic"
  vpc_id      = data.aws_vpc.default.id  # Attach to the default VPC

  # Inbound rule to allow SSH from any IP
  ingress {
    description = "SSH from anywhere"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]  # ⚠️ For production, replace with your IP (e.g. ["203.0.113.0/32"])
  }

  # Outbound rule to allow all traffic
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# --------------------------------------------------
# EC2 instance resource
# --------------------------------------------------
resource "aws_instance" "my_ec2" {
  ami           = "ami-0c2b8ca1dad447f8a"  # Amazon Linux 2 AMI (Free tier eligible)
  instance_type = "t2.micro"              # Free tier eligible instance type
  key_name      = "terraform-janak"       # Replace with the name of your existing AWS EC2 key pair
  security_groups = [aws_security_group.ssh_access.name]  # Attach the SSH security group

  tags = {
    Name = "MyTerraformVM"  # Tag to identify your instance
  }
}

# --------------------------------------------------
# Output block to show the public IP of the EC2 instance
# --------------------------------------------------
output "instance_public_ip" {
  description = "Public IP of the EC2 instance"
  value       = aws_instance.my_ec2.public_ip
}

✅ Save & close (Ctrl + O, Enter, Ctrl + X)


✅ Initialize Terraform

terraform init

✅ Code Formatting Terraform (optional)

terraform fmt

✅ Validate Configuration

terraform validate

✅ Apply the Configuration

terraform apply

It will show you a plan. Type yes to proceed.

terraform-apply


✅ Access Your EC2 Instance via SSH from your linxu machine.

 ssh -i my-key.pem ec2-user@<public_ip>

📝 Use ec2-user for Amazon Linux AMI (or ubuntu if you switch to Ubuntu AMI).

ssh to aws aws

✅ Destroy the Instance

terraform destroy

Terraform Handy Commands

These commands are crucial for almost every Terraform workflow.

I. Initialization and Configuration

  1. terraform init

    • Purpose: Initializes a Terraform working directory. This command downloads necessary providers and modules specified in your configuration.
    • When to use: Always the first command you run in a new or cloned Terraform directory, or when you add/change provider/module configurations.
    • Example: terraform init
  2. terraform validate

    • Purpose: Checks the syntax and configuration of your Terraform files (.tf) for correctness and internal consistency. It does not check against the actual cloud provider.
    • When to use: Before terraform plan or terraform apply to catch errors early.
    • Example: terraform validate

II. Planning and Applying Changes

  1. terraform plan

    • Purpose: Generates an execution plan. It shows you exactly what actions Terraform will take (create, modify, destroy) to reach the desired state defined in your configuration, without actually performing them.
    • When to use: Before terraform apply to review the proposed changes and ensure they are what you expect.
    • Example: terraform plan
    • Save Plan for Apply: terraform plan -out=myplan.tfplan (saves the plan to a file)
  2. terraform apply

    • Purpose: Executes the actions proposed in a Terraform plan to create, update, or destroy infrastructure. This is the command that makes changes to your cloud environment.
    • When to use: After terraform plan and you are satisfied with the proposed changes.
    • Example: terraform apply
    • Apply a Saved Plan: terraform apply myplan.tfplan (applies a plan saved with -out)
    • Auto-approve (for CI/CD or experienced users): terraform apply -auto-approve (bypasses the confirmation prompt)

III. State Management and Inspection

  1. terraform show

    • Purpose: Reads the current state file and outputs the managed infrastructure’s configuration in a human-readable format.
    • When to use: To inspect the current state of your deployed resources.
    • Example: terraform show
    • Show a saved plan: terraform show myplan.tfplan
  2. terraform state list

    • Purpose: Lists all resources managed by the current Terraform state.
    • When to use: To get an overview of what Terraform is currently managing.
    • Example: terraform state list
  3. terraform state show [resource_address]

    • Purpose: Displays the attributes of a specific resource within the Terraform state.
    • When to use: To get detailed information about a single resource.
    • Example: terraform state show aws_instance.my_server (replace aws_instance.my_server with your resource name)
  4. terraform output [output_name]

    • Purpose: Displays the value(s) of output variables defined in your Terraform configuration.
    • When to use: To easily retrieve specific information (like an IP address, DNS name, ARN) from your deployed infrastructure.
    • Example: terraform output instance_public_ip (to get a specific output)
    • All outputs: terraform output (to list all outputs)

IV. Destruction

  1. terraform destroy
    • Purpose: Destroys all resources managed by the current Terraform configuration. Use with extreme caution!
    • When to use: When you no longer need the infrastructure and want to tear it down completely.
    • Example: terraform destroy
    • Auto-approve: terraform destroy -auto-approve (bypasses the confirmation prompt)

V. Workspace Management (Advanced)

  1. terraform workspace list

    • Purpose: Lists available workspaces. Workspaces allow you to manage multiple distinct environments (e.g., dev, staging, prod) using the same Terraform configuration.
    • Example: terraform workspace list
  2. terraform workspace new [workspace_name]

    • Purpose: Creates a new workspace.
    • Example: terraform workspace new production
  3. terraform workspace select [workspace_name]

    • Purpose: Switches to an existing workspace.
    • Example: terraform workspace select staging

General Workflow Tip:

  1. terraform init
  2. terraform validate
  3. terraform plan
  4. terraform apply
  5. terraform output (to get useful info)
  6. terraform destroy (when done)

These commands form the backbone of most Terraform operations and will cover the vast majority of your use cases! You’re looking for a good set of “handy” Terraform commands! Here’s a breakdown of the most commonly used and useful commands, categorized for easier understanding:

1. Core Workflow Commands (The Essentials):

2. State Management Commands (Critical for Operations):

3. Utility and Helper Commands:

General Tips for Using Commands:

This list covers the most frequently used and crucial Terraform commands to manage your infrastructure effectively.


📖 References & Further Reading

  1. Terraform Plans, Modules, and Remote State – by Wahl Network A great explanation of how Terraform handles infrastructure planning, modularization, and remote state management. 🔗 https://wahlnetwork.com/2020/04/29/terraform-plans-modules-and-remote-state/

  2. Terraform AWS Provider Documentation – Official Registry The complete reference for all AWS resources supported in Terraform, including syntax, arguments, and examples. 🔗 https://registry.terraform.io/providers/hashicorp/aws/latest



Suggest Changes

Previous Post
Terraform - Complete step-by-step process to create a (VM) on Azure and SSH under student pack subscription.
Next Post
Docker, Kubernetes, and OpenShift Cheat sheets