Introduction to Terraform with AWS

Introduction to Terraform with AWS

Terraform ဟာအခုနောက်ပိုင်းရေပန်းစားပြီးအသုံးများလာတဲ့ IAC (Infrastructure as Code) tool တစ်ခုဖြစ်ပါတယ်။ သူကဘာလုပ်လဲဆို ကျွန်တော်တို့ ပုံမှန် provision လုပ်နေကျ cloud/on-prem resource တွေကို template ရေးပြီး apply ဆိုတာနဲ့ တန်း setup လုပ်ပေးတာပါ။ infrastructure တွေကို manual provision မလုပ်ဘဲ template(code) ရေးပြီးလုပ်လို့ရတော့ အဲ့ဒီ infrastructure file တွေကို versioning လုပ်လို့ရသလို အလားတူ infra မျိုးပြန် setup တာဖြစ်ဖြစ်၊ share သုံးတာဖြစ်ဖြစ် လုပ်လို့ရတော့ workflow ဟာပိုစနစ်ကျပြီး တစ်ခါအချိန်ပေးရုံနဲ့နောက်ပိုင်းအချိန်ကုန်သက်သာတာပေါ့။ ဒီ blog ကတော့ terraform သုံးပြီး AWS မှာဘယ်လို setup လုပ်လို့ရလဲဆိုတာကို မိတ်ဆက်ပေးသွားမှာဖြစ်ပါတယ်။

Terraform ဟာဒီလို resource တွေအသစ်လုပ်တာ၊ ရှိပြီးသား resource တွေကိုပြုပြင်ပြောင်းလဲတာတွေကို provider တွေမှတစ်ဆင့်လုပ်ဆောင်ပါတယ်။ provider ဆိုတာကတော့ terraform နဲ့ service တစ်ခုရဲ့ API ကြားချိတ်ဆက်ပေးတဲ့ plugin လို့သတ်မှတ်လို့ရပါတယ်။

Terraform workflow တစ်ခုရဲ့ fundamental အပိုင်းသုံးပိုင်းကိုအောက်ပါပုံမှာကြည့်လို့ရပါတယ်။

Terraform basic concept ကတော့ဒီလောက်ပါပဲ။ ကျန်တဲ့ concept တွေကိုတော့တစ်ခါတည်း aws နဲ့ setup လုပ်ရင်းမှတစ်ခုစီကြည့်သွားကြရအောင်။ အခုကစပြီးလုပ်မယ့် setup ကိုစမ်းချင်ရင်စမ်းလို့ရအောင်နောက်ဆုံးမှာ GitHub link share ပေးထားမှာပါ။

တစ်ခုပြောချင်တာကတော့ AWS ရဲ့ VPC, subnet, gateways, route tables စတာတွေကိုနားလည်ထားရင်ပိုကောင်းပါတယ်။ သိပ်မသိသေးရင် ဒီလင့်ခ် မှာဖတ်ကြည့်လို့ရပါတယ်။ လိုက်လုပ်မယ်ဆိုရင်တော့ terraform install ထားဖို့လိုပါမယ်။ AWS account တစ်ခုလည်းလိုပြီး IAM ကနေ Access Key ကိုထုတ်ပြီး setup လုပ်ထားဖို့လည်းလိုပါမယ်။​

Access Key Permissions

.bashrc

export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=

ကျွန်တော်ကတော့ ubuntu 22 t2.micro server မှာ install & setup လုပ်ပြီးစမ်းထားတာဖြစ်ပါတယ်။ စမ်းတာမို့လို့ VPC & EC2 full access ပေးထားတာဖြစ်ပြီးစမ်းပြီးတာနဲ့ access key revoke or IAM user ကိုပြန် remove ပေးဖို့မမေ့ပါနဲ့။

General Architecture

ကျွန်တော်တို့ setup လုပ်မယ့် system ရဲ့ architecture ကတော့ single region VPC နဲ့ single AZ မှာ public နဲ့ private subnet နှစ်ခုခွဲပြီး EC2 instance တစ်ခုကို public (front facing web app) နဲ့ ကျန်တစ်ခုကို private (private DB server) ပုံစံ setup လုပ်သွားမှာဖြစ်ပါတယ်။

Directory Structure

ဒါကတော့ directory structure ပါ။ ထွေထွေထူးထူးတော့မရှိပါဘူး။ version.tf ကနေစကြည့်ရအောင်။

