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.