初探 Terraform

何謂 Terraform ?

根據 IBM Cloud 學習中心的介紹,terraform 是一套宣告式編碼工具,他可以讓開發人員安全有效地建置與變更基礎架構並對其進行版本化,是知名軟體公司 hashicorp 的產品

類似的工具: pulumi


特色

  • 開放原始碼:Terraform 獲得大型貢獻者社群支援,他們為平台建置了外掛程式。 無論您使用哪一個雲端提供者,都可以輕鬆找到外掛程式、延伸及專業支援。 這也意味著 Terraform 發展迅速,不斷增加新的好處和改進。
  • 平台中立:表示您可以搭配它與任何 的雲端服務提供者一起使用。大部分其他的 IaC 工具都設計成與單一雲端提供者合作。
  • 不可變基礎架構:大部分的「基礎架構即程式碼(IaC)」工具會建立可變基礎架構,這表示基礎架構可進行變更以因應變動,例如中介軟體升級或新的儲存伺服器。 可變基礎架構的危險是配置漂移,隨著變更逐漸增多,實際佈建不同的伺服器或其他基礎架構元素將會進一步從原始配置「漂移」,使得錯誤或效能問題難以診斷及更正。 Terraform 佈建的是不可變基礎架構,這表示隨著環境每一次變更,將現行配置取代為因應變更的新配置,然後重新佈建基礎架構。 更棒的是,先前的配置可以保留為不同版本,以在必要或需要時啟用回復。

簡而言之,它具有 持續更新 通用性高 保持環境一制性 等優點

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

支援的 provider


安裝

在 mac 環境直接下

brew tap hashicorp/tap brew install hashicorp/tap/terraform

測試安裝結果

terraform version

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

(可選) 安裝 tab completion 功能

terraform -install-autocomplete

範例

這邊先簡單地以 docker 環境來說明

對 terraform 來說,每個plan都有一個最主要的定義檔案: main.tf

terraform { required_providers { // 宣告雲端提供者 docker = { source = "kreuzwerker/docker" version = "~> 2.13.0" } } } provider "docker" {} // 上面宣告的 雲端提供者 resource "docker_image" "nginx" { // 資源描述 : 映像檔 name = "nginx:latest" keep_locally = false // 設定 false,則之後 destroy 會把對應的 image 刪除 } resource "docker_container" "nginx" { // 資源描述 : 容器 image = docker_image.nginx.latest name = "tutorial" ports { internal = 80 external = 8087 } }

初始化 plan

terraform init

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

執行 plan

terraform apply

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

中間會遇到提問: Do you want to perform these actions?
輸入 yes

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

創建成功 看一下 container

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

更多範例


指令

terraform 常用指令

  • init : 初始化,新建立的 config 需要先跑這個指令
  • fmt : 自動將檔案格式化
  • validate : 檢查 config 是否正確
  • plan : 生成推測執行計劃,顯示將採取哪些操作來應用當前 config (實際上不會執行)
  • apply : 套用 config (相當於執行)
  • destroy : 清除配置

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
更多指令可以參考 terraform -h or terraform [COMMAND] -h


定義變數

terraform 支援變數輸入

variables.tf

variable "container_names" { description = "Create nginx containers with these names" type = list(string) default = ["nginx-1", "nginx-2", "nginx-3"] } variable "container_ports" { description = "Create nginx containers with these ports" type = list(number) default = [8081, 8082, 8083] }

main.tf

terraform { required_providers { docker = { source = "kreuzwerker/docker" version = "~> 2.13.0" } } } provider "docker" {} resource "docker_image" "nginx" { name = "nginx:latest" keep_locally = false } resource "docker_container" "nginx" { count = length(var.container_names) image = docker_image.nginx.latest name = var.container_names[count.index] ports { internal = 80 external = var.container_ports[count.index] } }

length() 是一個回傳長度的函數,按上面的範例,它會回傳 variables.tf 裡面定義的 container_names 的長度

name = var.container_names[count.index],應該很好懂,讀取 variables.tfcontainer_names 的第 count.index 個參數

套用上面的配置的產出:

loop 範例

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
更多 variables 說明


GCP 實例

下面的範例會在 GCP 建立一台 VM 實例

main.tf

terraform { required_providers { google = { source = "hashicorp/google" version = "3.5.0" } } } provider "google" { project = "[PROJECT_ID]" region = "asia-east1" zone = "asia-east1-b" } resource "google_compute_instance" "default" { name = "test" machine_type = "f1-micro" zone = "asia-east1-b" labels = { // 標籤 "foo" = "bar" } tags = ["foo", "bar", "foo-bar"] // 網路標籤 boot_disk { initialize_params { image = "debian-cloud/debian-9" // os 映像檔版本 } } network_interface { subnetwork_project = "[VPC_PROJECT_NAME]" subnetwork = "[SUBNETWORK_NAME]" network_ip = "[SPECIFIC_IP]" // 指定 VM IP ,省略的話會自動分配 access_config { // 外部訪問設定,建議省略,可確保無法從外網訪問該實例 } } metadata = { // 其他 例如 ssh key ssh-keys="[USER]:[PUBLIC_KEY]" } metadata_startup_script = "echo hi > /test.txt" // 開機腳本 非必要 }

更多設定參數

看一下執行結果

因為有建立 ssh key 所以成功透過 ssh 連上了

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
實驗結束記得用 destroy 清場


使用心得

雖然設定較複雜 需要一點學習成本 但是功能強大

對於有為數眾多 VM 要管理的專案來說 只需要寫好腳本就可以輕鬆的建立/修改/刪除機群

tags: docker container k8s terraform GCP