Skip to content

DevOps Day 96: Create EC2 Instance Using Terraform

This document outlines the solution for DevOps Day 96. The objective was to provision an AWS EC2 instance using Terraform, including generating an SSH key pair and attaching it to the instance for secure access.

Table of Contents

  1. Task Overview
  2. Step-by-Step Solution
  3. Deep Dive: Terraform Concepts Used
  4. Troubleshooting

Task Overview

Objective: Provision an AWS EC2 instance named datacenter-ec2 with a specific AMI and instance type, secured by a new SSH key pair.

Requirements: 1. Directory: /home/bob/terraform 2. File: main.tf 3. Key Pair: Create a new RSA key named datacenter-kp. 4. EC2 Instance: * AMI: ami-0c101f26f147fa7fd * Type: t2.micro * Name Tag: datacenter-ec2 * Security Group: Attach the default security group.


Step-by-Step Solution

1. Create main.tf

We define the necessary resources: a cryptographic key, an AWS key pair resource to upload that key, a data source to find the security group, and finally the instance itself.

Command:

cd /home/bob/terraform
vi main.tf

Content:

# 1. Generate a secure private key locally
resource "tls_private_key" "my_key" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

# 2. Create an AWS Key Pair using the public key from the resource above
resource "aws_key_pair" "deployer" {
  key_name   = "datacenter-kp"
  public_key = tls_private_key.my_key.public_key_openssh
}

# 3. Find the 'default' Security Group ID dynamically
data "aws_security_group" "default_sg" {
  name = "default"
}

# 4. Create the EC2 Instance
resource "aws_instance" "web" {
  ami           = "ami-0c101f26f147fa7fd"
  instance_type = "t2.micro"
  key_name      = aws_key_pair.deployer.key_name

  # Attach the security group found in step 3
  vpc_security_group_ids = [data.aws_security_group.default_sg.id]

  tags = {
    Name = "datacenter-ec2"
  }
}

2. Initialize and Apply

Run the standard Terraform workflow.

  1. Initialize: Downloads the AWS and TLS provider plugins.
    terraform init
    
  2. Plan: Previews the creation of the key, key pair, and instance.
    terraform plan
    
  3. Apply: Deploys the resources.
    terraform apply -auto-approve
    

3. Verification

Verify that Terraform is tracking the resources.

terraform state list
# Expected Output:
# data.aws_security_group.default_sg
# aws_instance.web
# aws_key_pair.deployer
# tls_private_key.my_key


Deep Dive: Terraform Concepts Used

TLS Private Key & AWS Key Pair

This is a powerful pattern for managing access. * tls_private_key: Generates the raw cryptographic material (the private and public key data) within Terraform's memory. * aws_key_pair: Takes the public key part (public_key_openssh) and uploads it to AWS console so it can be injected into EC2 instances. * Security Note: The private key exists in your terraform.tfstate file. In production, treat your state file as a sensitive secret!

EC2 Instance Resource

* aws_instance: The fundamental resource for creating virtual machines. * key_name: Links the instance to the Key Pair we created, allowing SSH access. * vpc_security_group_ids: Controls network access. We used a list [] because an instance can have multiple security groups.

Data Sources (Security Groups)

* data "aws_security_group": Instead of hardcoding a Security Group ID (like sg-12345), which changes per account/region, we tell Terraform to "Find the group named 'default'". This makes the code portable across different AWS accounts.


Troubleshooting

Issue: "AMI not found" * Cause: The AMI ID ami-0c101f26f147fa7fd is specific to a region (likely us-east-1). If your provider is configured for a different region (e.g., us-west-2), this AMI ID will not exist there. * Fix: Ensure your provider "aws" block or environment variables specify region = "us-east-1".

Issue: "InvalidKey.Format" * Cause: If you try to paste a pre-generated key incorrectly into the public_key field. * Fix: Using tls_private_key resource (as done in the solution) avoids format errors because Terraform handles the string generation automatically.