Melakukan Deployment EC2 Menggunakan Terraform

Saya akan coba membuat guidance untuk deployment EC2 menggunakan Terraform. Sebelumnya, yang perlu dipersiapkan :

  1. AWS Credentials
  2. AWS Keypair, untuk keypair ini bisa menggunakan script Terraform. Simpan dengan nama key-pair.tf, dan buat code-nya sebagai berikut :
# Membuat secure private key dan encode menjadi PEM
resource "tls_private_key" "key_pair" {
  algorithm = "RSA"
  rsa_bits  = 4096
} # Membuat keypair
resource "aws_key_pair" "key_pair" {
  key_name   = "ec2-key-pair"  
  public_key = tls_private_key.key_pair.public_key_openssh
} # Save file-nya ke local
resource "local_file" "ssh_key" {
  filename = "${aws_key_pair.key_pair.key_name}.pem"
  content  = tls_private_key.key_pair.private_key_pem
}

Next yang kita lakukan adalah membuat file Terraform untuk authentifikasi AWS. Untuk itu, kita buat file dengan nama provider-variables.tf, kemudian kita isi code sebagai berikut:

#Variable yang dibuat : aws access key, region dan secret key
variable "aws_access_key" {
  type = string
  description = "AWS access key"
}

variable "aws_secret_key" {
  type = string
  description = "AWS secret key"
}

variable "aws_region" {
  type = string
  description = "AWS region"
}
Setelah itu kita buat terraform.tfvars dan tambahkan script dibawah. Tapi perlu diingat, apabila terraform code ini dimasukkan ke repo public, agar file ini dimasukkan ke ignore list.
aws_access_key = "diisi access key aws"
aws_secret_key = "diisi secret key aws"
aws_region     = "ap-southeast-3" #region jakarta
Kalau sudah, kita buat provider.tf yang kita isi code sebagai berikut:
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}
provider "aws" {
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
  region     = var.aws_region
}
Setelah selesai, jalankan command ini di folder terraform tadi :
terraform init #ini untuk menginisiasi terraform provider terraform plan #ini untuk mengecek resource apa saja yang kena impact terraform apply #ini akan mendeploy terraform ini, dan membuat resource di AWS atau membuat keypair yang akan disimpan di dalam folder terraform ini dengan nama file ec2-key-pair.pem. Jangan lupa ketik yes dan enter kalo muncul prompt

OK, part 1 selesai, membuat akses ke AWS. Selanjutnya kita akan membuat network yang akan digunakan oleh EC2 kita. Pertama kita buat variable network dengan membuat file dengan nama network-variable.tf, yang kita isi dengan code sebagai berikut :

# AWS AZ
variable "aws_az" {
  default     = "ap-southeast-3a"
}

# VPC Variables
variable "vpc_cidr" {
  default     = "10.1.64.0/18"
}

# Subnet Variables
variable "public_subnet_cidr" {
  default     = "10.1.64.0/24"
}

Habis itu, kita buat network.tf, yang diisi dengan code sebagai berikut :

# Membuat VPC
resource "aws_vpc" "vpc" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  tags = {
    Name = "linux-vpc"
  }
}

# Define public subnet
resource "aws_subnet" "public-subnet" {
  vpc_id            = aws_vpc.vpc.id
  cidr_block        = var.public_subnet_cidr
  availability_zone = var.aws_az
  tags = {
    Name = "linux-subnet"
  }
}

# Define internet gateway
resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name = "linux-igw"
  }
}

# Define public route table
resource "aws_route_table" "public-rt" {
  vpc_id = aws_vpc.vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.gw.id
  }
  tags = {
    Name = "linux-rt"
  }
}

# Assign public route table ke public subnet
resource "aws_route_table_association" "public-rt-association" {
  subnet_id      = aws_subnet.public-subnet.id
  route_table_id = aws_route_table.public-rt.id
}

Untuk OS-nya kita akan buat Ubuntu, dan akan kita buat file ubuntu-verion.tf, bisa dipakai untuk beberapa versi Ubuntu.

