Teamwork with Terraform

Terraform သည် ရှေ့ Terraform First Step တွင် ပြောခဲ့သည့်အတိုင်း HCL language အသုံးပြု၍ code များရေးကာ infrastructure ကို provision ပြုလုပ်ပေးနိုင်သော Tools တစ်ခု ဖြစ်ပါတယ်။ ဒါပေမဲ့ VM သုံးလေးလုံး တည်ဆောက်ရုံနဲ့တော့ IAC(infrastructure as code) လို့ သတ်မှတ်လို့မရပါဘူး။ Software တွေ၊ applications တွေကို development ပြုလုပ်တဲ့အခါ အမြဲတမ်း အဆုံးမရှိ လိုအပ်ချက်များအပေါ် feature အသစ်များ ထည့်သွင်းခြင်း၊ မလိုအပ်သည့် feature များကို ပြန်ဖြုတ်ခြင်း၊ ပိုမိုကောင်းမွန်အောင် ပြုပြင်ပြောင်းလဲခြင်း၊ Bug Fix စတာတွေကို developer များ၊ QA များ အစုလိုက် အဖွဲ့လိုက် team အနေနဲ့ version control system များ အသုံးပြုကာ develop ပြုလုပ်ကြပါတယ်။ အဲ့လို Software များ၊ product များကို ပြုလုပ်သလိုမျိုး infrastructure တစ်ခုလုံးကို လိုအပ်ချက် အပေါ်မူတည်ပြီး အဆုံးမရှိ လိုအပ်ရင် လိုအပ်သလို administrator များ၊ ops များက team အလိုက် versioning ပြုလုပ်ကာ ဖြုတ်တပ် ပြုလုပ်ပြီး infrastructure developing လုပ်တာကို Infrastructure As Code လို့ ခေါ်ဆိုနိုင်ပါတယ်။ ယခုအခါတွင် infrastructure ကို code များဖြင့် developing လုပ်ခြင်းသာမက test case များ ရေးသားပြီး testing များပါ ပြုလုပ်နိုင်ကြပါပြီ။ ဆန္ဒရှိရင် infrastructure code များကို automated testing များပါ ပြုလုပ်နိုင်ပါတယ်။ infrastructure test ပြုလုပ်တာကတော့ ကောင်းမွန်တဲ့ အလေ့အထ ဖြစ်ပြီး အမှားအယွင်းနည်းပါးစေပါတယ်။ နောက်ပိုင်းတွင် သီးသန့် topic အနေနဲ့ ထပ်ရေးပေးပါ့မယ်။

အခု တကယ် ပြောချင်တာကတော့ Organizations အကြီးကြီးတွေမှာ ဖြစ်စေ၊ infrastructure အကြီးကြီးတွေမှာ ဖြစ်စေ terraform အသုံးပြုပြီးတော့ ကိုယ့် အလုပ်ထဲမှာရှိတဲ့ coworker တွေ၊ colleagues တွေနဲ့ ဒါမှမဟုတ် team အနေနဲ့ ဝိုင်းပြီးတော့ infrastructure ကို terraform code ရေးပြီးတော့ developing လုပ်မဲ့အကြောင်း ဖြစ်ပါတယ်။ ဒီနေရာမှာ ပုံမှန် terraform ကို အသုံးပြုပြီး infrastructure ကို တည်ဆောက်တဲ့ အခါ local စက်ရဲ့ terraform apply ပြုလုပ်ခဲ့သည့် directory ထဲမှာ state file ကို သိမ်းပါတယ်။ အဲ့လို state file ကို local စက်ထဲမှာ သိမ်းတာက တစ်ဦးတစ်ယောက်ချင်းစီအတွက် အဆင်ပြေပါတယ်။ တကယ်လို့ ကိုယ်တစ်ယောက်ထဲ မဟုတ်တော့ဘဲ team အလိုက် infrastructure ကို develop လုပ်တော့မယ်ဆိုရင် အဆင်ပြေတော့မှာ မဟုတ်ပါဘူး။ နောက်ထပ် team ထဲက develop လုပ်တဲ့သူကို state file ကို share ပေးမှရမှာပါ။ အဲတော့ team ထဲကလူတွေကို version control repo တွေကတဆင့် share ပေးလို့ရနိုင်ပါတယ်။ ဒါပေမဲ့ terraform code တွေကို version control repo တွေမှတဆင့် share ပေးလို့ အဆင်ပြေပေမယ့် state file တွေကို အဲ့လို share သုံးဖို့ကျတော့ ထင်သလောက် အဆင်မပြေပါဘူး။ ဘာလို့လဲဆိုတော့ တကယ်လို့ တစ်ချိန်ထဲမှာ လူနှစ်ယောက် တစ်ပြိုင်နက်ထဲ terrafrom apply လုပ်မိမယ်ဆိုရင် race condition လိုမျိုး မလိုလား အပ်တဲ့ ပြသနာတွေ ရှိလာနိုင်ပါတယ်။ race condition ကြောင့် state file တွေ corrupted ဖြစ်နိုင်ပါတယ်။ file corrupt ဖြစ်သွားရင် ကျွန်တော်တို့ infrastructure ရဲ့ အခြေအနေတွေကို ဆုံးရှုံးလိုက်ရတာပါဘဲ။ ဆက်ပြီးတော့လည်း develop လုပ်ဖို့ မဖြစ်တော့သလို ရှိနေပြီးသား resource တွေကိုလည်း manual တစ်ခုချင်းစီ လိုက်ဖျက်မှဘဲ ရမှာပါ။ အဲတော့ state file ကို ဒီအတိုင်း share သုံးဖို့ဆိုတာ ကောင်းတဲ့ နည်းလမ်းတော့ မဟုတ်ပါဘူး အန္တာရယ် များပါတယ်။

