前言
OpenTofu 是 Terraform 開源的替代方案。
Hashicorp 的 Terraform 從 v1.6 將 license 從 MPL 改為 BUSL,The Linux Foundation 從 MPL 版本的 Terraform Fork 出來繼續維護保持開源。
至於為什麼叫做 Tofu,應該是取自於 OpenTF 的 TF 吧1
安裝
# macOS
brew install opentofu
# Fedora
dnf install opentofu
# Snapcraft
snap install --classic opentofu工作目錄
工作目錄主要包含以下東西:
.terraform資料夾- 自動產生、自動維護的
- 存放 provider plugins 和 modules 快取
- 紀錄哪一個 workspace 是 active
- 紀錄最新的 backend configuration,知道下一次 migrate 要做什麼
- OpenTofu configuration,也就是
.tf檔案 - 狀態資料
核心流程
- Write:撰寫 IaC
- Plan:預覽 IaC 會造成的變更
- Apply:部屬基礎設施(reproducible infrastructure)
Write
撰寫一個 .tf 檔案,並且使用 init 初始化
# Write initial config
$ touch main.tf
$ vim main.tf
# Initialize OpenTofu
$ tofu initInitialization
tofu init 主要會做以下事情:
使用時機:
- 建立新專案,寫完
.tf後 - 修改基礎設施後,且需要重新初始化時(Reinitialization)。只會做差異更新,不會全部重新來
tofu get只會下載設定檔需要的 Module,不做初始化相關的工作
Plan
在撰寫、編輯的過程中,可以重複使用 tofu plan,確認有沒有 syntax error,並預覽變更是否符合預期
Apply
執行 tofu apply 並不會直接套用設定,而是會再跟使用者確認一次即將改變的內容,這是最後一次機會 review 更動
成功執行完 tofu apply 會產生狀態資料
Destory
tofu destroy 是 tofu apply -destroy 的簡寫
tofu plan -destroy 可以預覽 destory 影響的資源
Input Variable
定義變數(Declaring)
先上範例:
variable "image_id" {
type = string
}
variable "availability_zone_names" {
type = list(string)
default = ["us-west-1a"]
}
variable "docker_ports" {
type = list(object({
internal = number
external = number
protocol = string
}))
default = [
{
internal = 8300
external = 8300
protocol = "tcp"
}
]
}Arguments:
type- 基本型態:
string、number、bool - 複合型態 (complex types):
list(<TYPE>)、set(<TYPE>)、map(<TYPE>)、object({<ATTR NAME> = <TYPE>, ... })、tuple([<TYPE>, ...])
- 基本型態:
default:預設值,讓變數成為 optionalvalidation:condition寫判斷式、error_message寫錯誤訊息sensitive:讓tofu plan和tofu apply不要顯示敏感變數
傳入變數
能透過以下方式傳入變數:
- variable file:
.tfvars或.tfvars.json- OpenTofu 會自動尋找
terraform.tfvars、terraform.tfvars.json,或是檔名結尾是.auto.tfvars、.auto.tfvars.json的檔案 - 也可以手動指定位置:
tofu apply -var-file="testing.tfvars"
- OpenTofu 會自動尋找
- command line:
-var或-var-file
tofu apply -var="image_id=ami-abc123"
tofu apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
tofu apply -var='image_id_map={"us-east-1":"ami-abc123","us-east-2":"ami-def456"}'- environment variable:格式是
TF_VAR_name,如:VAR1=VALUE1⇒TF_VAR_VAR1=VALUE1
Output Variable
用途:
- 執行完
tofu apply後顯示的內容 - 後續使用
tofu output查詢內容 - 子模組 expose 資訊給父模組
定義輸出值
output "instance_ip_addr" {
value = aws_instance.server.private_ip
}Module
Module 是 Resource 的集合,也就是 .tf .tofu .tf.json .tofu.json 檔案們在一個資料夾中。
Module 可以來自本地端、git repo、HTTP
- Root Module
- Child Module
- Published Module
其他術語 (Glossary)
一些懶得紀錄,但一直出現的東西
Provider
Provider 是一個 Plugin (外掛程式),例如 AWS、Azure、GCP 等。每個 Provider 會有一組 resource type(資源類型) 和/或 data sources(資料來源)
Plugin
OpenTofu 透過稱為 Provider 的外掛程式管理各種類型的資源。Provider 是大多數使用者唯一會碰到的 Plugin。
tofu version 可以查看目前工作目錄安裝的 provider 版本,相關的指令還有:tofu providers 和 tofu providers schema
Resource
resource "<type>" "<name>" {
}Workspace
Backend
OpenTofu 預設使用 local 作為 backend,將 state 存在本地端
terraform {
backend "remote" {
organization = "example_corp"
workspaces {
name = "my-app-prod"
}
}
}- 一個 configuration 只會有一個 backend
- backend 中的值不能從 state 產出
State
狀態是一個很重要的檔案,確保 OpenTofu 可以正確的掌握資源的狀況,並依照此檔案進行資源(resource)的追蹤與維護。
狀態文件可以被存在遠端,如 S3,方便共同協作。若存在本機,則使用 terraform.tfstate 作為狀態文件。若專案是多個 workspace,則會去 terraform.tfstate.d 資料夾找。
可以透過 tofu show 查看目前狀態