在前文《Terraform安裝及簡(jiǎn)單介紹》中簡(jiǎn)單介紹了 Terraform 相關(guān)的概念,本文讓我們使用 Terraform 在 Azure 上創(chuàng)建一個(gè)虛機(jī),以此來(lái)直觀體驗(yàn)一下 Terraform 強(qiáng)大威力。說(shuō)明:本文的演示環(huán)境為 Ubuntu 16.04。
provider 與 resource
在 Terraform 的配置文件中,比較常見(jiàn)的配置類型有 provider 和 resource。
provider 在 Terraform 中負(fù)責(zé)管理資源的生命周期:創(chuàng)建、讀取、更新、刪除。比如訪問(wèn) AWS 中的資源需要使用 AWS 的 provider,訪問(wèn) Azure 中的資源需要使用 Azure 的 provider。
resource 是基礎(chǔ)設(shè)施的一個(gè)組件。它可能是一些低級(jí)組件,例如物理服務(wù)器、虛擬機(jī)或容器。也可以是更高級(jí)別的組件,如電子郵件提供程序、DNS記錄或數(shù)據(jù)庫(kù)提供程序。
指定 provider
provider "azurerm" { }
訪問(wèn) Azure 中的資源需要使用 Azure 的 provider,即這里的 “azurerm”。這里沒(méi)有把訪問(wèn) azure 的認(rèn)證信息寫(xiě)進(jìn)來(lái),還是以前文《Terraform安裝及簡(jiǎn)單介紹》中設(shè)置環(huán)境變量的方式來(lái)提供認(rèn)證信息。
創(chuàng)建 Resource Group
下面的配置文件在 eastasia 的數(shù)據(jù)中心創(chuàng)建名稱為 NickResourceGroup 的 Resource Group:
resource "azurerm_resource_group" "nicktfrg" { name = "NickResourceGroup" location = "eastasia" tags { environment = "My Terraform Demo" } }
在配置文件的其他部分中,可以使用 ${azurerm_resource_group.nicktfrg.name} 引用該 Resource Group。
創(chuàng)建虛擬網(wǎng)絡(luò)
下面的配置在 Resource Group NickResourceGroup 中創(chuàng)建名為 NickVnet 的虛擬網(wǎng)絡(luò),其網(wǎng)絡(luò)空間為 10.0.0.0/16:
resource "azurerm_virtual_network" "nicktfnetwork" { name = "NickVnet" address_space = ["10.0.0.0/16"] location = "eastasia" resource_group_name = "${azurerm_resource_group.nicktfrg.name}" tags { environment = "My Terraform Demo" } }
然后在 NickVnet 虛擬網(wǎng)絡(luò)中創(chuàng)建名稱為 NickSubnet 的子網(wǎng):
resource "azurerm_subnet" "nicktfsubnet" { name = "NickSubnet" resource_group_name = "${azurerm_resource_group.nicktfrg.name}" virtual_network_name = "${azurerm_virtual_network.nicktfnetwork.name}" address_prefix = "10.0.2.0/24" }
創(chuàng)建公共 IP 地址
如果要通過(guò)網(wǎng)絡(luò)訪問(wèn) Azure 云端的虛機(jī),需要?jiǎng)?chuàng)建公共的 IP 地址并分配給虛機(jī)。下面的配置創(chuàng)建名為 nickPublicIP 的公共 IP 地址:
resource "azurerm_public_ip" "nicktfpublicip" { name = "NickPublicIP" location = "eastasia" resource_group_name = "${azurerm_resource_group.nicktfrg.name}" public_ip_address_allocation = "dynamic" tags { environment = "My Terraform Demo" } }
創(chuàng)建網(wǎng)絡(luò)安全組
網(wǎng)絡(luò)安全組控制出入虛機(jī)的網(wǎng)絡(luò)流量。 下面的配置創(chuàng)建名為 NickNetworkSecurityGroup 的網(wǎng)絡(luò)安全組并定義規(guī)則放行 TCP 端口 22 上的 SSH 數(shù)據(jù)包:
resource "azurerm_network_security_group" "nicktfnsg" { name = "NickNetworkSecurityGroup" location = "eastasia" resource_group_name = "${azurerm_resource_group.nicktfrg.name}" security_rule { name = "SSH" priority = 1001 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "22" source_address_prefix = "*" destination_address_prefix = "*" } tags { environment = "My Terraform Demo" } }
創(chuàng)建虛擬網(wǎng)卡
虛擬網(wǎng)卡(NIC)將虛機(jī)連接到指定的虛擬網(wǎng)絡(luò)、公共 IP 地址和網(wǎng)絡(luò)安全組。下面的 Terraform 配置信息創(chuàng)建名為 NickNIC 的虛擬 NIC,并連接到已創(chuàng)建的虛擬網(wǎng)絡(luò)資源:
resource "azurerm_network_interface" "nicktfnic" { name = "NickNIC" location = "eastasia" resource_group_name = "${azurerm_resource_group.nicktfrg.name}" network_security_group_id = "${azurerm_network_security_group.nicktfnsg.id}" ip_configuration { name = "NickNicConfiguration" subnet_id = "${azurerm_subnet.nicktfsubnet.id}" private_ip_address_allocation = "dynamic" public_ip_address_id = "${azurerm_public_ip.nicktfpublicip.id}" } tags { environment = "My Terraform Demo" } }
創(chuàng)建存儲(chǔ)賬戶
若要為新建的虛機(jī)存儲(chǔ)啟動(dòng)診斷日志,需要一個(gè)存儲(chǔ)帳戶。這些啟動(dòng)診斷日志有助于排查故障和監(jiān)視虛機(jī)狀態(tài)。這里創(chuàng)建的存儲(chǔ)帳戶僅用于存儲(chǔ)啟動(dòng)診斷數(shù)據(jù)。由于每個(gè)存儲(chǔ)帳戶必須具有唯一名稱,下面的配置會(huì)先生成一些隨機(jī)文本:
resource "random_id" "randomId" { keepers = { # Generate a new ID only when a new resource group is defined resource_group = "${azurerm_resource_group.nicktfrg.name}" } byte_length = 8 }
接下來(lái)就可以創(chuàng)建存儲(chǔ)帳戶了。 下面的配置會(huì)創(chuàng)建一個(gè)存儲(chǔ)帳戶,其名稱基于上一步中生成的隨機(jī)文本:
resource "azurerm_storage_account" "nicktfstorageaccount" { name = "nicksa${random_id.randomId.hex}" resource_group_name = "${azurerm_resource_group.nicktfrg.name}" location = "eastasia" account_replication_type = "LRS" account_tier = "Standard" tags { environment = "My Terraform Demo" } }
創(chuàng)建虛機(jī)
準(zhǔn)備好上面的資源后就可以開(kāi)始創(chuàng)建虛機(jī)了,下面的配置創(chuàng)建名為 NickVM 的虛機(jī),并添加虛擬網(wǎng)卡 NickNIC。 新的虛機(jī)基于 Ubuntu 16.04 LTS 映像并禁止通過(guò)密碼登錄,同時(shí)會(huì)創(chuàng)建一個(gè)可以通過(guò)秘鑰登錄的名稱為 nick 的用戶。注意,ssh_keys 部分提供了 SSH 密鑰數(shù)據(jù),key_data 字段需要提供用戶的有效 SSH 公鑰:
resource "azurerm_virtual_machine" "nicktfvm" { name = "NickVM" location = "eastasia" resource_group_name = "${azurerm_resource_group.nicktfrg.name}" network_interface_ids = ["${azurerm_network_interface.nicktfnic.id}"] vm_size = "Standard_DS1_v2" storage_os_disk { name = "NickOsDisk" caching = "ReadWrite" create_option = "FromImage" managed_disk_type = "Premium_LRS" } storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "16.04.0-LTS" version = "latest" } os_profile { computer_name = "phoenix" admin_username = "nick" } os_profile_linux_config { disable_password_authentication = true ssh_keys { path = "/home/nick/.ssh/authorized_keys" key_data = "xxxxxxxxxxxxxxxxxx" } } boot_diagnostics { enabled = "true" storage_uri = "${azurerm_storage_account.nicktfstorageaccount.primary_blob_endpoint}" } tags { environment = "My Terraform Demo" } }
到這里配置文件就完成了,完整的配置文件內(nèi)容請(qǐng)參考這里。
執(zhí)行部署
創(chuàng)建 Terraform 配置文件(也被稱為模板)后,第一步是初始化 Terraform。這一步會(huì)安裝 配置文件中用到的所有 Terraform 插件:
$ terraform init
然后執(zhí)行 plan 驗(yàn)證配置文件的正確性(關(guān)于登錄 Azure 的認(rèn)證信息,請(qǐng)參考前文《Terraform 簡(jiǎn)介》):
$ . azureEnv.sh $ terraform plan
檢查 plan 的輸出,如果符合預(yù)期,就可以通過(guò) apply 執(zhí)行實(shí)際的部署了:
$ terraform apply -auto-approve
檢查結(jié)果
從 portal 上登錄 Azure 查看我們創(chuàng)建的 Resouce Group NickResourceGroup,其中的資源包括虛擬機(jī) NickVM 及其相關(guān)的網(wǎng)卡、Public IP 地址、虛擬網(wǎng)絡(luò)、網(wǎng)絡(luò)安全組、存儲(chǔ)等組件:
獲取虛機(jī)的公共 IP 地址
在 portal 上的 Cloud Shell 中執(zhí)行下面的命令獲得新建虛機(jī)的 IP 地址:
$ az vm show --resource-group NickResourceGroup --name NickVM -d --query [publicIps] --o tsv
或者是直接在 portal 上查看虛機(jī)的信息:
通過(guò) SSH 登錄虛機(jī)
$ ssh nick@13.70.0.72
這就可以開(kāi)始工作了(當(dāng)然對(duì)于一個(gè)系統(tǒng)管理員來(lái)說(shuō),所謂的工作就常常是指以自動(dòng)化的方式在虛機(jī)上部署各種應(yīng)用)!
總結(jié)
不管是通過(guò) PowerShell 還是 Azure CLI,或者是本文介紹的 Terraform(當(dāng)然,Terraform 強(qiáng)大的功能讓它具有非常大的優(yōu)勢(shì)),我們操作的資源對(duì)象都是一樣的。當(dāng)你手中有多個(gè)工具時(shí),你就可以根據(jù)具體的場(chǎng)景選擇最佳的方式完成任務(wù)。