အခုဖြစ်တဲ့ state file ကို share သုံးတဲ့ ပြသနာကို ဖြေရှင်းဖို့ နည်းလမ်း နှစ်ခုကတော့ enhance backend နဲ့ standard backend ကို အသုံးပြုခြင်းပါပဲ။ enhance backend ကတော့ cli operation ကို remote machine မှာ run ပြီး output result ကိုတော့ steam လုပ်ပြီး local machine ကို ပြန်ပို့ပေးပါတယ်။ နောက်ထပ် ထူးခြားတဲ့အချက်ကတော့ variables တွေနဲ့ credentials တွေလို sensitive ဖြစ်တဲ့ ဟာတွေကို remote machine မှာဘဲ store လုပ်ပါတယ်။ အဲဒီ enhance backend ရဲ့ features တွေကိုတော့ Terraform Enterprise Cloud မှာ ရရှိနိုင်ပါတယ်။

Popular ဖြစ်ပြီး လူအသုံးများတာကတော့ standard backend ဖြစ်ပါတယ်။ standard backend ကတော့ state file ကို AWS မှာဆိုရင် remote S3 မှာ backend အနေနဲ့ထားပြီး အသုံးပြုတဲ့ နည်းဖြစ်ပါတယ်။ KMS ကို အသုံးပြုပြီး encrypt လုပ်ကာ S3 မှာ state file ကို သိမ်းပါတယ်။ IAM role နဲ့ policy ကို configure ပြုလုပ်ပြီးတော့ DynamoDB နဲ့ S3 ကို access ပြုလုပ်မှာ ဖြစ်ပါတယ်။ ဒီနေရာမှာ DynamoDB ကို သုံးရတဲ့အကြောင်းအရင်းကတော့ Locking mechanism ပြုလုပ်ပေးဖို့ပါပဲ။ ဒါမှ terraform ကို ဝိုင်းပြီး apply ပြုလုပ်တဲ့အခါ တစ်ယောက် ပြုလုပ်နေတဲ့အချိန် မှာ နောက်တယောက်က state file ကို access မရအောင် lock ချပေးထားမှာ ဖြစ်ပါတယ်။ ဒီ s3backend ကို သုံးဖို့ terraform module ကတော့ အဆင့်သင့် ရေးပြီးသား ရှိပါတယ်။

ဒီ s3backend ကို အသုံးပြုဖို့ inputs သုံးခုနဲ့ output တစ်ခု လိုအပ်ပါတယ်။ inputs သုံးခုကတော့ principal_arn ( principal arn ကတော့ ကျွန်တော်တို့ user ရဲ့ iam arn ဖြစ်ပါတယ် ) ၊ namespace နဲ့ force_destroy_state ( force destroy state ကတော့ မထည့်လည်း ရပါတယ်။ default value true ပါ ) ဖြစ်ပါတယ်။ output ကတော့ config ပါ။ ကျွန်တော်တို့ infra ကို develop လုပ်တဲ့အခါ ကျရင် သုံးရမယ့် backend config ထွက်လာမှာ ဖြစ်ပါတယ်။ ဒါဆို ကျွန်တော်တို့ s3backend ကို တည်ဆောက်ဖို့ terraform code ရေးဖို့ အဆင်သင့်ဖြစ်ပါပြီ။

