[Terraform] AWS – EC2 Instance

You can see the power of Terraform when you provision infrastructure in the cloud environment. In this post, we will create an EC2 instance via Terraform step by step.

We are going to configure

  • Security Group: allows HTTP and SSH inbound traffic
  • New EC 2 Instance
    • Install Apache HTTP Server (“httpd“) via “User Data”

Prerequisites

  • Install Terraform CLI
  • Install AWS CLI
  • Setup the AWS Sandbox
  • Configure AWS CLI with the credential

[Note] Let’s use the Windows machine for the examples in this post.
[Note] To install Terraform on Windows, you need to install chocolatey first.
https://chocolatey.org/install

choco --version

choco install terraform

terraform --version

aws --version

aws configure

Prepare the Environment

  • Make sure you have a default VPC
  • Create a key pair in the EC2 Dashboard
  • Create a working directory such as C:\Apps\Terraform\AWS-demo

Define Input and Output Variables

  • Create a variable definition file: variables.tf
    • 3 Inputs and 2 Outputs
variable "my_instance" {  
  type        = object({
    ami           = string
    instance_type = string    
    tagname       = string
  })  
  description = "My EC2 instance"
}

variable "vpc" {
  type        = object({
    vpc_id    = string
    subnet_id = string
    key_name  = string
  })
}
 
variable "region" { 
  type        = string
  description = "AWS Region"
}

output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.my_instance.id
}

output "instance_public_ip" {
  description = "Public IP address of the EC2 instance"
  value       = aws_instance.my_instance.public_ip
}

Create Terraform Configuration

  • Create a main configuration file: main.tf
    • Security Group for SSH and HTTP
    • Install Apache HTTP Server (“httpd“)
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}
 
provider "aws" {
  region  = var.region
}

resource "aws_security_group" "allow_ssh_http" {
  name        = "allow_ssh_http"
  description = "Allow SSH and HTTP inbound traffic"
  vpc_id      = var.vpc.vpc_id

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

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

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

  tags = {
    Name = "allow_ssh_http"
  }
}

resource "aws_instance" "my_instance" {
  ami           = var.my_instance.ami
  instance_type = var.my_instance.instance_type
  subnet_id     = var.vpc.subnet_id
  key_name      = var.vpc.key_name
  associate_public_ip_address = true
  security_groups = [aws_security_group.allow_ssh_http.id]

  user_data = <<EOF
#!/bin/bash
sudo yum -y install httpd && sudo systemctl start httpd

echo '<h1>Hello World From Terraform!</h1>' > index.html

sudo mv index.html /var/www/html/
EOF

  tags = {
    Name = var.my_instance.tagname
  }
}

Set Input Values

  • Create a variable value file: variables.tfvars
  • Replace the vpc_id and subnet_id
my_instance    = {
  ami           = "ami-0b0dcb5067f052a63"
  instance_type = "t2.micro"
  tagname       = "my-tf-ec2-instance"
}

vpc = {
  vpc_id    = "vpc-06ffeaae395dcc428"
  subnet_id = "subnet-061c855404b8b01eb" 
  key_name  = "aws"
}

region = "us-east-1"

Run the terraform and Check the Output

terraform init
terraform validate

terraform plan -var-file="variables.tfvars"

terraform apply -var-file="variables.tfvars"

terraform show

You can check the output at any time even after you run the apply command.

terraform output 

Copy the public IP output, and paste it as http://{public_id} in the browser.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s