version.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

ဒီ file မှာကတော့ terraform နဲ့သုံးမယ့် provider ရဲ့ version ကိုသတ်မှတ်ပေးထားပါ။ ကျွန်တော်ကတော့ AWS သုံးမှာမို့လို့ AWS provider ကို specify ထားပါတယ်။ AWS block ထဲက version ကတော့ AWS provider ရဲ့ version ဖြစ်ပြီး အပြင်က version ကတော့ run မယ့် terraform ရဲ့ version ပါ။ ဒီနေရာမှာ azure တို့ GCP တို့သုံးမယ်ဆိုရင်တော့ဒီမှာလာပြောင်းပေးရမှာပါ။ ပြောင်းရင်တော့အောက်က resource တွေလည်းလိုက်ပြောင်းရမှာပေါ့။

provider.tf

provider "aws" {
  region = var.region
}

ဒီ provider.tf file မှာတော့ ကျွန်တော်အသုံးပြုမယ့် provider (AWS) နဲ့ region ပဲထည့်ထားပါတယ်။ တကယ်ဆို အပေါ်က version.tf file နဲ့တူတူထားလို့ရပါတယ်။ ကျွန်တော်ကတော့တခြား provider specific settings တွေသတ်မှတ်ရင်မရောသွားအောင်သတ်သတ်ခွဲထားတာပါ။ ဒီမှာသတိထားစရာရှိတာက region ကိုသတ်မှတ်ရာမှာ var.region ဆိုပြီးသုံးထားပါတယ်။ အဲ့ဒီ var ဘယ်ကလာလဲက အောက်က vars.tf file မှာဆက်ကြည့်ကြရအောင်။

vars.tf

variable "region" {
  type    = string
  default = "ap-south-1"
}

variable "vpc_cidr" {
  type    = string
  default = "10.0.0.0/16"
}

variable "pub_sub_cidr" {
  type    = string
  default = "10.0.0.0/24"
}

variable "pri_sub_cidr" {
  type    = string
  default = "10.0.1.0/24"
}

variable "a_zone" {
  type    = string
  default = "ap-south-1b"
}

variable "ami_id" {
  type    = string
  default = "ami-0912cd2fb490de15d"
}

variable "instance_type" {
  type    = string
  default = "t2.micro"
}

variable "foo_pub_key" {
  type    = string
  default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID/Q89jqJkQSLE4C2Fsa663vHvRAWrilDJ6L7eJVPngk thuhtetaung.d2@gmail.com"
}

programming language တွေလိုပဲ terraform မှာလဲ variable သတ်မှတ်ပေးလို့ရပါတယ်။ terraform မှာ variable က input, output နဲ့ local ဆိုပြီးသုံးမျိုးရှိပါတယ်။ input variable ဆိုတာတော့ အပေါ်မှာ define ထားတဲ့ပုံစံမျိုးကိုခေါ်တာပါ။ ကျွန်တော်ပြောင်းနိုင်လောက်တဲ့ settings တွေကို variable အနေနဲ့သတ်မှတ်ထားတာပါ။ ဒီမှာတစ်ခုရှိတာ variable block ထဲက default ဆိုတဲ့ term ပါ။ value လို့မသုံးပဲဘာလို့ default ဆိုပြီးသုံးလဲပေါ့။ အကြောင်းကတော့ module သုံး or module ပုံစံရေးတဲ့အခါ module ထဲကို variable ထည့်ပေးလို့ရပါတယ်။ module ကိုလှမ်းသုံးတဲ့အခါ value မထည့်ပေးလိုက်ရင် default value ဘာသုံးရမလဲဆိုတာကိုရေးထားတဲ့သဘောပါ။ programming language တွေမှာ function တစ်ခုခေါ်သလိုပါပဲ၊ function argument မထည့်ပေးလိုက်ရင် default ဘာသုံးမလဲဆိုတာ define လိုက်သလို‌‌ပေါ့။ output variable ကတော့‌အောက်မှာသုံးထားပြီး local variable ကတော့ မသုံးထားပါဘူး။ သူ (local variable) ကတော့ input variable ကိုမှ local scope မှာပဲရှိတဲ့ပုံစံပါ။ function တစ်ခုထဲက temporary variable လိုပေါ့။ terraform module အသုံးပြုပုံအကြောင်းတော့ part 2 မှပဲ ဆက်လက်ပြောပြပေးသွားပါ့မယ်။