s3backend.tf
provider "aws" {
  region = "us-east-2"
}

module "s3backend" {
  source        = "DTherHtun/s3backend/aws"
  version       = "0.1.0"
  namespace     = "k8smm"
  principal_arn = "arn:aws:iam::************:user/dtherhtun"
}

output "s3backend_config" {
  value = module.s3backend.config
}

ဒီအပေါ်က terraform code ကို terrraform init နဲ့ လိုအပ်တဲ့ providers နဲ့ modules တွေကို download ဆွဲပေးသွားမှာ ဖြစ်ပါတယ်။ terraform apply လုပ်တာနဲ့ s3 အသုံးပြုထားတဲ့ standard backend ကို provision ပြုလုပ်သွားမှာ ဖြစ်ပါတယ်။

ဒါဆိုရင်တော့ output က ထွက်လာတဲ့ s3backend config တွေကို အသုံးပြုပြီး Team အလိုက် infra ကို develop ပြုလုပ်လို့ရပါပြီ။ backend အနေနဲ့ အသုံးပြုဖို့ team member တစ်ယောက်ချင်းစီ configure အနည်းငယ် ပြုလုပ်ဖို့ လိုအပ်ပါတယ်။

backend.tf
terraform {
  backend "s3" {
    bucket  = "k8smm-t5zowrlr3d8lqtf8vu-state-bucket"
    key     = "k8smm/infra"
    region  = "us-east-2"
    encrypt = true
    role_arn = "arn:aws:iam::344475516279:role/k8smm-t5zowrlr3d8lqtf8vu-tf-assume-role"
    dynamodb_table = "k8smm-t5zowrlr3d8lqtf8vu-state-lock"
  }
  required_version = "~> 0.12"
}

ခုနက output က ထွက်လာတဲ့ ရလဒ်တွေကို အသုံးပြုပြီး terraform backend ကို အပေါ် မှာ ပြထားတဲ့အတိုင်း backend.tf ထဲမှာ configure ပြုလုပ်ရပါမယ်။ configure ပြုလုပ်ပြီးပြီဆိုရင်တော့ team member ကိုယ်တိုင် infra develop လုပ်မယ့် folder အောက်မှာ backend.tf ကို save ပြီး terraform initလုပ်လိုက်ရုံဖြင့် s3 backend ကို setup ပြုလုပ်ပေးသွားမှာ ဖြစ်ပါတယ်။

အခုဆိုရင် infrastructure ကို team နဲ့ စတည်ဆောက်လို့ ရပါပြီ။ တည်ဆောက်မဲ့ infra resource တိုင်းအတွက် ရေးထားတဲ့ terraform code တွေကို ဒီ backend.tf configure လုပ်ထားတဲ့ directory ထဲမှာ run ရမှာ ဖြစ်ပါတယ်။ အရင်ဆုံး EC2 တစ်ခု စမ်းဆောက်ကြည့်ပါမယ်။ အောက်မှာပေးထားတဲ့ terraform code တွေနဲ့ အရင် post က code နဲ့ အတူတူပါပဲ။

main.tf
provider "aws" {
  profile = "default"
  region  = "us-east-2"
}
 
resource "aws_instance" "k8smm" {
  ami           = "ami-0520e698dd500b1d1"
  instance_type = "t2.micro"
  tags = {
    Name = terraform.workspace
  }
}

