# 初探 Terraform ## 何謂 Terraform ? 根據 [IBM Cloud 學習中心](https://www.ibm.com/tw-zh/cloud/learn/terraform)的介紹,terraform 是一套宣告式編碼工具,他可以讓開發人員安全有效地建置與變更基礎架構並對其進行版本化,是知名軟體公司 [hashicorp](https://www.hashicorp.com/) 的產品 >類似的工具: [pulumi](https://www.pulumi.com/) --- ## 特色 * 開放原始碼:Terraform 獲得大型貢獻者社群支援,他們為平台建置了外掛程式。 無論您使用哪一個雲端提供者,都可以輕鬆找到外掛程式、延伸及專業支援。 這也意味著 Terraform 發展迅速,不斷增加新的好處和改進。 * 平台中立:表示您可以搭配它與任何 的雲端服務提供者一起使用。大部分其他的 IaC 工具都設計成與單一雲端提供者合作。 * 不可變基礎架構:大部分的「基礎架構即程式碼(IaC)」工具會建立可變==基礎架構==,這表示基礎架構可進行變更以因應變動,例如中介軟體升級或新的儲存伺服器。 可變基礎架構的危險是配置漂移,隨著變更逐漸增多,實際佈建不同的伺服器或其他基礎架構元素將會進一步從原始配置「漂移」,使得錯誤或效能問題難以診斷及更正。 Terraform 佈建的是不可變基礎架構,這表示隨著環境每一次變更,將現行配置取代為因應變更的新配置,然後重新佈建基礎架構。 更棒的是,先前的配置可以保留為不同版本,以在必要或需要時啟用回復。 簡而言之,它具有 ==持續更新== ==通用性高== ==保持環境一制性== 等優點  支援的 provider --- ## 安裝 在 mac 環境直接下 ```shell= brew tap hashicorp/tap brew install hashicorp/tap/terraform ``` 測試安裝結果 ```shell= terraform version ```  (可選) 安裝 tab completion 功能 ```shell= terraform -install-autocomplete ``` --- ## 範例 這邊先簡單地以 `docker` 環境來說明 對 terraform 來說,每個==plan==都有一個最主要的定義檔案: main.tf ```terraform= 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 ```shell= terraform init ```  執行 plan ```shell= terraform apply ```  中間會遇到提問: `Do you want to perform these actions?` 輸入 `yes`  創建成功 看一下 container  >更多[範例](https://learn.hashicorp.com/terraform?utm_source=terraform_io&utm_content=terraform_io_hero) --- ## 指令 terraform 常用指令 * init : 初始化,新建立的 config 需要先跑這個指令 * fmt : 自動將檔案格式化 * validate : 檢查 config 是否正確 * plan : 生成推測執行計劃,顯示將採取哪些操作來應用當前 config (實際上不會執行) * apply : 套用 config (相當於執行) * destroy : 清除配置 :::info :musical_note: 更多指令可以參考 `terraform -h` or `terraform [COMMAND] -h` ::: --- ## 定義變數 terraform 支援變數輸入 variables.tf ```terraform= 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= 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.tf` 中 `container_names` 的第 `count.index` 個參數 套用上面的配置的產出:  > loop [範例](https://www.bogotobogo.com/DevOps/Terraform/Terraform-Introduction-AWS-loops.php) :::warning :musical_note: 更多 variables [說明](https://learn.hashicorp.com/tutorials/terraform/variables?in=terraform/configuration-language) ::: --- ## GCP 實例 下面的範例會在 GCP 建立一台 VM 實例 main.tf ```terraform= 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" // 開機腳本 非必要 } ``` >更多設定[參數](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance) 看一下執行結果  因為有建立 ssh key 所以成功透過 ssh 連上了  :::warning :warning: 實驗結束記得用 `destroy` 清場 ::: --- ## 使用心得 雖然設定較複雜 需要一點學習成本 但是功能強大 對於有為數眾多 VM 要管理的專案來說 只需要寫好腳本就可以輕鬆的建立/修改/刪除機群 ###### tags: `docker` `container` `k8s` `terraform` `GCP`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up