關於我想看漫畫卻不想看廣告這檔事 (15) — 使用 Terraform 佈署 AWS ECR + AWS Lambda

Seaweed
6 min readOct 8, 2021

--

前一晚一切正常的爬蟲…

今天起床就炸裂了…

我們永遠沒辦法預知 Lambda 中的爬蟲會發生什麼。這是個大坑,慎入。

本篇程式碼

AWS ECR + Lambda 佈署介紹

在這裡我們會介紹 AWS Lambda 的另外一種佈署方法,也就是「直接讓 Lambda 載入一個容器映像」,比起之前單純插入程式碼給 Lambda 執行的方式,這個方法能夠更加彈性地配置 Lambda 的執行環境(比如裝一些外部 lib/binary 甚至是 runtim),這項特性對於爬蟲也是至關重要(畢竟相依性特別多)。

最後會生出一個透過 cloudwatch 被定時啟動的 Lambda 以及作為 Lambda 執行環境的容器映像(ecr)。實際配置時會用到 AWS ECR 這個服務,相關介紹可以看以下:

佈署流程上,首先把 docker build 完成的映像檔上傳到 ECR,接著讓 Lambda 從 ECR 載入映像便完成,使用上應該算方便。

目前 AWS Lambda 能夠載入的容器映像仍僅限 AWS ECR 的付費私有映像,本藻也不知道為什麼公開免費的不給用…

不過雖然載入還算方便,但主要的問題是如何準備 Lambda 可用的映像。AWS 有準備能用的 base image,並且也強烈建議使用它,否則光是一些預載的 script 或環境變數就可以搞死人了。

不過關於 base image 的選定,可以看看官網,挑一個適合的就行了:

各自的使用方法都寫在專有頁面的 usage 裏:

不過通常也就如上圖單純用 FROM 跟 CMD

除此之外,自己建立映像讓 Lambda 載入相對於單純插入程式碼還會遇到一大堆問題,這邊也沒辦法先列舉,總之為了避免之後連錯誤輸出都看不到,建議開發時盡量留下 log 然後輸出到 cloudwatch 吧。

佈署程式碼

總之接著就是直接來看關鍵的程式碼。

首先是建立映像用的 Dockerfile:

其實也沒什麼,就是記得用上面提到的 base image。另外這裡的 CMD [ "lambda_main.handler"] 算是慣用用法,就是 AWS 中可以設定的程式進入點,格式是 檔案名(去掉.py).進入點函式

接著是部署 AWS Lambda 的 terraform 程式:

內容上基本上就是部署五個資源:

  • aws_lambda_function: Lambda 本體
  • aws_iam_role: 佈署 Lambda 時必要的 role(一定要有,但權限不限)
  • aws_cloudwatch_event_rule: 用於定時啟動的規則本體
  • aws_cloudwatch_event_target: 綁定定時啟動規則與要啟動的 Lambda(用 arn 綁定 Lambda)
  • aws_lambda_permission: 給予剛才建立的 aws_cloudwatch_event_rule 啟動剛剛建立的 Lambda 的權限

到目前為止我們就完成 Lambda 建立以及定時啟動了。若想要針對各個 resource 加深理解它們的用法可以參考官網

不過給 Lambda 載入的映像(image_uri 那串)還沒有完成,這裡接著介紹:

看程式碼就知道我們這裡用的是 AWS ECR,剛剛有提到。雖然有點長不過大部分都跟上傳 AWS ECR 前的權限認證有關,這邊一一介紹:

  • aws_caller_identity: 為之後登入 aws ecr 拿來取得帳號 id 用的
  • aws_ecr_image: 拿來取得「已上傳的 image」的相關資料用的 data,而這不是 resource
  • archive_file: 壓縮指定檔案,為了之後拿 hash 判定資料夾內容是否有變動
  • locals: 一堆變數,方便之後使用
  • aws_ecr_repository: 就是 image 的名字,之後可以直接在 web console 看到獨立頁面
  • null_resource: 主要進行映像檔建制與上傳至 ecr(詳細後續介紹)

null_resource

這裡可以分為 triggersprovisioner "local-exec" 兩個部分,前者用來告知 Terraform 重新執行的時機,如果 triggers 中的任一個值與上次執行的不同,那麼就會觸發重新佈署。provisioner "local-exec" 則是實際建置與上傳映像的地方,概要如下:

1. 透過 aws ecr get-login-password, docker login 登入 dockerhub(之後上傳的東西會同步在 ecr 上看到)
2. 以 docker build 建立映像
3. 以 docker push 上傳映像至 dockerhub,然後就能在 ecr 看到。

解說就到這裡,剩下就是把該補的設定值補到 terraform.tfvar 之後就能佈署了。

結語

這篇我們介紹了另外一種 Lambda 佈署的方法,順便附送 cloudwatch 定時啟動的實現。看似容易,實際上要讓自己建置好的容器映像在 Lambda 中正確運行是非常困難的一件事,佈署上去的東西如果沒有留下正確的 log 後續也沒辦法連線進去確認,更不可能重現,要更改測試也都必須通過重新佈署。

而接下來本藻為了把爬蟲搬上 Lambda 將會開始把各種東西(包含 Chrome)塞上這個映像,過程中會遇到一堆問題,有興趣的敬請持續關注吧。

下篇預告

實戰部署 chrome 至 Lambda,百雷的官方 image。

下篇傳送門↓

--

--

Seaweed

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