# Get latest Ubuntu Linux Focal Fossa 20.04 AMI
data "aws_ami" "ubuntu-linux-2004" {
  most_recent = true
  owners      = ["099720109477"] # Canonical
  
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
  
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

# Get latest Ubuntu Linux Jammy 22.04 AMI
data "aws_ami" "ubuntu-linux-2204" {
  most_recent = true
  owners      = ["099720109477"] # Canonical
  
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }
  
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

Untuk variable Ubuntu-nya, kita akan membuat file linux-variable.tf sebagaimana terlampir

variable "linux_instance_type" {
  type        = string
  description = "EC2 instance untuk Server Linux"
  default     = "t3.micro"
}
variable "linux_associate_public_ip_address" {
  type        = bool
  description = "Associate public IP address ke EC2 instance"
  default     = true
}
variable "linux_root_volume_size" {
  type        = number
  default = 8
}
variable "linux_data_volume_size" {
  type        = number
  default = 10
}
variable "linux_root_volume_type" {
  type        = string
  default     = "gp2"
}
variable "linux_data_volume_type" {
  type        = string
  default     = "gp2"
}

Nah, sekarang kita bisa buat ec2-main.tf. Alias code untuk membuat EC2 Instance plus parameter penyokongnya seperti security group, ami dan juga elastic IP-nya biar si EC2 ini bisa diakses dari public.

# Membuat security group untuk EC2
resource "aws_security_group" "aws-linux-sg" {
  name        = "linux-sg"
  description = "Allow incoming traffic ke EC2 Instance"
  vpc_id      = aws_vpc.vpc.id  
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow incoming koneksi HTTP "
  }  
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow incoming koneksi SSH"
  }  
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
# Membuat EC2 Instance
resource "aws_instance" "linux-server" {
  ami                         = data.aws_ami.ubuntu-linux-2004.id #kita menggunakan versi 20
  instance_type               = var.linux_instance_type
  subnet_id                   = aws_subnet.public-subnet.id
  vpc_security_group_ids      = [aws_security_group.aws-linux-sg.id]
  associate_public_ip_address = var.linux_associate_public_ip_address
  source_dest_check           = false
  key_name                    = aws_key_pair.key_pair.key_name
  user_data                   = file("user-data.sh") #ini opsional
  
  # root disk
  root_block_device {
    volume_size           = var.linux_root_volume_size
    volume_type           = var.linux_root_volume_type
    delete_on_termination = true
    encrypted             = true
  }
  # extra disk
  ebs_block_device {
    device_name           = "/dev/xvda"
    volume_size           = var.linux_data_volume_size
    volume_type           = var.linux_data_volume_type
    encrypted             = true
    delete_on_termination = true
  }
  
  tags = {
    Name = "linux-vm"
  }
}

# Membuat Elastic IP untuk EC2
resource "aws_eip" "linux-eip" {
  vpc  = true
  tags = {
    Name = "linux-eip"
  }
}

# Associate Elastic IP ke EC2
resource "aws_eip_association" "linux-eip-association" {
  instance_id   = aws_instance.linux-server.id
  allocation_id = aws_eip.linux-eip.id
}

Untuk user-data.sh, digunakan agar pada saat melakukan testing akses ec2 ini bisa langsung dibuka via webservice. Step ini opsional. Scriptnya bisa menggunakan ini :

#! /bin/bash
sudo apt-get update
sudo apt-get install -y apache2
sudo systemctl start apache2
sudo systemctl enable apache2
echo "<h1>Test Apache Webservice</h1>" | sudo tee /var/www/html/index.html

Kalau sudah, jalankan command sbb:

terraform plan
terraform apply
#jangan lupa ketik yes dan enter lagi kalo muncul prompt

Gitu aja sih. Kalo ada pertanyaan, feel free buat comment aja. Untuk repo git, bisa langsung comot disini.

Leave a Reply

Your email address will not be published. Required fields are marked *