關於我想看漫畫卻不想看廣告這檔事 (18) — Github Actions + Terraform + Serverless framwork = 大團圓

Seaweed
10 min readDec 11, 2021

--

作為收尾,這次用上了之前所提到的所有技術,堪稱大團圓。

而既然是大團圓,那就來感性一下:

這麼溫馨的場景,還請各位司機不要亂開車。

本篇程式碼

Workflow 檔這次也同樣在 .github/workflows 底下,名為section_18_delpoyToAws.yml。

各雲端角色定位

這次佈署包含三個工具三個雲端的互動,這邊先明確各個雲端的角色定位。

Terraform Cloud

這裡是第一次使用,但由於我們將在雲端佈署另一個雲端,用來紀錄雲端狀態的 terraform.tfstate 勢必也得雲端化。而依靠 Terraform Cloud 我們可以直接省去處理 terraform.tfstat 同步問題的麻煩,它將會在執行時隨時將最新狀態同步至雲端方便隨後存取。

AWS

事到如今應該沒什麼好說的,我們的佈署目標。

Github Actions

執行我們 CI/CD 的主要平台,啟動前先透過 Terraform Cloud 獲取目前的 AWS 雲端狀態(以及鎖),接著使用 Terraform 佈署 Crawler 。最後根據 Terraform 輸出的資料庫連線資訊,使用 Serverless Framework 佈署 Reader。

這樣我們就可以一次佈署 Crawler 與 Reader 並且不必擔心在 Github Actions 佈署時因佈署失敗或其他不可測狀況導致的 terraform.tfstate 狀態遺失。

部署流程

接著來大致說明一下這次新增的 workflow 大致的執行流程

程式碼測試

佈署之前進行的程式測試,基本上就是上一篇的內容。

參數讀取與初始化

原本的 PROXY_PEM_PATH 以及 SQL_PATH 表示的都是檔案的路徑,但在雲端的 Github Actions 中並不會有這些檔案,所以這邊我們直接把檔案內容塞入 secrets 中並重新透過 echo > 輸出成檔案。

佈署環境準備

安裝佈署時會用到的工具,比如 mysql-client/aws-cli 等等。

Terraform 佈署 Crawler & 產出 .env

佈署 crawler ,並且輸出佈署 reader 會需要的資料庫連線資訊,放到 .env 內。

Severless Framework 佈署 Reader

拿上一步產生的 .env 來佈署 Reader。

流程大致就是這五步,詳細後續說明。

前置準備

正式進到程式碼之前我們有兩個東西得先設定:

Terraform Cloud 設定

建立 Workspace

用下面的連結申請帳號後建立一個 Organization 以及一個 Workspace(類型是 CLI-driven workflow)。

然後點進剛建立好的 Workspace 點擊 Setting 下的 General。

往下拉到 Execution Mode 選擇 Local。這很重要,否則就會變成在雲端執行 Terraform 部署,然後找不到 docker 等等各種相依套件之後爆炸。

然後拉到最底下儲存設定。

取得個人認證 Token

接著要來取得個人認證用的 Token,讓 Local 端的 Terraform 使用這個 Token 來存取現在的雲端狀態。

總之先找到右上角的個人 icon 後點進 User settings。點擊左側的 Token 分頁。

Create An API Token 點下去。

之後輸入名字之後再點一次 Create API token 就完成了。最後會直接顯示 Token 內容,麻煩記下來我們,頁面關掉就看不到了。

Github Actions Secrets 設定

這次會用到的參數如下,執行前請先確保有設定在 Secrets 裏面。

AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY

AWS 的 Key

TF_API_TOKEN

前一步取得的存取 Terraform Cloud 的個人認證用的 Token。

PROXY_HOST/PROXY_PORT/PROXY_USER

跳板連線用的 ssh host/port/username。

DB_USER/DB_PASS

將來連線資料庫要用的 username/password。

PROXY_PEM/DB_SQL

跳板連線用的 pem 檔案以及初始化資料庫的 .sql 的內容(不是檔名)

這邊順便附上 Github secrets 的詳細設定方法:

部署程式碼解說

接著我們來看這次新增的程式碼。

remote-state.tf

這邊就是設定連線我們剛剛建立的 Terraform cloud。使用時麻煩把 organization 跟 workpaces 都換成剛剛建立的。

github actions: tests-crawler-before-deploy-to-aws

這次我們的 actions 比較長,切成了三個部分說明。另外,說明不包含 on 的 trigger 內容設定,有需求還請看以下的官方教學自行撰寫。

部署前第一步是執行程式測試:

github actions: deploy-to-aws:env-setup

接著是實際進行部署,但部署之前我們得先對部署環境進行初始化。

可以發現主要就是做了以下幾件事:

  • 由參數生成必要檔案(proxy.pem 與 init.sql)
  • 安裝/設定必要指令(mysql-client 與 docker)
  • 登入關聯雲端服務(AWS, AWS ecr, Terraform cloud)

另外需要注意這邊用 need: test-crawler-before-deploy-to-aws(不是 name: 的部分 切記)來指定這個 job 的前置條件,透過這種方式就可以設定 job 的相依性。

其他應該是沒有特別需要注意的,頂多比較容易混亂的是使用 Terraform push image 進 AWS ECR 之前得先設定 AWS 憑證並登入 ECR(L21 & L28)。這邊雖然看似用了很多外部的 action,但都不難,對詳細用法有興趣去 Marketplace搜尋查看各自的說明頁面就可。

github actions: deploy-to-aws:deploy-crawler

然後就是實際部署了,首先是 Crawler:

這邊其實也沒什麼特別的,主要需要說明的就只有以下三項:

  • 因為沒有 terraform.tfvars 檔案,所以這裡透過 TF_VAR_<varname> 來設定部署參數。
  • 為避免麻煩,部署失敗時一率全部刪掉後退出,所以用 build_failed.txt 作為控管的條件。
  • 使用 terraform output -json , grep 以及 jq 將建立好的資訊打包成 .env 檔案格式,最後轉交 Serverless Framework 部署 Reader。

github actions: deploy-to-aws:deploy-reader

最後看看 Reader 部署:

這裏應該是本篇最簡單的部分了,先安裝 Python/Node.js 然後再安裝 Serverless Framework 跟相依套件, serverless deploy 就能部署了。

要注意的只有兩點:

  • 這次用 Serverless Framework 部署 Python 的應用,因此需要 Python 相依性來安裝 requirements.txt
  • github actions 內的環境用 npm install -g 安裝套件依然會找不到,因此這邊直接 install 後進 node_modules/.bin 找。

結語

到此為止我們總算是建立完整的漫畫爬蟲與閱讀器的完整 CI/CD 流程了。雖然簡陋,並且各項工具的坑一個也沒少踩,我們也依然是活下來了。

雖然在正常的商用環境可能不會把爬蟲 AWS(Lambda, ECR, ApiGateway) Terraform, Github Actions 湊在一起,但那個尼采不是說過嗎?

「那些殺不死我們的,使我們更強大。」 — 尼采

也許作為一個工程師,不是別人虐你,就是自虐吧。

一個魯臭宅海藻這麼文青實在不好,還是拉回來吧。雖然我們的漫畫爬蟲系列算是到此完結,但這遠遠不代表我們中間所用到的技術就這點程度,還願有興趣的讀者繼續挖掘,最好還回饋本藻一下。不說廢話了,讓我們期待下個系列再會吧。

--

--

Seaweed

最大的才能是行光合作用,朋友是矽藻的海藻。