vpc.tf

resource "aws_vpc" "foo_vpc" {
  cidr_block = var.vpc_cidr

  tags = {
    Name = "foo_vpc"
  }
}

resource "aws_subnet" "foo_pub_sub" {
  vpc_id            = aws_vpc.foo_vpc.id
  cidr_block        = var.pub_sub_cidr
  availability_zone = var.a_zone

  depends_on = [aws_vpc.foo_vpc]

  tags = {
    Name = "foo_pub_sub"
  }
}

resource "aws_subnet" "foo_pri_sub" {
  vpc_id            = aws_vpc.foo_vpc.id
  cidr_block        = var.pri_sub_cidr
  availability_zone = var.a_zone

  depends_on = [aws_vpc.foo_vpc]

  tags = {
    Name = "foo_pri_sub"
  }
}

ဒီ vpc.tf file မှာတော့ setup လုပ်မယ့် VPC တစ်ခု၊ public subnet ‌တစ်ခုနဲ့ private subnet တစ်ခုသတ်မှတ်ပေးထားတာပါ။ ဒီမှာ resource block ကိုစသုံးထားပါတယ်။ resource block မှာတော့အသုံးပြုမယ့် provider ရဲ့ resource identifier နဲ့ settings တွေသတ်မှတ်‌ပေးရပါတယ်။ VPC block မှာဆို resource identifier က "aws_vpc" ဖြစ်ပြီး နောက်က "foo_vpc" ကတော့ကျွန်‌တော်တို့သတ်မှတ်တဲ့ resource ရဲ့ name ပါ။ အထဲက CIDR block တွေအတွက်တော့အပေါ်က var ထဲကပြန်ယူထားတာပါ။ subnet မှာလည်း အလားတူပဲ var ထဲကပြန်ယူထားပါတယ်။ subnet သတ်မှတ်ရာမှာ VPC id လိုတဲ့အတွက် အပေါ်က create လိုက်တဲ့ VPC ရဲ့ id ဖြစ်တဲ့ "aws_vpc.foo_vpc.id" နဲ့ပြန် bind ထားပါတယ်။ subnet block ထဲက "depends_on" directive ကတော့ subnet create ရာမှာ VPC id လိုတဲ့အတွက် ထည့်ထားတားပါ။ VPC အရင် create ပြီးမှ subnet ကို create မယ်ဆိုတယ့်သဘောပါပဲ။ terraform က auto infer လုပ်နိုင်ပေမယ့် ကျွန်တော်ကတော့ explicitly ထည့်ထားတာပါ။

gateways.tf

resource "aws_eip" "foo_ngw_eip" {
  vpc = true
}

resource "aws_internet_gateway" "foo_igw" {
  vpc_id = aws_vpc.foo_vpc.id

  depends_on = [aws_vpc.foo_vpc]

  tags = {
    Name = "foo_igw"
  }
}

resource "aws_nat_gateway" "foo_ngw" {
  allocation_id = aws_eip.foo_ngw_eip.id
  subnet_id     = aws_subnet.foo_pub_sub.id

  depends_on = [
    aws_subnet.foo_pub_sub,
    aws_internet_gateway.foo_igw
  ]

  tags = {
    Name = "foo_ngw"
  }
}

ဒီ gateways.tf file မှာတော့ internet gateway နဲ့ NAT gateway ကိုသတ်မှတ်ထားတာပါ။ ကျွန်တော်တို့ VPC ထဲက instance တွေ internet access ရဖို့ internet gateway လိုပြီး private subnet ထဲက DB server instance က internet access ရဖို့တွက် public NAT gateway လိုပါတယ်။ AWS မှာ public NAT gateway create ရင် public IP allocate လုပ်ဖို့လိုတဲ့အတွက် "aws_eip" ဆိုတဲ့ AWS elastic IP resource ကိုအရင် create လုပ်ပေးဖို့လိုပါတယ်။ NAT gateway resource block မှာ eip ရဲ့ id ကိုပြန်ခေါ်သုံးထားပြီး subnet ကိုလည်း ကျွန်တော်တို့ VPC ရဲ့ public subnet နဲ့ပြန် attach ထားပါတယ်။

