Terraform 知幾何?
Terraform 是一個 IT 基礎架構自動化編排工具,它的口號是 "Write, Plan, and create Infrastructure as Code", 基礎架構即代碼。具體的說就是可以用代碼來管理維護 IT 資源,比如針對 AWS,我們可以用它創建,修改,刪除 S3 Bucket, Lambda, EC2 實例,Kinesis, VPC 等各種資源。並且在真正運行之前可以看到執行計划(即干運行-dryrun)。由於狀態保存到文件中,因此能夠離線方式查看資源情況 -- 當然,前提是不要在 Terraform 之外對資源進行修改。
Terraform 配置的狀態除了能夠保存在本地文件中,也可以保存到 Consul, S3, azure, http, swift 等處。
Terraform 是一個高度可擴展的工具,通過 Provider 來支持新的基礎架構,AWS 不過為目前官方內建 68 個 Providers 中的一個。其他能用 Terraform 的地方有 Alicloud(阿里雲, 實名制備案才能用), Google Cloud, Heroku, Kubernetes, Microsoft Azure, MySQL, RabbitMQ, Docker 等等。願意的話可以寫自己的 Provider, 如搞個 Kafka 的話,用來管理 Topic 等的創建,維護工作。
Terraform 之前我們對 AWS 的操作用的是 awscli, 或 Serverless。awscli 什么都能做,但它是無狀態的,必須明確用不同的命令來創建,修改和刪除。Serverless 不是用來管理基礎架構的,用它創建 Lambda 時創建資源都是很麻煩的事。AWS 提供的 CloudFormation 才是與 Terraform 較類似的工具,但是看到用法就頭疼。
下面從最簡單例子開始,看看怎么用 Terraform 創建,刪改,修改 S3 Bucket。
- Terraform 安裝
Linux操作系統安裝:
# 安裝依賴工具
sudo yum install wget unzip
# 下載terraform並安裝terraform
wget https://releases.hashicorp.com/terraform/0.11.10/terraform_0.11.10_linux_amd64.zip
unzip terraform_0.11.10_linux_amd64.zip
mv terraform /usr/local/bin/
Mac操作系統安裝:
brew install terraform
安裝后 shell 命令就是 terraform, 常用的是 terraform init, terraform plan, terraform apply
- 創建配置文件
像 git 一樣,每個 Terraform 項目需要自己單獨的目錄空間,所以我們創建一個 terraform-learning 目錄
mkdir terraform-learning
cd terraform-learning
該目錄下的所有 *.tf 文件都會被 Terraform 加載,在初始化 Terraform 工作空間之前必須至少要有一個 *.tf 文件。我們這里建立文件 main.tf, 內容如下
Terraform 配置的語法是該公司 HashiCorp 獨創的 HCL(HashiCorp configuration language), 它可以兼容 JSON 格式。
上面 tf 文件在 Vim 中的語法加亮是安裝的 hashivim/vim-terraform 插件。
我們寫好了 *.tf 文件后可以調用 terraform fmt 對配置文件進行格式化,它比較喜歡被 Java 棄用的等號對齊的格式。
- 配置文件介紹
從正式跨入 terraform 命令正題之前先來大概的介紹一下上面那個 main.tf 文件。
- provider "aws" 部分,它指定選用什么 provider, 以及驗證信息。aws 既允許指定 access_key 和 secret_key
provider "aws" {
region = "us-east-1"
access_key = "your-access-key-here"
secret_key = "your-secret-key-here"
}
也能夠指定證書文件中的 profile
provider "aws" {
region = "us-east-1"
shared_credentials_file = "~/.aws/credentials" //不指定的話,默認值是 "~/.aws/credentials"
profile = "yanbin" //不指定的話,默認值是 "default"
}
如果是使用 shared_credentials_file 中的 profile, 請確定您以預先生成好的 credentials 文件及有效的 profile。
更多關於 AWS Provider 的配置請參考 https://www.terraform.io/docs/providers/aws/index.html
2) resource "aws_s3_bucket" "s3_bucket" 部分
這只是我們今天舉的一個小例子,點擊鏈接 aws_s3_bucket 查看 S3 Bucket 所有的配置項。Terraform 能夠管理的所有 AWS 資源也能從前面那個鏈接中看到。
如果 bucket yanbin-test-bucket 不存在的話,運行 terraform apply 將會創建它,否則試圖更新該 bucket。此例子只指定了 bucket 的 acl 和 tag 信息。terraform destroy 用來刪除已存在的 bucket。
注意:terraform 配置文件中只指定要管理的資源對象,並不關心操作資源的行為--創建,修改,刪除操作。操作行為與 Terraform 的狀態有關系,無則創建,有則修改,更名會拆分為除舊立新兩個操作,terraform destroy 用於顯式刪除資源。后面實例操作時會講到。
注:resource "aws_s3_bucket" "s3_bucket" { 中,resource 后第一個是 type, 即資源名,第二個參是 name。其實 "s3_bucket" 在這里沒什么用,只是一個描述或助記符而已。(2017-08-28): 更正一下,在作為變量引用的時候就要用到它,例如在后面要為 Lambda 創建一個 S3 Event 的 Trigger, 就要寫成 event_source_arn = "${aws_s3_bucket.s3_bucket.arn}", 引用時不需要知道實際的名稱。
- 初始化工作目錄
在初始化 Terraform 工作目錄之前, 其他命令如 apply, plan 多是不可用的,提示需要初始化工作目錄,命令是
terraform init
它要做的事情像是 git init 加上 npm install,執行完了 terraform init 之后會在當前目錄中生成 .terraform 目錄,並依照 *.tf 文件中的配置下載相應的插件。
- 執行 Terraform 管理命令
有了前面的准備之后,終於可以開始運行 Terraform 的管理命令了。Terraform 在正式執行之前提供了預覽執行計划的機會,讓我們清楚的了解將要做什么
terraform plan
由此計划還能知道關於 aws_s3_bucket 有些什么配置項,比如配置中可以加上 acceleration_status = "Enabled"
terraform apply
這樣便在 AWS 上創建了一個 S3 bucket "yanbin-test-bucket", 同時會在當前目錄中生成一個狀態文件 terraform.tfstate, 它是一個標准的 JSON 文件。這個文件對 Terraform 來說很重要,它會影響 terraform plan 的決策,雖然不會影響到實際的執行效果。我們可以把它存到遠端,如 S3 或 Consul。terraform state [list|mv|pull|push|rm|show] 用來操作狀態文件。
此時什么也不改,再次執行 terraform plan, 會顯示沒什么要做的
aws_s3_bucket.s3_bucket: Refreshing state... (ID: yanbin-test-bucket)
No changes. Infrastructure is up-to-date.
如果對 main.tf 作點小改,改個 tag 屬性,再次 terraform plan
~ aws_s3_bucket.s3_bucket
tags.Name: "Created by Terraform" => "sCreated by Terraform"
Plan: 0 to add, 1 to change, 0 to destroy.
為什么說 terraform plan 是基於狀態文件 terraform.tfstate 作出的呢?我們可以刪除這個狀態文件,然后執行 terraform plan 看看
+ aws_s3_bucket.s3_bucket
.....
bucket: "yanbin-test-bucket"
......
tags.Environment: "QA"
......
Plan: 1 to add, 0 to change, 0 to destroy.
Terraform 由於缺乏 terraform.tfstate 對比,所以認為是要添加一個 bucket, 但是實際執行 terraform apply 時,連接到遠端 AWS, 發現該 bucket 已存在就只是進行更新。terraform apply 總能給出正確的操作結果。同理如果狀態文件中說有那個 bucket, terraform plan 會說是更新,但 AWS 沒有那個 bucket,實際執行 terraform apply 也會進行添加的。
資源更名
如果把 main.tf 中的
bucket = "yanbin-test-bucket"
改成
bucket = "yanbin-test-bucket-rename"
即欲為 bucket 更名,用 terraform plan 看下計划
實際上 terraform apply 也是先刪除舊的,再創建新的。Terraform 像 git 一樣用不同顏色和 +/- 號來顯示變動操作
最后是 terraform destroy 命令,把 *.tf 文件中配置的所有資源從 AWS 上清理掉。
- Terraform 工作目錄中文件命名
Terraform 運行時會讀取工作目錄中所有的 *.tf, *.tfvars 文件,所以我們不必把所有的東西都寫在單個文件中去,應按職責分列在不同的文件中,例如:
provider.tf -- provider 配置
terraform.tfvars -- 配置 provider 要用到的變量
varable.tf -- 通用變量
resource.tf -- 資源定義
data.tf -- 包文件定義
output.tf -- 輸出
以此篇最簡單的入門出發,以后可以深入了解 Lambda, Lambda 觸發器,及 API Gateway, EC2 實例怎么用 Terraform 來管理,也知曉了資源的可用屬性應該到哪里去查。
vpc123的小提示:在執行像 terraform plan 或 terraform apply 等命令的時候,可以按下 ctrl + c 讓控制台輸出詳細的日志信息。