အပေါ်က terraform code ကိုbackend.tffile ရှိတဲ့ directory ထဲမှာ တချိန်ထဲ တပြိုင်နက်ထဲ run တဲ့အခါ ပထမဆုံး run တဲ့သူတယောက်တည်း အသုံးပြုနိုင်ဖို့ state file ကို lock ပြုလုပ်ပေးထားပါတယ်။ connection မကောင်းလို့ ဖြစ်စေ၊ အကြောင်း အမျိုးမျိုးကြောင့် ဒုတိယ ဖြစ်သွားတဲ့သူကတော့ state file lock ဖြစ်နေတယ်ဆိုပြီး တော့ error တက်မှာ ဖြစ်ပါတယ်။ ဒါဆိုရင်တော့ အပေါ်မှာ ပြောခဲ့တဲ့ infra ကို share ပြီးတော့ develop လုပ်တဲ့အခါ ဖြစ်လာနိုင်တဲ့ race conditions လိုပြသနာမျိုးကို ကြုံရတော့မှာ မဟုတ်ပါဘူး။

နောက်ထပ် team အနေနဲ့ရော Remote backend နဲ့ပါ အသုံးပြုဖို့ အလွန်အသုံးဝင်တဲ့ အရာကတော့ terraform workspace ပါဘဲ။ terraform workspace ကတော့ terraform မှာ built in ပါပြီးသား feature တစ်ခုဖြစ်ပါတယ်။ ကျွန်တော်တို့ infra ကို environment မတူတဲ့အခါ အသုံးပြုဖို့ ဖြစ်ပါတယ်။ ဥပမာ development, qa, staging, production စတဲ့ environment တွေမှာ repetitive တည်ဆောက်ချင်တဲ့ အခါမျိုးမှာ သုံးပါတယ်။ local machine မှာဆိုရင် အဲ့လို repetitive အလုပ်တွေလုပ်ဖို့ state file တွေ ထပ်ခွဲရပါမယ်။ ဒီလို state file တွေခွဲဖို့ directory တွေကိုပါ dev, qa, stag, production ဆိုပြီး ထပ်ခွဲရပါမယ်။ တူညီတဲ့ code တွေကိုပါ ပြန်ထည့်ထားရပါမယ်။ အလုပ်နည်းနည်း ရှုပ်ပါတယ်။ terraform backend နဲ့ workspace တွဲသုံးရင်တော့ ဒီလို အလုပ်ရှုပ်စရာ မလိုတော့ပါဘူး။ တကယ်တော့ ကျွန်တော်တို့က terraform workspace ကို အစကတည်းက သုံးနေပြီးသားပါ။ သုံးလို့ သုံးနေမှန်းသာ သတိမထားမိတာ ဖြစ်ပါတယ်။ terraform workspace list လို့ ရိုက်ထည့်လိုက်ရင် ရှိသမျှ workspace list တွေ ကျလာမှာ ဖြစ်ပါတယ်။ အဲ့ထဲမှာ * နဲ့ ပြထားတဲ့ workspace ကတော့ ကိုယ် အခုလက်ရှိ သုံးနေတဲ့ workspace ဖြစ်ပါတယ်။ လက်ရှိ အမြဲ သုံးလို့သုံးမှန်း သတိမထားမိဘဲ သုံးနေတာကတော့ default workspace ဖြစ်ပါတယ်။

[dther@k8smm k8smm-develop-infra]$ terraform workspace list
* default
[dther@k8smm k8smm-develop-infra]$ terraform workspace new dev
Created and switched to workspace "dev"!

You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
[dther@k8smm k8smm-develop-infra]$ terraform workspace new prod
Created and switched to workspace "prod"!

You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
[dther@k8smm k8smm-develop-infra]$ terraform workspace list
  default
  dev
* prod

workspace အသစ်တစ်ခု တည်ဆောက်ဖို့ terraform workspace new နဲ့ တည်ဆောက်နိုင်ပြီး workspace တစ်ခုနဲ့တစ်ခု ချိန်းဖို့ကိုတော့ terraform workspce select ဆိုပြီး ပြောင်းသုံးနိုင်ပါတယ်။ workspace ကို စမ်းဖို့ terraform code ကို repetitive run လို့ရအောင် အနည်းငယ် ပြန်ပြင်ရပါမယ်။ ကျွန်တော်တို့ environment ၂ခု ခွဲပြီး သုံးပါမယ် ။ env ၂ခု ခွဲ run ဖို့ variables file ၂ခုပြင်ရပါမယ်။ ပထမဆုံး main.tfကို အနည်းငယ် ပြင်ပါမယ်။

main.tf
variable "region" {
  description = "AWS Region"
  type        = string
}
 
provider "aws" {
  profile = "default"
  region  = var.region
}
 