network_acls.tf

resource "aws_network_acl" "foo_pub_nacl" {
  vpc_id     = aws_vpc.foo_vpc.id
  subnet_ids = [aws_subnet.foo_pub_sub.id]

  ingress {
    protocol   = "all"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  egress {
    protocol   = "all"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  depends_on = [
    aws_vpc.foo_vpc,
    aws_subnet.foo_pub_sub,
  ]

  tags = {
    Name = "foo_pub_nacl"
  }
}

resource "aws_network_acl" "foo_pri_nacl" {
  vpc_id     = aws_vpc.foo_vpc.id
  subnet_ids = [aws_subnet.foo_pri_sub.id]

  ingress {
    protocol   = "all"
    rule_no    = 100
    action     = "allow"
    cidr_block = aws_vpc.foo_vpc.cidr_block
    from_port  = 0
    to_port    = 0
  }

  egress {
    protocol   = "all"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  depends_on = [
    aws_vpc.foo_vpc,
    aws_subnet.foo_pri_sub,
  ]

  tags = {
    Name = "foo_pri_nacl"
  }
}

network ACL ကတော့ subnet level firewall ဖြစ်ပါတယ်။ ingress ကတော့အဝင်ဖြစ်ပြီး egress ကတော့အထွက်ပါ။ rules တွေကိုတော့ public ရော private ရော allow all ပဲပေးထားပါတယ်။ နောက်မှာ security group ထပ်ခံမှာဖြစ်တဲ့အတွက်ဘာမှထပ်မခံထားတာပါ။ private subnet ရဲ့ ingress ကတော့ same VPC ထဲက resource တွေကိုပဲ allow ပေးထားပါတယ်။ ပို secure ချင်ရင်တော့ လိုချင်တဲ့ rules ထပ်ထည့်လို့ရပါတယ်။

route_tables.tf

resource "aws_route_table" "foo_pub_rt" {
  vpc_id = aws_vpc.foo_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.foo_igw.id
  }

  depends_on = [aws_vpc.foo_vpc, aws_internet_gateway.foo_igw]

  tags = {
    Name = "foo_pub_rt"
  }
}

resource "aws_route_table" "foo_pri_rt" {
  vpc_id = aws_vpc.foo_vpc.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.foo_ngw.id
  }

  depends_on = [aws_vpc.foo_vpc, aws_nat_gateway.foo_ngw]

  tags = {
    Name = "foo_pri_rt"
  }
}

resource "aws_route_table_association" "pub" {
  subnet_id      = aws_subnet.foo_pub_sub.id
  route_table_id = aws_route_table.foo_pub_rt.id
}

resource "aws_route_table_association" "pri" {
  subnet_id      = aws_subnet.foo_pri_sub.id
  route_table_id = aws_route_table.foo_pri_rt.id
}

route_tables.tf file မှာတော့ ကျွန်တော်တို့ subnet အတွက် route တွေသတ်မှတ်ပေးထားတာပြီး subnet နဲ့ပြန်တွဲပေးထားတာဖြစ်ပါတယ်။ public subnet ထဲမှာဆို internet gateway ဆီ route ပေးပြီး private ထဲကဆိုရင်တော့ NAT gateway ကိုပြန် route ပေးတဲ့ rules တွေထည့်ထားတာဖြစ်ပါတယ်။

instances.tf

resource "aws_key_pair" "foo_key" {
  key_name   = "foo_key"
  public_key = var.foo_pub_key
}

resource "aws_instance" "foo_pub_ec2" {
  ami                         = var.ami_id
  instance_type               = var.instance_type
  key_name                    = aws_key_pair.foo_key.key_name
  subnet_id                   = aws_subnet.foo_pub_sub.id
  associate_public_ip_address = true

  root_block_device {
    volume_size = 30
    volume_type = "gp2"
  }

  vpc_security_group_ids = [aws_security_group.foo_pub_sg.id]

  depends_on = [
    aws_key_pair.foo_key,
    aws_subnet.foo_pub_sub,
    aws_security_group.foo_pub_sg
  ]

  tags = {
    Name = "foo_pub_ec2"
  }
}

resource "aws_instance" "foo_pri_ec2" {
  ami           = var.ami_id
  instance_type = var.instance_type
  key_name      = aws_key_pair.foo_key.key_name
  subnet_id     = aws_subnet.foo_pri_sub.id

  root_block_device {
    volume_size = 30
    volume_type = "gp2"
  }

  vpc_security_group_ids = [aws_security_group.foo_pri_sg.id]

  depends_on = [
    aws_key_pair.foo_key,
    aws_subnet.foo_pri_sub,
    aws_security_group.foo_pri_sg
  ]

  tags = {
    Name = "foo_pri_ec2"
  }
}

instances.tf မှာတော့ server တွေ ssh ဝင်ဖို့ "aws_keypair" ဆိုတဲ့ resource create ထားပြီး "aws_instance" resource block အောက်က "key_name" မှာ ပြန်ချိတ်ထားပါတယ်။ "aws_instance" resource မှာ "ami", "instance_type", "subnet_id", "root_block_device" အကုန်အသေးစိတ်သတ်မှတ်ပေးလို့ရပါတယ်။ ami id မှာကျွန်တော်က mumbai region မှာ setup လုပ်မှာဖြစ်တဲ့အတွက် mumbai region specific ubuntu 22 ami id ကို var file မှာသတ်မှတ်ထားပါတယ်။

security_groups.tf

resource "aws_security_group" "foo_pub_sg" {
  name        = "foo_pub_sg"
  description = "allow http, https and ssh"
  vpc_id      = aws_vpc.foo_vpc.id

  ingress {
    description = "allow http"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "allow https"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "allow ssh"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "all"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  depends_on = [aws_vpc.foo_vpc]

  tags = {
    Name = "foo_pub_sg"
  }
}

resource "aws_security_group" "foo_pri_sg" {
  name        = "foo_pri_sg"
  description = "allow postgres, redis"
  vpc_id      = aws_vpc.foo_vpc.id

  ingress {
    description = "allow ssh"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [aws_vpc.foo_vpc.cidr_block]
  }

  ingress {
    description = "allow redis"
    from_port   = 6379
    to_port     = 6379
    protocol    = "tcp"
    cidr_blocks = [aws_vpc.foo_vpc.cidr_block]
  }

  ingress {
    description = "allow postgres"
    from_port   = 5432
    to_port     = 5432
    protocol    = "tcp"
    cidr_blocks = [aws_vpc.foo_vpc.cidr_block]
  }

  ingress {
    description = "allow icmp"
    from_port   = -1
    to_port     = -1
    protocol    = "icmp"
    cidr_blocks = [aws_vpc.foo_vpc.cidr_block]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "all"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  depends_on = [aws_vpc.foo_vpc]

  tags = {
    Name = "foo_pri_sg"
  }
}

security group မှာတော့ public ec2 instance အတွက် ssh, http and https port တွေကို ingress block တွေနဲ့ သတ်မှတ်ထားပြီး private ec2 instance အတွက်ကတော့ ssh, postgres (port 3306) and redis (port 6379) တွေပဲဖွင့်ထားပါတယ်။ egress အတွက်တော့ allow all ပဲထားထားပါတယ်။

outputs.tf

output "vpc_id" {
  value = aws_vpc.foo_vpc.id
}

output "public_subnet_id" {
  value = aws_subnet.foo_pub_sub.id
}

output "private_subnet_id" {
  value = aws_subnet.foo_pri_sub.id
}

output "public_ec2_address" {
  value = aws_instance.foo_pub_ec2.public_ip
}

output ကိုတော့ကိုယ်လိုချင်တာကို output block နဲ့ပြန်တွဲပြီး output ထုတ်လို့ရပါတယ်။ ကျွန်တော်ကတော့ "vpc_id", "public_subnet_id", "private_subnet_id" and "public_ec2_address" တွေကိုပြန်ထုတ်ထားပါတယ်။

ကျွန်တော်တို့ setup file တွေပြည့်စုံသွားပြီဆိုရင်တော့ terraform cli နဲ့စ run လို့ရပါပြီ။

$ terraform init

"terraform init" run လိုက်ပြီဆိုရင်တော့ current directory မှာလိုအပ်တယ့် module တွေ initialize လုပ်လိုက်တာပါ။

terraform plan

"terraform plan" run လိုက်ရင်တော့ terraform က execution plan ထုတ်ပြီးဘယ် resource တွေကို create/modify လုပ်မလဲဆိုတာ output ထုတ်ပေးတာပါ။ တကယ်တမ်းနောက်မှာက state file ကနေသွားဖတ်ပြီးဘာတွေ create/modify လုပ်မယ်ဆိုတာသိတာဖြစ်ပါတယ်။ state file ဆိုတာကတော့လက်ရှိ deploy လုပ်ထားတဲ့ resource တွေရဲ့ state တွေကို plain text နဲ့ save ထားတာပါ။ အဲ့တာကြောင့် terraform files တွေကို version control လုပ်တဲ့အခါ state file တွေပါမသွားဖို့အလွန်အရေးကြီးပါတယ်။ RDS လိုမျိုး service ပါရင် credential တွေပါ ပါလာတက်လို့ပါ။ ကျွန်တော်ဆိုလည်း .gitignore မှာ state file တွေကို ignore ထားပါတယ်။ အခုကစမ်းတာမို့လို့ကိစ္စမရှိပေမယ့်တကယ် production မှာသုံးမယ်ဆိုရင်တော့ remote state နဲ့သုံးသင့်ပါတယ်။ remote state နဲ့ setup ကတော့ part 2 မှာမှဆက်ပြောသွားမှာဖြစ်ပါတယ်။

terraform apply

"terraform apply" ကို run လိုက်ရင်တကယ် provision လုပ်တော့မှာမို့ထွက်လာတယ့် output ကိုသေချာစစ်ဆေးပြီးမှ "yes" သင့်ပါတယ်။ "yes" ပြီးရင်တော့ terraform က ကျွန်တော်တို့ infrastructure ကို auto provision လုပ်ပေးသွားမှာဖြစ်ပါတယ်။

တစ်ခုရှိတာကအခု terraform setup မှာက infra level ပဲပါပါတယ်။ software installation တွေမပါသေးပါဘူး။​ (ဥပမာ - web app runtime ဆိုလည်း node.js, database runtime ဆိုလည်း postgres/redis စတာတွေမပါသေးပါဘူး။)​ အဲ့လို software တွေ install မယ်ဆို ansible သုံးတာဖြစ်ဖြစ်၊ အပေါ်က instances.tf က ec2 resource ​block မှာ user data define ပြီးဖြစ်ဖြစ်၊​ ssh နဲ့ manual install ပြီးဖြစ်ဖြစ်လုပ်လို့ရပါတယ်။ ssh နဲ့ manual install မယ်ဆိုရင်တော့ private subnet ထဲက ec2 instance ကို ssh proxy နဲ့ဝင်မှရပါမယ်။

ssh proxy config

Host terraform-pub-svr
    Hostname <public ip>
    User <user>
    IdentityFile <path to private key>
Host terraform-pri-svr
    Hostname <private ip>
    User <user>
    IdentityFile <path to private key>
    ProxyCommand ssh -W %h:%p terraform-pub-svr

အခု infra setup မှာက cost မကျအောင် instance ဆိုလည်း t2.micro တွေသုံးထားပေမယ့် မလိုအပ်ပဲ cost မကျအောင်စမ်းပြီးရင်တော့ပြန်ဖျက်တာကောင်းပါတယ်။​ terraform နဲ့ဆိုရင်ပြန်ဖျက်တာလည်းလွယ်ပါတယ်။

terraform destroy

အပေါ်က command run ပြီး confirm လိုက်တာနဲ့ terraform က ရှိသမျှ resource တွေအကုန်တစ်ခုမကျန်ဖျက်ပေးသွားမှာဖြစ်ပါတယ်။

ဒီ part မှာတော့ Terraform ကိုအသုံးပြုပြီး AWS မှာ infrastructure တစ်ခုဘယ်လို setup လုပ်လို့ရလဲဆိုတာကိုမိတ်ဆက်ပေးသွားတာဖြစ်ပါတယ်။ code ကိုတော့ GitHub link မှာကြည့်နိုင်ပါတယ်။ နောက် part မှာတော့ AWS မှာ Terraform ရဲ့ module နဲ့ remote state အသုံးပြုပုံကိုပြောပြသွားမှာဖြစ်လို့စိတ်ဝင်စားရင်ဆက်လက်ဖတ်ရှုလို့ရပါတယ်။ အဆုံးထိဖတ်ရှုပေးလို့ကျေးဇူးတင်ပါတယ်ဗျာ။