《Terraform 101 從入門到實踐》這本小冊在南瓜慢說官方網站和GitHub兩個地方同步更新,書中的範例程式碼也是放在GitHub上,方便大家參考檢視。
初聞不知Terraform,再聞已是雲中人。
在以前,當我們需要把應用部署在伺服器時,需要購買多臺伺服器和機房、組裝交換機和網路、不間斷電源UPS等。隨著雲時代的到來,我們可以在IaaS(Infrastructure as a Service)平臺直接購買所有的基礎設施,包括伺服器、專用網路、DNS、負載均衡等,而你只需要專注於應用層面即可。
IaaS(Infrastructure as a Service)的意思是基礎設施即服務,它是雲服務的基礎。著名的IaaS廠商有亞馬遜、微軟、谷歌和阿里雲等。
雲廠商為我們解決了許多運維問題:我們不再需要自己管理物理機器,而且能夠根據需要隨時建立和銷燬雲機器,還能根據業務和效能要求指定建立伺服器的設定和數量。這種便利對於創業型的小公司和個人開發者尤其重要。
隨時公司業務的良好發展,所需要的硬體資源越來越多,架構越來越複雜。通過介面操作手工建立伺服器、資料庫等資源的方式帶來越來越多的問題。首先,只要是人工操作,都會有失誤的可能,沒有人能保證自己不會犯錯;而人工操作在軟體行業發生事故的案例屢見不鮮。其次,為保證正確率,人工操作一般只能序列,資源多的時候時間會很長。最後,如果我需要根據開發環境的設定再建立一個測試環境和生產環境,人工操作可能會造成差異和錯誤。
因此,對於這種複雜需要,最佳的方式是通過程式碼來建立所有硬體資源。這種思想就是基礎設施即程式碼(Infrastructure as Code,很簡稱IaC),通過程式碼與定義、部署、更新和銷燬基礎設施。把硬體對映為軟體,而開發和運維人員通過管理程式碼來管理硬體。
IaC的好處有:
最終,實現快速安全地應用部署交付(Devivery)。
在IaC這方面的優秀工具還是非常多的,而且不同的工具完成不同的職責,下面列出一些比較常見的工具:
圖示 | 工具名 | GitHub STAR數 |
---|---|---|
Ansible | 50.9k | |
Terraform | 30.2k | |
Vagrant | 23k | |
Chef | 6.8k | |
Puppet | 6.4k | |
AWS CloudFormation | ||
Azure Resource Manager | ||
Google Cloud Deployment Manager |
其中,Ansible在設定自動化應該是領頭羊的地位。而Terraform則在服務開通上的事實標準。這裡並不想給各個工具做具體介紹,感興趣的可以去官網或GitHub瞭解。
注:有些文章或書籍會把Docker和Kubernetes也列為IaC工具,它們的主要職責是在容器與服務編排方面。
我們的主角Terraform終於登場了。它是由HashiCorp公司研發的開源的IaC工具,它是由GO語言編寫的,可以在各個平臺上執行,支援Linux、Mac、Windows等。它簡單易用,即使沒有太多程式碼經驗的人,也能讀懂Terraform的設定程式碼HCL。
HCL,即HashiCorp Configuration Language,是HashiCorp公司開發的設定語言。後續我們會介紹一些常用語法。
Terraform是一個安全高效的用於對基礎設施進行建立和變更且進行版本控制的工具。它支援私有云和公有云,如AWS、Azure、GCP和阿里雲等。它的官方網站為https://www.terraform.io。
主要特性有:
截至2021年12月02日,Terraform的最新版本為1.0.11,而它在2021年6月8日才正式釋出1.0.0版本。可見Terraform是如此年輕且有活力。而在Terraform還不是1.0.0版本的時候,已經有大量公司在生產環境上使用了。
Terraform是一個由Go語言編寫的程式,它會讀取HCL語言編寫的組態檔,然後將變更資訊通過RPC與外掛通訊,由外掛呼叫雲廠商的API完成變更操作。這就是Terraform的工作原理,架構圖如下:
Terraform core:Terraform的核心元件,類似於指揮官,負責解析設定、管理狀態、模組等核心功能。
外掛Plugin:完成具體變更的元件,因為Terraform支援多種平臺,它並沒有把對所有平臺的支援都放到核心元件中實現,而是通過外掛的方式來提供這些功能。需要對接什麼平臺,就加入什麼平臺的外掛,非常方面。
模組module:可以將完成特定功能的HCL封裝成一個模組,以實現程式碼複用。類似於其它程式語言中的函數或方法。有入參和出參,一切都可自定義。
狀態state:狀態存在專門的狀態檔案裡,它是作用是記錄實際基礎設施的狀態。當再次執行變更請求時,Terraform會讀取狀態檔案,判斷是否真的需要變更實際的基礎設施。如果狀態檔案記錄的狀態與HCL描述的一致,就不用再執行變更操作了。
Terraform就是一個二進位制的程式,只要下載並新增到PATH中去就可以了。各個系統的安裝方式沒有太大差異。這裡以Mac系統為例,做個簡單介紹。
下載程式:
可以直接到官網介面(https://www.terraform.io/downloads.html)去下載,請根據自己的系統選擇對應的檔案:
下載後進行解壓,並將該程式新增到環境變數中。
比如我的Terraform放在路徑/Users/larry/Software/terraform中,則新增到環境變數的命令如下:
export PATH=$PATH:/Users/larry/Software/terraform
為了讓它一直生效,我把上面命令放在home目錄下的.bash_profile檔案中。
檢查是否安裝成功如下:
$ terraform version
Terraform v1.0.11
on darwin_amd64
如果在純終端的環境下,也可以通過命令進行下載和解壓,命令如下:
# 下載安裝包
$ wget https://releases.hashicorp.com/terraform/1.0.11/terraform_1.0.11_darwin_amd64.zip
# 解壓
$ unzip terraform_1.0.11_darwin_amd64.zip
Terraform的主要應用場景是雲服務的基礎設施管理,但為了讓大家能快速的接觸與體驗Terraform,我會先選擇最簡單的一個外掛來入門,以免需要太多的環境設定。我們的任務是建立一個文字檔案,內容由我們來指定。可以通過外掛hashicorp/local來完成。
在當前目錄建立一個main.tf檔案,完整的程式碼如下:
terraform {
required_version = "= v1.0.11"
required_providers {
local = {
source = "hashicorp/local"
version = "= 2.1.0"
}
}
}
resource "local_file" "terraform-introduction" {
content = "Hi guys, this the tutorial of Terraform from pkslow.com"
filename = "${path.module}/terraform-introduction-by-pkslow.txt"
}
然後執行下面命令:
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/local versions matching "2.1.0"...
- Installing hashicorp/local v2.1.0...
- Installed hashicorp/local v2.1.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
看命令的輸出結果可以知道,Terraform會自動幫我們去下載對應版本的外掛hashicorp/local,並做一些初始化的操作。
接著我們通過命令terraform plan
來檢視將要執行的變更計劃:
$ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# local_file.terraform-introduction will be created
+ resource "local_file" "terraform-introduction" {
+ content = "Hi guys, this the tutorial of Terraform from pkslow.com"
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "./terraform-introduction-by-pkslow.txt"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
輸出紀錄檔中會提示需要建立、改變和銷燬多少資源。
Plan: 1 to add, 0 to change, 0 to destroy
這裡表示會建立一個資源。
廢話少說,我們直接執行變更:
$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# local_file.terraform-introduction will be created
+ resource "local_file" "terraform-introduction" {
+ content = "Hi guys, this the tutorial of Terraform from pkslow.com"
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "./terraform-introduction-by-pkslow.txt"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
會讓你確認是否執行變更,如果是,則輸入yes。我們直接輸入yes並按回車。
Enter a value: yes
local_file.terraform-introduction: Creating...
local_file.terraform-introduction: Creation complete after 0s [id=f63c7933c953ea2d03820d1ec35a80c718bd4777]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
成功執行,建立了檔案。
$ ls -l
total 24
-rw-r--r-- 1 larry staff 344 Dec 3 00:01 main.tf
-rwxr-xr-x 1 larry staff 55 Dec 3 00:13 terraform-introduction-by-pkslow.txt
-rw-r--r-- 1 larry staff 921 Dec 3 00:13 terraform.tfstate
上面還有一個tfstate檔案,是用來記錄狀態的,以後會詳細講這塊內容。
檢視一下檔案內容:
$ cat terraform-introduction-by-pkslow.txt
Hi guys, this the tutorial of Terraform from pkslow.com
與我們預期的內容一致。
如果再次執行apply會不會再次建立一個檔案呢?還是建立失敗,因為檔案已存在?
帶著這樣的問題,我們再執行一次:
$ terraform apply
local_file.terraform-introduction: Refreshing state... [id=f63c7933c953ea2d03820d1ec35a80c718bd4777]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
發現提示不需要變更,不會執行任何操作。
大家可以思考一下為什麼,答案會在後面章節揭曉。
現在我不需要這個檔案呢,通過destroy命令可以刪除:
$ terraform destroy
local_file.terraform-introduction: Refreshing state... [id=f63c7933c953ea2d03820d1ec35a80c718bd4777]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# local_file.terraform-introduction will be destroyed
- resource "local_file" "terraform-introduction" {
- content = "Hi guys, this the tutorial of Terraform from pkslow.com" -> null
- directory_permission = "0777" -> null
- file_permission = "0777" -> null
- filename = "./terraform-introduction-by-pkslow.txt" -> null
- id = "f63c7933c953ea2d03820d1ec35a80c718bd4777" -> null
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
local_file.terraform-introduction: Destroying... [id=f63c7933c953ea2d03820d1ec35a80c718bd4777]
local_file.terraform-introduction: Destruction complete after 0s
Destroy complete! Resources: 1 destroyed.
一樣需要你確認是否真的需要刪除,輸入yes回車即可。
到這裡,就已經真正地帶大家體驗了一下Terraform是如何工作的,介紹了它的整個流程,也就是Terraform官網所說的Write, Plan, Apply。希望大家能真正動手實踐,包括後續的實驗,這跟學程式語言是一樣的。
最後,對於本次實驗我想提幾點:
-auto-approve
即可。