resource "aws_instance" "k8smm" {
  ami           = "ami-0520e698dd500b1d1"
  instance_type = "t2.micro"
  tags = {
    Name = terraform.workspace
  }
}

main.tf file မှာ region အတွက် variable ကို declare လုပ်ခဲ့ပါတယ်။ မတူညီတဲ့ environment အတွက် region ခွဲပြီး ec2 instance ဆောက်လို့ရအောင်လို့ ဖြစ်ပါတယ်။ ဥပမာ dev မှာ region တစ်ခု၊ production အတွက် သက်သက် region တစ်ခု ပုံစံမျိုး အသုံးပြုလို့ရအောင်ပါ။ အဲတော့ env နှစ်ခု အတွက် variable files တွေ ထပ်ရေးရပါမယ်။ variables ဆိုတဲ့ folder အောက်မှာထားပြီး အသုံးပြုပါမယ်။

region = "us-east-2"

ဒါတွေအာလုံး ပြီးရင်တော့ ကျွန်တော်တို့ terrafrom workspace select နဲ့ ပြောင်းပြီး terraform apply -var-file=./variables/.tfvars နဲ့မတူညီတဲ့ environment တွေကို develop ပြုလုပ်နိင်ပါပြီ။ EC2 မှာတော့ workspace name တွေအတိုင်း vm တွေ တည်ဆောက်ပေးသွားမှာ ဖြစ်ပါတယ်။

AWS S3 ကို အဓိကထားပြီး Standard backend ကို သုံးသွားတာ ဖြစ်ပါတယ်။ တစ်ခြား cloud တွေမှာလဲ S3/DynamoDB လိုမျိုး အလားသဏ္ဍာန် ပုံစံတူတာတွေနဲ့ backend ကို အသုံးပြုလို့ ရနိုင်ပါတယ်။ ဒါမှမဟုတ် AWS S3 ကို backend အနေနဲ့သုံးပြီး တခြား cloud အပေါ်မှာလဲ resource provision ပြုလုပ်လို့ ရပါတယ်။ ဒီလိုမျိုး အသုံးပြုချင်းဖြင့် team အနေနဲ့ လုပ်ဆောင်ရတာ ပိုမိုလွယ်ကူ အဆင်ပြေစေပါတယ်။ အမှားအယွင်း နည်းစေပါတယ်။ နောက်တခြားနည်းကတော့ Terraform Enterprise ပါဘဲ။ Terraform Enterprise ကတော့ configure ချရတာ လွယ်ပါတယ်။ သုံးရတာ ပိုမိုက်ပါတယ်။ ပိုက်ဆံ ပိုပေးရပါတယ်။

Terraform Enterprise ကို အသုံးပြုချင်ရင်တော့ ဒီမှာ http://app.terraform.io/ register ပြုလုပ်ရပါတယ်။ Organization တစ်ခု တည်ဆောက်ပြီး token ကို generate ထုတ်ရပါတယ်။ terrafrom Enterprise အတွက် backend configuration ကိုတော့ အောက်မှာ ဖော်ပြပေးသွားပါမယ်။

backend.tf
terraform {
  backend "remote" {
    hostname = "app.terraform.io"
    organization = "k8smm"
    token = "Generate ထုတ်လို့ရတဲ့ token ကို ဒီမှာ ထည့်ပေးရပါမယ်။"
    workspaces {
      name = "k8smm"
    }
  }
}

Standard backend ကို setup လုပ်သလိုမျိုး Terraform Enterprise backend ကို terraform initပြုလုပ်ရုံနဲ့ setup ပြုလုပ်လို့ ရပါတယ်။ Terraform Enterprise ကို အသုံးပြုမယ်ဆိုရင်တော့ variables တွေ credentials တွေကို Terraform Enterprise ထဲမှာ upload ပြီးမှသာ အသုံးပြု၍ရမှာ ဖြစ်ပါတယ်။ ဒါဆိုရင်တော့ Terraform ကို Team တွေ Organization တွေအနေနဲ့ သုံးမယ်ဆိုရင် ဘယ်လိုနည်းလမ်းတွေနဲ့ သုံးမယ်၊ ဘယ်လို backend တွေကို ရွေးချယ်မယ်ဆိုတာ ကိုနားလည် သဘောပေါက်မယ် ထင်ပါတယ်။

Last updated