DevOps課程-IaC with Terraform 15
我們會有許多CASE,需要在建置機台後
執行的指令或是Shell Script(如下圖前篇過程中完成的部分):
在如圖中的user_data區塊中放入initial的資料
大部分的公有雲(AWS,GCP,Azure,等等都有支援到user_data區塊)
來執行初始化的命令
但是其實Terraform在請AWS執行完EC2機台建立後
AWS還傳EC2建立成功給Terraform
隨後AWS再接著執行user_data區塊的初始化工作
這時候Terraform的工作即已經"正常"結束
Terraform並不會曉得是否"user_data區塊"內容執行是否成功!
簡言之:
Terraform沒有機制控制"user_data區塊"執行狀況
所以就算"user_data區塊"執行上有失敗的狀況,Terraform並不會知道!
但是有些provisioner有提供解法
這邊先將當前的git branch切換到另一個 →feature/provisioners
#執行指令切換branch:
git checkout -b feature/provisioners
開始撰寫以下Code:
上述增加的provisioner "remote-exec"區塊
就是供應商允許我們在"機台建置後"連線到遠端機台執行指令
裡面寫法可以如下:
但是還需要定義該連線的方式:
而前篇完成的"user_data區塊"是直接將資料拋給AWS執行:
這邊provisioner “remote-exec”區塊則明確定義了是ssh連線方式執行命令
其相關解說可以在以下官方doc內找到:
這邊Code完成後就先執行plan指令看看:
執行apply最後看到:
同理也可以執行script檔案,但是首先需要將檔案拋到遠端機台上
所以Code改為如下:
對於多台機台的環境,在provisioner區塊內可以有自己的connection區塊
類似如下寫法:
但是這邊不需要,所以還原:
上面總共講解了兩個provisioner區塊(file,remote-exec)
接著介紹另一個provisioner區塊 →(local-exec)
第三整provisioner區塊範例寫法如下:
基本上就會有許多的應用,例如應用程式的安裝,建置等等
Provisioners are not recommended by Terraform
基本上就是不建議使用Provisioner
簡單來說Provisioner可能仍有很難控制的遠端指令執行過程
如果足夠,可能使用user_data區塊就好了
並且Provisioner則有"Breaks idempotency concept"(打破等冪性)
這邊的等冪性亦即不管執行幾次都有一樣結果(Output)
透過Provisioner中的remote-exec來執行shell script就不一定保證有等冪性
因為Terraform並不會知曉script內容做了啥
且也會打破current-desired state comparison(比較)
種種都違反了Terraform設計原則
而對於有這方面需求,真正建議的執行方式是 :
使用其他的Configuration工具(例如Ansible,puppet,CHEF…etc)
待Terraform執行完provisioned後,轉向執行這類其他工具
另外provisioner區塊(local-exec)也建議轉用如下local provider的部分
如上圖的local_file專門處理本機端檔案,裡面包含比較完整的對照能力
能確保變更異動(這樣也比較符合Terraform的設計)
單針對機台建置後執行script,如果整個是透過CI/CD工具如Jenkins執行
也建議乾脆將script執行交給Jenkins來做
Provisioner Failure
直接實驗如下:
直接執行apply指令:
看起來對Terraform來說我這樣不算有變更
但是用plan指令有看到:
最後發現其實會執行不了
參考doc應該還是要這樣執行:
但是講師那邊是會有以下畫面錯誤:
這邊恢復成如doc的範例Code後整理如下(main.tf):
terraform.tfvars內容:
並且嘗試移除後重建確認可以執行:
但是在apply時看起來已經建好nginx容器,但是一直結束不了:
後面就ctrl+c結束:
看起來真的不太容易用provisioner,也不少人有類似問題:
事後我就把目前的resource執行
terraform destroy