延續昨天的 playbook,今天打算花一些篇幅來簡單解說,
理由是這支 playbook 涵蓋了我接觸到 devops/build flow 自動化 80% 的底層邏輯,
剩下的 20% 多半是一些 domain specific 的知識點,
例如用 ansible 接上 cloud provider 的 API 控制部署環境
btw,推薦去書店翻翻 <<底層邏輯>> 這本書,
所有事情都可以分成 底層邏輯 + 環境變數,
有點像 20/80 法則,
掌握 20% 的核心可以取得 80% 的成果,
所以我們就把核心的部分說細一點,
掌握基本知識點後面就容易擴展了
btw2,祝讀者中秋節快樂~
我現在吃得非常撐來寫這篇文章,
每天發文真滴不容易…
希望明天能順利進入 AWX 的部分
前情提要
adhoc 寫一個 Python FastAPI 範例 + Dockerfile
用 Ansible 遠端部署 <- 現在在這裡
用 Ansible AWX 自動部署
以下正文
- name: show remote host
debug:
msg: "the remote server is {{ ansible_host }}"
這條沒什麼,我習慣在每個 playbook 第一條印出 remote host 和 user 的訊息,
當你有複數層跳板需要打穿 + 複數台機器需要同時部署,
好的習慣能幫助你少犯一些 trivial 的錯誤也容易 debug
- name: create build dir if not exists
file:
path: "{{ build_root_abspath }}"
state: directory
這邊的 "{{ build_root_abspath }}"
是使用 jinja2 的模板語法,
變數的定義是從 project 根目錄的 main.yml
傳下來的,
這也是我一開始用 ansible 最困惑的地方…我怎麼知道這東西可以從那邊傳過來…
- name: git clone
git:
repo: "git@github.com:yiidtw/ironman2023-demo-fastapi.git"
dest: "{{ build_root_abspath }}"
remote: "origin"
version: "main"
非常直觀的一支 task,remote
對應 git remote
看到的 remote alias,version
對應 remote git branch,
只需要兩點提醒,
第一點,最好先在 remote 機器 e.g. ubuntu-staging-env,確認到 github.com 的 ssh connection 是連通的,
例如壓這個指令 ssh -T git@github.com
,應該要可以看到自己 Welcome <你的 github account> 的 console output,
第二點,我們這邊的 dest
是用 timestamp 當參數,每次執行的時候在 remote server 建立暫時的資料夾,
原因是你大概會希望每次 clone 都是最新版的 code,才不會被舊的 code 汙染,
e.g. 有人 git push -f
不跟你說…你可以選擇執行完 playbook 之後把 temp 資料夾砍掉省空間,
我是都會留著,一段時間再一起 rotate ,避免需要某個時間的 build snapshot 來 debug
- name: build docker
community.docker.docker_image:
name: ironman2023-fastapi
build:
path: "{{ build_root_abspath }}"
tag: "{{ demobackend_version }}"
source: build
對應到你在 remote server 壓下 docker build -t ironman2023-fastapi:"{{ demobackend_version }}" .
的指令,
同樣的,該參數是從 top-down 傳下來
- name: run docker
docker_container:
name: demobackend
state: started
recreate: yes
image: "ironman2023-fastapi:{{ demobackend_version }}"
ports:
- "8080:8080"
對應到 remote server 上 docker run -d --restart -p 8080:8080 ironman2023-fastapi:"{{ demobackend_version }}"
- name: wait for the api ready
wait_for:
host: 0.0.0.0
port: 8080
delay: 10
等 10 sec 之後,再開始等 0.0.0.0:8080 port open,
因為 recreate container 需要一些時間,
可以按需延長等待時間
- name: testing api locally
shell: "curl -k localhost:8080"
register: reg_curl_result
- name: show curl result
debug:
msg: "{{ reg_curl_result.stdout }}"
你大概會有很多方法可以測試 container 的 heartbeat 或是健康程度,
還可以串各種 UT、integration test 測試你的 backend API container 是否正常運作?
我們這邊用最簡單的方式直接 curl
,
並用肉眼判斷結果是否為 {"Hello", "World"}