နားလည်ထားရမယ့် အချက်
deploy မြန်တာက အသင်းတွေ ဂုဏ်ယူပြောလေ့ရှိတဲ့ ကိန်းဂဏန်းပါ၊ ဒါပေမယ့် incident တစ်ခုက ခဏတာ ခြစ်ရာလား၊ တကယ့် outage လား ဆိုတာ ဆုံးဖြတ်ပေးတာက recovery မြန်နှုန်းပါ။ ၄ မိနစ်နဲ့ ship လုပ်နိုင်ပေမယ့် ပြန်ရုပ်ဖို့ ၉၀ မိနစ် ကြာတဲ့ pipeline ဟာ မကောင်းတဲ့နေရာကို မြန်မြန်ရောက်အောင် ပို့ပေးတဲ့ ကိရိယာ တစ်ခုပါပဲ။ ဒါကြောင့် rollback လမ်းကြောင်းကို အရင်ဒီဇိုင်းဆွဲပြီး၊ ပုံမှန် လက်တွေ့ စမ်းသုံးပါ — မစမ်းဖူးတဲ့ rollback ဟာ အယူအဆတစ်ခုသာ ဖြစ်တယ်။
ရွေးစရာ နှစ်ခု ရှိတယ်။ roll back ဆိုတာ ကောင်းတယ်လို့ သိပြီးသား version အဟောင်းကို ပြန်တင်တာပါ၊ ပြဿနာက ဘာကြောင့်လဲ ဆိုတာ မသိသေးတဲ့အခါ ဒါက မှန်တယ် — ဘာကြောင့်လဲ ရှာမနေရဘဲ သွေးထွက်တာကို အရင်ရပ်နိုင်လို့ပါ။ fix forward ဆိုတာ ပြင်ဆင်ချက် အသစ်တစ်ခု ship လုပ်တာပါ၊ version အဟောင်းကလည်း ပျက်နေတဲ့အခါ၊ code အသစ်က ရေးထားတဲ့ data ကို code အဟောင်းက ဖတ်လို့မရတော့တဲ့အခါ၊ ဒါမှမဟုတ် ပြောင်းလဲမှုက လုံးဝ ပြန်မလှည့်နိုင်တဲ့အခါ ဒါက မှန်တယ်။ ဖိအားအောက်မှာ ဆုံးဖြတ်ရတာ ခက်တဲ့အတွက် စည်းမျဉ်းကို ကြိုသဘောတူထားသင့်တယ် — default က roll back၊ rollback မလုံခြုံဘူးဆိုတဲ့ အကြောင်းရင်းကို တစ်ယောက်ယောက် ပြောပြနိုင်မှသာ fix forward။
rollback ကို လွယ်ကူစေတာက immutable artifact ပါ။ build တိုင်းက သူ့ commit SHA နဲ့ tag တပ်ထားတဲ့ image တစ်ခု ထုတ်ပြီး အဲဒီ tag ကို ဘယ်တော့မှ ပြန်မသုံးဘူးဆိုရင် rollback ဟာ ရှိပြီးသား tag တစ်ခုကို ပြန် deploy လုပ်ရုံပါပဲ — build ပြန်လုပ်စရာ မလို၊ dependency ပြန်ရှာစရာ မလို၊ source တူပေမယ့် binary မတူထွက်လာမယ့် အန္တရာယ်လည်း မရှိ။ incident အတွင်းမှာ "အရင် commit" ကို ပြန် build လုပ်တာက transitive dependency တစ်ခု ရွေ့သွားပြီဆိုတာ သိလိုက်ရတဲ့ နည်းလမ်းပါ။
လူတွေ လွတ်တတ်တဲ့ အချက်က application ကို ပြန်ရုပ်တာဟာ database ကို ပြန်မရုပ်ပေးဘူး ဆိုတာပါ။ column တစ်ခု drop လုပ်ခဲ့တဲ့၊ type ကို ကျဉ်းချုံ့ခဲ့တဲ့၊ ဒါမှမဟုတ် data ကို ဖျက်ပြီး backfill လုပ်ခဲ့တဲ့ migration ကို code အဟောင်း ပြန်တင်ရုံနဲ့ ပြန်လှည့်လို့ မရဘူး။ ဒါကြောင့် schema ပြောင်းလဲမှုတွေမှာ expand/contract ကို သုံးတယ် — ပုံစံအသစ်ကို အရင်ထည့်၊ နှစ်ခုလုံးကို ရေး၊ reader တွေကို ရွှေ့၊ ပြီးမှ run နေတဲ့ version တစ်ခုမှ မလိုတော့တဲ့အခါ နောက် release တစ်ခုမှာမှ အဟောင်းကို ဖျက်တယ်။
ROLLBACK ON A VERSION TIMELINE
------------------------------
APP CODE
v41 ---- v42 ---- v43 (BAD) ---- v42 again ---- v44 (fix forward)
| ^
alerts fire |
+-- redeploy existing immutable tag v42
no rebuild, no dependency resolution
DATABASE
v43 also ran: ALTER TABLE users DROP COLUMN nickname
deploying v42 again does NOT bring that column back
worse: v42 may now crash reading rows it no longer understands
EXPAND / CONTRACT (the reversible way)
release 1: add new column (old code still fine)
release 2: write both old + new (either version can serve)
release 3: read new only
release 4: drop old column (only now, and never sooner)လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
ဒီ workflow က rollback ကို ကိုယ်တိုင် စတင်နိုင်တဲ့ လုပ်ငန်းစဉ်တစ်ခု အဖြစ် ရေးထားတယ် — incident ဖြစ်မှ တစ်ယောက်ယောက်ရဲ့ terminal history ထဲက command ကို ရှာစရာ မလိုတော့ဘူး။ input က ပြန်သွားချင်တဲ့ immutable image tag ပါ။
verify-artifact job က အရေးအကြီးဆုံးပါ။ ပထမ step က အဲဒီ tag registry ထဲမှာ တကယ် ရှိသေးလား စစ်တယ် — retention policy က တစ်လကျော် image တွေကို ဖျက်ပစ်ပြီးမှ rollback လုပ်လို့မရမှန်း သိရတာမျိုး မဖြစ်စေချင်ဘူး။ ဒုတိယ step က ပိုအရေးကြီးတယ် — အဲဒီ version နောက်ပိုင်းမှာ ပြန်မလှည့်နိုင်တဲ့ migration တစ်ခုခု run ခဲ့လားလို့ စစ်ပြီး၊ ရှိရင် rollback ကို ငြင်းပယ်တယ်။ ဒီ step မပါရင် pipeline က ကိုယ့်ကို "အောင်မြင်တဲ့ rollback" လို့ ပြောပြီး app ကတော့ schema အသစ်ပေါ်မှာ crash နေမယ်။
redeploy job က source ကနေ ပြန်မဆောက်ဘူး ဆိုတာ သတိပြုပါ — ရှိပြီးသား image ကို ညွှန်ပြရုံပါပဲ။ ဒါက rollback ကို ဒီလောက် မြန်စေတဲ့ အကြောင်းရင်းပါ။ နောက်ဆုံးမှာ smoke test က တကယ် ပြန်ကောင်းသွားပြီလား အတည်ပြုပေးတယ်။ လေ့ကျင့်ခန်းအနေနဲ့ ဒီ workflow ကို လအလိုက် တစ်ခါလောက် staging မှာ run ပါ — မ run ဖူးတဲ့ rollback path ဟာ လိုအပ်တဲ့ နေ့မှာ အလုပ်မလုပ်တတ်ပါဘူး။
အတူတူ စမ်းရေးကြည့်မယ်
name: Rollback
on:
workflow_dispatch:
inputs:
version:
description: Immutable image tag to roll back to
required: true
type: string
permissions:
contents: read
id-token: write
jobs:
verify-artifact:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Confirm the image tag still exists in the registry
run: ./scripts/registry-has-tag.sh ${{ inputs.version }}
- name: Refuse if an irreversible migration ran after that version
run: ./scripts/check-migration-compat.sh ${{ inputs.version }}
redeploy:
needs: verify-artifact
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE }}
aws-region: ap-southeast-1
- name: Point production at the older image without rebuilding
run: ./scripts/deploy-image.sh ${{ inputs.version }}
- name: Smoke test the restored version
run: ./scripts/smoke.sh https://example.com
- uses: actions/upload-artifact@v4
if: always()
with:
name: rollback-record
path: reports/
retention-days: 90
workflow ကို image tag တစ်ခုနဲ့ ကိုယ်တိုင် စတင်ရတယ်။ verify-artifact job က အဲဒီ tag registry ထဲမှာ ရှိမရှိ၊ အဲဒီ version နောက်ပိုင်း ပြန်မလှည့်နိုင်တဲ့ migration တစ်ခုခု run ခဲ့မခဲ့ စစ်တယ်။ တစ်ခုခု ကျရင် redeploy job က needs မပြည့်လို့ လုံးဝ မစဘဲ ကျော်သွားတယ် — ဆိုလိုတာက ပြန်မလှည့်နိုင်တဲ့ schema အပေါ်ကို version အဟောင်း ပြန်တင်မိတဲ့ အခြေအနေမျိုး မဖြစ်တော့ဘူး။ စစ်ဆေးမှု အားလုံး အောင်မြင်ရင် redeploy job က production environment ကို သုံးလို့ အဲဒီ environment မှာ approval လိုအပ်ရင် အရင် စောင့်ရမယ်၊ ပြီးမှ ရှိပြီးသား image ကို ညွှန်ပြပြီး smoke test run တယ်။ smoke test ကျရင် deploy က fail အဖြစ် မှတ်တမ်းတင်ပေမယ့် record artifact ကတော့ if: always() ကြောင့် တင်ပြီးသား ဖြစ်နေမယ်။၅ မိနစ် စမ်းကြည့်
ကိုယ့် repository ရဲ့ နောက်ဆုံး migration ၅ ခုကို စစ်ပြီး ဘယ်ဟာတွေက ပြန်လှည့်လို့ ရ၊ ဘယ်ဟာတွေက မရ ဆိုတာ စာရင်းလုပ်ပါ။ မရတဲ့ တစ်ခုကို ရွေးပြီး expand/contract အဖြစ် release ဘယ်နှစ်ခု ခွဲရမလဲ ရေးဆွဲပါ။ ပြီးရင် ဒီ rollback workflow ကို staging မှာ တကယ် run ပြီး အချိန်ဘယ်လောက် ကြာလဲ တိုင်းပါ — အဲဒါက ကိုယ့်ရဲ့ တကယ့် time to restore ရဲ့ အောက်ခြေကန့်သတ်ချက် ဖြစ်ပါတယ်။
သတိလေးတစ်ချက်
rollback လုပ်လိုက်ရင် အဲဒီ release နဲ့အတူ ပါလာခဲ့တဲ့ database migration ပါ ပြန်ပြောင်းသွားမယ်လို့ ယူဆမိတာ — column drop လုပ်ပြီးသားဆိုရင် code အဟောင်းက crash ဖြစ်နိုင်တယ်
incident အတွင်းမှာ commit အဟောင်းကနေ ပြန် build လုပ်တာ — dependency တွေ ရွေ့သွားပြီး ကောင်းတယ်လို့ ထင်ထားတဲ့ version နဲ့ မတူတဲ့ artifact ထွက်လာနိုင်တယ်
GitHub Docs: Deploying with GitHub Actions — CI/CD with GitHub Actions