591
技術社區[雲棲]
雲生態下的基礎架構資源管理利器Terraform
About Terraform
Terraform (https://www.terraform.io/)是HashiCorp旗下的一款開源(Go語言開發)的DevOps 基礎架構資源管理運維工具,可以看下對應的DevOps工具鏈:
Terraform可以安全高效的構建、更改和合並多個雲廠商的各種服務資源,當前支持有阿裏雲、AWS、微軟Azure、Vmware、Google Cloud Platform等多個雲廠商雲產品的資源創建。
Write, Plan, and Create Infrastructure as Code
Terraform通過模板配置文件定義所有資源類型(有如主機,OS,存儲類型,中間件,網絡VPC,SLB,DB,Cache等)和資源的數量、規格類型、資源創建依賴關係,基於資源廠商的OpenAPI快速創建一鍵創建定義的資源列表,同時也支持資源的一鍵銷毀。
通過模板配置化的方式,我們可以得知整個資源關係,也可以做相應的資源版本化管理,甚至可以把該資源模板直接複製建立多可用區的服務,包括資源的彈性伸縮,可以說在提高運維自動化生產力上是一個絕好的利器。
這裏引用@簫竹 一次分享中提供的一個創建阿裏雲資源的Terraform產品介紹圖 :
最左邊欄通過一個main.tf文件(隻需要是*.tf 文件)定義了ECS(鏡像、實例類型)、VPC(CIDR、VPC Name)、OSS資源(ACL、實例Name)信息,通過Terraform 對資源配置參數做解析,調用阿裏cloud OpenAPI 進行資源校驗於創建,同時把整個資源創建狀態化到一個*.tf.state文件中,基於該文件則可以得知資源創建的所有信息,包括資源數量調整,規格調整,實例變更都依賴這種非常重要的文件。 具體後續綜合一些案例,比如Terraform 實現WordPress的一鍵自動化搭建,可以更好的理解該產品的執行過程。
下麵先講述下Terraform的安裝,模板配置文件的編寫,後續再專門寫幾個案例作為分享。
Install Terraform
Terraform 可以隨意部署在任意的C端上,隻要可以連通公網即可(Initializing provider plugins and Call Cloud OpenAPI)
通過 https://www.terraform.io/downloads.html 下載對應平台的可執行二進製包,解壓出來Executable Binary 放指定目錄,配置好相應的PATH則可使用terraform 指令。
wangzhipengs-MacBook-Pro:~ wangzhipeng$ which terraform
/usr/local/bin/terraform
wangzhipengs-MacBook-Pro:~ wangzhipeng$ terraform
Usage: terraform [--version] [--help] <command> [args]
The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.
Common commands:
apply Builds or changes infrastructure
console Interactive console for Terraform interpolations
destroy Destroy Terraform-managed infrastructure
env Workspace management
fmt Rewrites config files to canonical format
get Download and install modules for the configuration
graph Create a visual graph of Terraform resources
import Import existing infrastructure into Terraform
init Initialize a Terraform working directory
output Read an output from a state file
plan Generate and show an execution plan
providers Prints a tree of the providers used in the configuration
push Upload this Terraform module to Atlas to run
refresh Update local state file against real resources
show Inspect Terraform state or plan
taint Manually mark a resource for recreation
untaint Manually unmark a resource as tainted
validate Validates the Terraform files
version Prints the Terraform version
workspace Workspace management
All other commands:
debug Debug output management (experimental)
force-unlock Manually unlock the terraform state
state Advanced state management
這裏需要特別說明一下的是目前Terraform官網的版本隻支持阿裏cloud比較有效的幾個大產品的resource,因此如果要創建阿裏cloud多個resource需要引入阿裏cloud的provider:
https://github.com/alibaba/terraform-provider/releases
通過下載alicloud的provider binary (bin/terraform-provider-alicloud) 放置到Terraform的安裝目錄下。
Build Infrastructure
整個架構資源創建的過程,可以分成如下四部分:
通過一個*.tf 後綴的模板文件,描述指定廠商的所有資源配置信息,比如說創建一個alicloud ECS的模板配置:
# Configure the Alicloud Provider
provider "alicloud" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
# Create a web server
resource "alicloud_instance" "web" {
# cn-beijing
provider = "alicloud"
availability_zone = "cn-beijing-a"
image_id = "ubuntu_140405_32_40G_cloudinit_20161115.vhd"
internet_charge_type = "PayByBandwidth"
instance_type = "ecs.n1.medium"
io_optimized = "optimized"
system_disk_category = "cloud_efficiency"
security_groups = ["${alicloud_security_group.default.id}"]
instance_name = "web"
}
# Create security group
resource "alicloud_security_group" "default" {
name = "default"
provider = "alicloud"
description = "default"
}
# Output message
output "ecs instance name" {
value = "${alicloud_instance.web.instance_name}"
}
output "ecs private ip" {
value = "${alicloud_instance.web.private_ip}"
}
如上access_key,secret_key 填寫創建資源賬號的AK,該Config File涵蓋了Region,可用區,ECS鏡像,帶寬計費方式,實例規格,IO類型,存儲類型,安全組,實例名稱多個信息。
完成如上配置信息後,需要通過terraform init 做cloud provider plugins的初始化操作:
wangzhipengs-MacBook-Pro:terraform_dir wangzhipeng$ terraform init
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "alicloud" (0.1.0)...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.alicloud: version = "~> 0.1"
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目錄,保存有該平台下的provider可執行文件。
上麵信息也做了提示,我們可以running "terraform plan" 查看將要創建的資源信息:
wangzhipengs-MacBook-Pro:terraform_dir wangzhipeng$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ alicloud_instance.web
id: <computed>
allocate_public_ip: "false"
availability_zone: "cn-beijing-a"
host_name: <computed>
image_id: "ubuntu_140405_32_40G_cloudinit_20161115.vhd"
instance_name: "web"
instance_type: "ecs.n1.medium"
internet_charge_type: "PayByBandwidth"
io_optimized: "optimized"
private_ip: <computed>
public_ip: <computed>
security_groups.#: <computed>
status: <computed>
subnet_id: <computed>
system_disk_category: "cloud_efficiency"
system_disk_size: <computed>
+ alicloud_security_group.default
id: <computed>
description: "default"
name: "default"
Plan: 2 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
通過apply可以預覽模板對應創建2個資源,已經對應的屬性信息:
- alicloud_instance.web
- alicloud_security_group.default (該安全組暫時未設置自定義放行規則)
其中computed標識為暫時無法得知最終創建出來的信息,所以也可以理解成係統默認分配。
接下通過指令terraform apply執行資源創建:
``` wangzhipengs-MacBook-Pro:terraform_dir wangzhipeng$ terraform apply alicloud_security_group.default: Creating... description: "" => "default" name: "" => "default" alicloud_security_group.default: Creation complete after 1s (ID: sg-2zec9v8aq2hgb244qrqf) alicloud_instance.web: Creating... allocate_public_ip: "" => "false" availability_zone: "" => "cn-beijing-a" host_name: "" => "" image_id: "" => "ubuntu_140405_32_40G_cloudinit_20161115.vhd" instance_name: "" => "web" instance_type: "" => "ecs.n1.medium" internet_charge_type: "" => "PayByBandwidth" io_optimized: "" => "optimized" private_ip: "" => "" public_ip: "" => "" security_groups.#: "" => "1" security_groups.2344301974: "" => "sg-2zec9v8aq2hgb244qrqf" status: "" => "" subnet_id: "" => "" system_disk_category: "" => "cloud_efficiency" system_disk_size: "" => "" alicloud_instance.web: Still creating... (10s elapsed) alicloud_instance.web: Still creating... (20s elapsed) alicloud_instance.web: Still creating... (30s elapsed) alicloud_instance.web: Still creating... (40s elapsed) alicloud_instance.web: Still creating... (50s elapsed) alicloud_instance.web: Creation complete after 51s (ID: i-2zedvfowy4m39sg1xdig)
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
ecs instance name = web
ecs private ip = 10.31.28.93
分鍾級功夫該ECS就創建好了

## Input/Output Variables
回顧上麵通過Terraform 創建資源的過程,最關鍵的還是如何描述模板配置信息,這裏主要說明一下參數配置2個輸入輸出的變量實現。
Configure the Alicloud Provider
provider "alicloud" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
我們可以在當前文件,但最好另創建一個*.tf後綴結尾文件,存放對應的ak和region信息,這樣我們就可以把一些變量信息提取出來避免硬編碼,這對整個配置文件具備更好的可維護性:
wangzhipengs-MacBook-Pro:terraform_dir wangzhipeng$ cat variable.tf
variable "access_key" {
default = "xxx"
}
variable "secret_key" {
default = "xxx"
}
variable "region" {
default = "cn-beijing"
}
此外,如上配置指定了output的變量信息,本身如果不指定output的內容也不影響整個資源創建的過程,但通過輸出output的信息可以徹底脫離控製台,對於如下的output變量信息也可以存放在另一個*.tf後綴文件,對於resource的輸出變量可以參閱每個provider resource的attribute信息。
Output message
output "ecs instance name" {
value = "${alicloud_instance.web.instance_name}"
}
output "ecs private ip" {
value = "${alicloud_instance.web.private_ip}"
}
## Destroy Infrastructure
資源使用後如果想要釋放,以往通過控製台,往往需要存在資源依賴,導致資源釋放的時候需要先釋放被依賴的資源,所以整個資源釋放的過程還是比較繁瑣的,甚至可能存在忘記釋放個別資源造成資源浪費,Terraform通過指令terraform destroy 可以一鍵釋放資源:
wangzhipengs-MacBook-Pro:terraform_dir wangzhipeng$ terraform destroy
alicloud_security_group.default: Refreshing state... (ID: sg-2zec9v8aq2hgb244qrqf)
alicloud_instance.web: Refreshing state... (ID: i-2zedvfowy4m39sg1xdig)
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
alicloud_instance.web
alicloud_security_group.default
Plan: 0 to add, 0 to change, 2 to destroy.
Do you really want to destroy?
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
alicloud_instance.web: Destroying... (ID: i-2zedvfowy4m39sg1xdig)
alicloud_instance.web: Still destroying... (ID: i-2zedvfowy4m39sg1xdig, 10s elapsed)
alicloud_instance.web: Destruction complete after 11s
alicloud_security_group.default: Destroying... (ID: sg-2zec9v8aq2hgb244qrqf)
alicloud_security_group.default: Destruction complete after 1s
Destroy complete! Resources: 2 destroyed.
最後更新:2017-09-25 12:03:06