Circle CI run Terraform and AWS deployment

最近花很多時間在 CI,其中一個比較大的目標是跑 Terraform 加上用它輸出的 S3 name 來作為後面發佈步驟的發佈目標,然後加上不想要用第三方的 docker image 和 orbs,不過網路上都沒看到有這樣子做的範例,所以花了些時間嘗試、看文件和範例,這篇就是把一些目前的結論記錄下來:

Terraform 是用 hashicorp 官方的 image,基本上就是 alpine + go + terraform 而已,shell 只有 sh 沒有 bash,不過其實 Circle CI 的一些文件看起來,他們應該是建議要使用 bash 為主,其中一個主要原因就是 BASH_ENV 這個環境變數有沒有支援,支援的話就可以很輕鬆的在不同 command 間傳遞環境變數了,不過還好我在 Terraform 這邊只需要寫入,還不需要讀出,所以就是 Terraform 執行完之後加一個 command 執行:

echo "export S3_ID=`terraform output s3_bucket_name`" >> $BASH_ENV

當然你的 terraform module 要有定義好 output。

第二個是重點是$BASH_ENV的值,個人建議是設定絕對路徑,直接寫出完整路徑,不要用其它環境變數來組合,然後位置要放在 working directory 內,好方便能persist_to_workspace,這樣才能夠跨 job 使用,另外就是檔名建議不要用.開頭的隱藏檔名,我遇到過各種找不到檔案的錯誤訊息,然後 working directory 建議不要放在 home 目錄下,一來$BASH_ENV去用$HOME組合出來我遇到錯誤過,用~來寫路徑也是遇到錯誤過,二來不同 image 的 home 目錄路徑不同,如果要在 config 內直接寫死絕對路徑,建議直接定一個固定的位置,我現在是用:

/tmp/workspace

然後這樣後面就可以用官方的 s3 orb 下指令了:

- aws-s3/sync:
    from: build
    to: "s3://${S3_ID}"
    aws-region: "ap-northeast-1"