အနားမသပ်နိုင် သေးတဲ့ Infrastructure as Code (IaC) - အပိုင်း(၄)
ဒီအပိုင်းကို တော်တော်နဲ့ ဆက်မရေးဖြစ်ပဲနဲ့ အခုမှတခါ Ansible နဲ့ Infrastructure as Code (IaC) ကိုဘယ်မျိုးလုပ်ရင်ကောင်းမယ်ဆိုတဲ့ idea တစ်ခုရတာနဲ့ ပြန်ပြီးဆက်ရေးဖြစ်ပြန်တယ်။ စာရေးသူ ပြီးခဲ့တဲ့ နှစ်သစ်မကူးခင်ကာလက ရှိပြီးသား WireGuard VPN server တစ်လုံးကို ဖျက်စီးပြီးတော့ အသစ်ကနေပြန်စပြီး setup လုပ်ဖို့ဖြစ်လာပြန်ပါတယ်။ ပုံမှန်အားဖြင့်... WireGuard VPN server တစ်လုံးတည်ဆောက်ဖို့နဲ့ လိုအပ်တဲ့ peer configuration ထုတ်ဖို့ဆိုတာ မခက်ခဲပေမယ့် လက်ဝင်တယ်၊ အချိန်ကုန်တယ်လို့ စိတ်ထဲမှာထင်လာလို့ automation လုပ်ဖို့အတွက် အနည်းငယ်အားစိုက်ထုတ် ရပါတော့တယ်။ VPS တစ်လုံးကို Linode ပေါ်မှာတည်ဆောက်တာကစလို့ လိုအပ်တဲ့ system configuration နဲ့ wireguard configuration တွေအကုန်လုံး ကို စာရေးသူ Ansible နဲ့ ရအောင်လုပ်ဖို့ ကြိုးပမ်းပါတော့တယ်။ ပြီးတော့ တဆက်တည်းမှာပဲ peer configuration တွေကိုလည်း တပါတည်း Ansible နဲ့ လုပ်နိုင်ရင် ကောင်းမယ် စဉ်းစားမိတာနဲ့ အရင်က bash နဲ့ automation လုပ်ထားတဲ့ workflow ကိုပါ integrate လုပ်ချင်လာပြန်ပါတယ်။ ဒီတော့... end-to-end automation ကိုမြင်ယောင်ပြီးတော့ တစချင်းစီ play တွေတည်ဆောက်ပါခဲ့ပါတယ်။ အားလုံး အလုပ်လုပ်ပြီဆိုတာနဲ့ ကိုယ်လည်း နှစ်သစ်မှာ အပြင်မှာလည်ပတ်ပြီးတော့မေ့သွားမှာ စိုးရိမ်လို့ အင်္ဂလိပ်လိုပဲ ခပ်သွက်သွက်လေး self-note ပုံစံမျိုး ချရေးထားလိုက်ပါတယ်။ အနည်းဆုံးတော့ ကိုယ့်အတွက် documentation တစ်ခုကျန်အောင်လို့ပါ။ ဒါနဲ့ အဲ့ဒီ အင်္ဂလိပ်လို ရေးထားတဲ့ အတိုင်းပဲ share ပေးထားလိုက်ပါတယ်။ နောက်မှ... IaC အပိုင်း(၄) အတွက် ဒီ use case လေးနဲ့တော့ အဆင်ပြေတယ်ဆိုပြီး အခုဆက်ရေးဖြစ်သွားတယ်။ ဒီ article မှာတော့ စာရေးသူ အဲ့ဒီ playbook မှာပါဝင် အစိတ်အပိုင်းလေးတွေကို အချိန်ရသလောက် နည်းနည်းချင်းစီ ရှင်းပြသွားချင်ပါတယ်။
Ansible workflow အတွေးလုပ်ငန်းစဉ်
ပထမဆုံး အနေနဲ့ စာရေးသူ အတွေးလုပ်ငန်းစဉ်ကို အရင်ချပြချင်ပါတယ်။ Linode မှာဘယ်လိုမျိုး VPS တစ်လုံးကို Ansible နဲ့ တည်ဆောက်သလဲဆိုတာကို ရှာဖို့အတွက်က Linode မှာ documentation တွေအများကြီးရှိပါတယ်။ ဒီအတွက်... VPS တစ်လုံးဖြစ်အောင် Ansible နဲ့လုပ်ဖို့ဆိုတာတော့ သိပ်မခက်ဘူးဆိုတာတွေးမိပါတယ်။ ပြဿနာက ကိုယ်တစ်ယောက်တည်း သုံးလို့ရအောင် လုပ်ဖို့ထပ် ကိုယ်အားလုံးပြီးသွားလို့ ပြန် share တဲ့အခါမှာ အခြားသူအတွက် နားလည်လွယ်ဖို့အတွက် ထပ်ကာထပ်ကာပြန်သုံးနိုင်ဖို့အတွက် variable တွေကို အသုံးပြုနိုင်ဖို့ ဆုံးဖြတ်လိုက်ပါတယ်။ ဒီတော့... နောက်အသုံးပြုချင်တဲ့သူက var folder ထဲမှာရှိတဲ့ variable တွေကိုလိုသလို ပြောင်းလဲသုံးနိုင်ဖို့အတွက် မခက်ခဲတော့ဘူးလို့ မြင်ပါတယ်။ နောက်တစ်ခုက... လိုအပ်တဲ့ content input တွေကို သင့်တော်သလို Jinja2 template နဲ့လုပ်ဖို့လည်း စိ်တ်ကူးမိပါတယ်။ sshdconfig လိုမျိုး static file ကိုတော့ files ဆိုတဲ့ folder မှာပဲထားပြီး ဒီအတိုင်းထည့်ဖို့ စဉ်းစားခဲ့ပါတယ်။ sed တို့ awk တို့ကို သုံးပြီး sshdconfig file ကို Ansible ကနေ edit လုပ်နိုင်သော်လည်း immutable workflow အတွက် static file ကပိုအလုပ်ဖြစ်မယ်လို့ ထင်ပါတယ်။ ဒီအတွက် build process တိုင်းမှာ sshd_config ဟာ desired state မှာအမြဲရှိဖို့ အတွက်လည်း ရည်ရွယ်ပါတယ်။
လုပ်ရင်းကိုင်ရင်းနဲ့ စာရေးသူအတွက် အခက်အခဲတစ်ခုက Linode မှာတည်ဆောက်လိုက် VPS တစ်လုံးကို on-the-fly inventory တစ်ခုတည်ဆောက်ဖို့လိုပါတယ်။ အဲ့ဒီအတွက် in-memory inventory တစ်ခုကို Ansible ရဲ့ add_host module ကိုသုံးထားပါတယ်။ ဒီလိုလုပ်လိုက်ခြင်းဖြင့် inventory file ကိုသပ်သပ် ဖန်းတီးစရာမလိုတော့တဲ့အပြင်၊ workflow ဟာလည်း ပိုပြီးတော့ fluid ဖြစ်လာတယ်၊ dynamic ပိုဖြစ်လာတယ်လို့ မြင်မိပါတယ်။ Ansible playbook မှာတော့ stanza တစ်ခုတည်းပါ၊ ကိုယ်လုပ်ချင်တဲ့ပုံစံဖြစ်ဖို့အတွက် ဘယ် module ကိုအသုံးချရမလဲဆိုတာ သိဖို့ကတော့ အချိန်အများကြီးပေးပြီးတော့ ရှာလိုက်ရပါတယ်။
နောက်တစ်ခုက... စာရေးသူလုပ်ချင်တဲ့ဟာတွေကို Ansible playbook တစ်ခုတည်းမှာပဲ အပိုင်းလေးတွေခွဲပြီးတော့ လုပ်ချင်ပါတယ်။ အဲ့ဒီအတွက် Ansible မှာရှိတဲ့ block ဆိုတဲ့ concept ကိုအသုံးပြုပါတယ်။ ပြီးတော့ testing အတွက်လည်း လိုအပ်တဲ့ block တွေကိုတစ်ခုချင်းစီ ပြန်ပြီးခေါ်လို့ရနိုင်အောင်လို့ tags ကိုသုံးထားပါတယ်။ Testing အတွက်မပါလည်းရပါတယ်၊ စာရေးသူ build process ပြီးရင် VPS ထဲဝင်ဝင် စစ်ရလို့ စိတ်မရှည်တော့လို့ testing block ကိုထပ်ပြီးတော့ implement လုပ်ဖြစ်သွားတာပါ။ Block တွေတစ်ခုပြီးတစ်ခုရေးရင်နဲ့ သတိထားမိလာတာ စာရေးသူ ရဲ့ Line တွေအများကြီးဖြစ်လာပါတယ်၊ ဒီ့အပြင် VPN user တွေအတွက် QRcode တွေကိုအများကြီးရိုက်ထုတ်တဲ့အခါ loop တစ်ခုလိုအပ်တဲ့အတွက် wguser.yml ဆိုတဲ့ playbook ကို သီးသန့်ခွဲထုတ်ဖို့ ဖြစ်လာပြန်တယ်။ ဒီလိုခွဲထုတ်လိုက်ခြင်းအားဖြင့် readability လည်း တက်လာသလို၊ code ရဲ့ workflow ကပိုပြီးတော့ ပြေပြစ်သွားပါတယ်။ နောက်ဆုံးတစ်ခုကတော့... teardown အတွက် wg_PURGE.yml playbook တစ်ခုကို ထပ်မံတည်ဆောက်ဖို့ ဖြစ်လာပြန်ပါတယ်။
လက်တွေ့အသုံးချပုံ
စာရေးသူရဲ့ Ansible playbook နဲ့ အခြား folder တွေအကုန်လုံးကို အောက်မှာပါတဲ့ link သွားပြီးတော့ download ဆွဲလို့ရပါတယ်။
ပထမဆုံး Linode ရဲ့ API python library ကို အောက်မှာပြထားတဲ့ အတိုင်း pip နဲ့အရင်ဆုံး install လုပ်ရပါ့မယ်။
ဒါဆိုရင်တော့... Linode ရဲ့ API ကိုအသုံးပြုပြီးတော့ Ansible မှာ VPS တစ်လုံးတည်ဆောက်ဖို့ အဆင်သင့်ဖြစ်ပါပြီ။ ဒီတော့ wg_build.yml စပြီးတော့ကြည့်လိုက်ရအောင်ဗျ။
ဒီအပို်င်းမှာတော့ ဘာမှထွေထွေထူးထူး မရှိပါဘူး။ Linode ရဲ့ API ကိုအသုံးပြုပြီးတော့ VPS တစ်လုံးတည်ဆောက်တယ်၊ ပြီးရင် in-memory inventoy တည်ဆောက်တယ်၊ နောက်တော့ port 22 က Linode ချပေးတဲ့ public IP မှာ ready ဖြစ်ပြီလာဆိုတာကို စစ်ကြည့်တယ်။ VPS ကအားလုံး ready ဆိုတော့မှ နောက်အဆင့်ကို ထပ်ပြီးတော့သွားဖို့ အဆင့်သင့်ဖြစ်ပါတော့တယ်။ လိုအပ်တဲ့ variable တွေကိုတော့ vars folder အောက်က linode_wg.yml မှာအောက်ကအတိုင်းတွေ့ရမှာပါ။
ဒုတိယအပိုင်းမှာတော့ ရလာတဲ့ VPS ကို လိုအပ်တဲ့ basic security configuration တွေအတွက် အောက်ကအတိုင်း ဆက်ပြီးတော့ Ansible ကိုအသုံးပြုပြီးတော့ configure လုပ်ပါတယ်။
ဒီတပိုင်းမှာတော့... Ubuntu 20.04 LTS ကို apt update && apt upgrade လုပ်တယ်၊ လိုအပ်ရင် server ကို reboot ချပြီးတော့၊ server ပြန်တက်လာရင် ufw နဲ့ packet forwarding ကို wireguard အတွက်ပြင်ဆင်ရပါတယ်။ ဒီအဆင့်မှာပဲ... sshd_config ကို local machine ကနေ VPS ပေါ်ကို ကူးယူပြီးတော့၊ handler နဲ့ ssh daemon ကို restart ချပါတယ်။ လိုအပ်ရင် သုံးလို့ရအောင်လို့ unit testing ပုံစံမျိုး code block တစ်ခုကိုလည်း ပြထားတဲ့ အတိုင်းထပ်ပေါင်းထည့်ထားပါတယ်။ Testing အတွက်တကူးတက VPS ထဲဝင်ပြီး ssh နဲ့ sysctl configuration တွေကိုတစ်ခုချင်းစီ စစ်ဆေးစရာမလိုတော့ပါဘူး။ အဲ့ဒီအတွက်... Ansible ရဲ့ assert module ကိုအသုံးပြုထားပါတယ်။
နောက်ဆုံးအပိုင်းမှာတော့... WireGuard installation နဲ့ configuration အတွက်အောက်ကအတိုင်း code block တစ်ခုကိုတွေ့ရမှာပါ။
အပိုင်းသုံးပိုင်းထဲမှာ ဒီအပိုင်းက အရေးအကြီးဆုံးနဲ့ stanza အများဆုံး အပိုင်းဖြစ်ပါတယ်။ ဒီ့အပြင်... wguser.yml ကိုလည်း ဒီအပိုင်းမှာပဲ loop ထည့်လှည့်ထားတာကိုတွေ့ရမှာပါ။ နောက်ပြီးတော့... wireguard peers တွေကိုရိုက်ထုတ်တဲ့ လုပ်ငန်းစဉ်ကို ပထမက VPS ပေါ်မှာလုပ်ပြီးတော့ VPS မှာပဲ သိမ်းဖို့ရည်ရွယ်သော်လည်း နောက်ဆုံးမှာ local machine မှာပဲ လုပ်ဖို့ဆုံးဖြတ်ချက်ချလိုက်ပါတယ်။ အဲ့ဒီအတွက် nested block အနေနဲ့ block တစ်ခုတည်ဆောက်ပြီး delegateto: localhost ဆိုတာနဲ့ in-memory inventory ကို bypass လုပ်ထားပါတယ်။ wg_user.yml ကိုတော့အောက်ကအတိုင်းတွေ့ရမှာပါ။
ဒီ wireguard peer တွေကိုထုတ်တဲ့အခါမှာလည်း idempotent ဖြစ်အောင်လို့ error handling တွေအတွက် လိုအပ် logic control တွေကိုထည့်သွင်းထားတာကိုလည်း တွေ့ရမှာပါ။
Teardown အတွက် စာရေးသူ wg_PURGE.yml playbook ကိုသီးသန့် ခွဲထုတ်လိုက်ရပါတယ်။ ရိုးရှင်းသလောက် static hostname နဲ့ label ကိုအသုံးပြုထားတဲ့အတွက် immutable ဖြစ်ပါတယ်။ dynamic hostname ကိုသုံးမယ်ဆိုရင် ပြဿနာရှိနိုင်ပါတယ်။
ကောင်းပြီ... playbook နဲ့ပတ်သတ်တဲ့ အပိုင်းကိုအကုန်လုံး ရှင်းလင်းပြီး နောက်အဆင့်အနေနဲ့ templates တွေပါတချက်ကြည့်လိုက်ရအောင်ဗျ။ ပထမဆုံးအနေနဲ့ wg0.conf.j2 ကိုအရင်ဆုံး အောက်ကအတိုင်းတွေ့ရမှာပါ။ Jinja2 templating မှာလည်း vars folder အောက်က linode_wg.yml မှာသိုလောင်ထားတဲ့ variable တွေကို ဒီမှာယူသုံးလို့ရပါတယ်။ အခြားသော Ansible ရဲ့ variable တွေကိုလည်း ယူသုံးနိုင်တဲ့အတွက် ဘယ် variable ကိုဘယ်မှာ ဘယ်လိုယူသုံးရသလဲဆိုတာကိုတော့ သိဖို့လိုပါတယ်။ ဥပမာ... {{ ansible_default_ipv4.interface }} ဆိုတဲ့ variable ကိုယူမသုံးခင်က စာရေးသူ eth0 ဆိုပြီးတော့ သုံးပါတယ်။ သို့သော်... Linux ရဲ့ network interface name ဟာတခါတလေကြရင် အကြောင်းအမျိုးမျိုးကြောင့် ပြောင်းသွားနိုင်တာမို့ Ansible ရဲ့ variable ကိုယူသုံးတာ ပိုပြီးတော့ သဘာဝကျပါတယ်။
နောက် template တစ်ခုကတော့ wireguard peer တွေကိုရိုက်ထုတ်တဲ့အခါမှာ ထွက်လာတဲ့ server နဲ့ client configuration တွေအတွက် template နှစ်ခုပါ။ ပထမဆုံး wg_srv.j2 ကိုအောက်မှာကြည့်လိုက်ရအောင်။
ဒီ template ကထွက်လာအပိုင်းကို Wireguard server configuration မှာသွားပြီးတော့ merge လုပ်ရမှာဖြစ်ပြီးတော့၊ အဲ့လို merge လုပ်တိုင်း wireguard service ကို restart လုပ်ရပါ့မယ်။
Wireguard client အတွက်တော့ wg_peer.j2 ဆိုတဲ့ template ကိုအသုံးပြုပြီးတော့ peer တွေကိုလိုသလောက် ရိုက်ထုတ်လို့ရပါတယ်။
ဒီတစ်ခုမှာလည်း အပေါ်မှာတွေ့ရတဲ့အတိုင်း{{ hostvars[inventory_hostname]["inventory_hostname"] }} ဆိုတဲ့ variable ကိုအသုံးပြုခြင်းကြောင့် VPS ကို build နဲ့ teardown လုပ်တဲ့အခါမှာ ဘာကိုမှပူစရာမလိုတော့ပဲ၊ အလွယ်တကူ ထပ်ခါထပ်ခါလုပ်လို့ရတဲ့ workflow တစ်ခုဖြစ်လာပါတယ်။
VPN user တွေကို အများကြီးပေါင်းထည့်လို့ရအောင်လို့လည်း wg folder အောက်မှာ users.csv ဆိုတဲ့ file ကိုအသုံးပြုထားပါတယ်။ ဒီတစ်ခုမှာတော့ စာရေးသူအရင်ကလုပ်ပြီးသား bash script automation ကို Ansible ဘက်ကိုတိုက်ရိုက်နီးပါး ပြန်ကူးယူးထားတယ်လို့ဆိုရမလားတောင် မသိပါဘူး။ တော်တော်လေးဆင်တူနေတာကိုတွေ့ရမှာပါ။ Bash script နဲ့လုပ်ထားတဲ့ automation workflow အကြောင်းကို မဖတ်ရသေးရင်တော့ အောက်က link မှာသွားရောက်ဖတ်ရှုနိုင်ပါတယ်။
Ansible-vault ကိုသုံးပြီးတော့ password တွေ token တွေကို encrypt လုပ်တာကိုတော့ အသေးစိတ်မသွားတော့ပါဘူး။ အင်္ဂလိပ်လိုရေးတဲ့ article မှာလည်း အကျဉ်းချုပ်ရေးသားပြီးသားမို့ သေချာသိချင်ရင် အောက်က link မှာလေ့လာလို့ရနိုင်ပါတယ်။
ဒီလောက်ဆိုရင်တော့... ဒီ article အတွက်တော်တော်လေးကိုပြည့်စုံသွားပြီလို့ပြောလို့ရပါတယ်။ အခုလိုမျိုး Ansible ကိုအသုံးပြုပြီးတော့ playbook တွေဖန်တီးလိုက်တာဟာ နောင်အခါ Wireguard server လုပ်ဖို့အတွက်အများကြီး လွယ်သွားရုံသာမက၊ Infrastructure as Code (IaC) ဆိုတဲ့အတိုင်း အဲ့ဒီ playbook တွေဟာ ကိုယ့်အတွက်လည်း Wireguard server ကိုဘယ်လို setup လုပ်သလဲ၊ configure လုပ်သလဲဆိုတာကို document လုပ်ပြီးသားဖြစ်သွားပါတယ်။ Ansible playbook တွေဟာ delcarative ဖြစ်တဲ့အတွက် ဖတ်ရတာလည်း အဲ့ဒီလောက်မခက်ပါဘူး။ ဒီ article ကိုဖတ်ပြီးတော့ အကျိုးရှိမယ်တော့ထင်ပါတယ်။ IaC အပိုင်း (၄) ကို ဒီမှာပဲရပ်လိုက်ပါတော့မယ်။
Last updated
Was this helpful?

