1. 程式人生 > >Code as IaaS for Azure : Terraform 做多一點事情

Code as IaaS for Azure : Terraform 做多一點事情

命令 define compute 區域 ken 我們 指定 dns nag

上一篇大概介紹了怎麽用Terraform在Azure上創建一個虛擬機,接下來,我們會用Terraform來做一些更復雜的工作。

在開始工作前,我們還是要先解釋下會用到的幾個命令。

因為我用的是Win10系統,所以下載的Terraform下載後就是一個執行文件,可以放在任何一個目錄下執行。在最開始的時候,記得先要執行以下命令:

terraform init

這條命令會初始化terraform的執行目錄。如果查看隱藏目錄的話,會看見這條命令創建一了一個隱藏目錄”.terraform”,並在這個目錄裏下載了兩個插件。

Terraform可以使用不同的工作區域來區分不同的執行環境。命令是:

terraform workspace

可以在後面再加上new,delete,show,list,select參數來創建刪除和管理工作區域。

還有兩個很重要的命令是terraform plan和terraform apply

terraform plan會解析配置腳本,並比較現有資源和配置腳本之間的差異。如果用了 -out 參數,可以輸出一個執行腳本。如果配置腳本的語法或參數錯誤,plan命令會返回相應的錯誤信息。換句話說,plan沒有報錯,說明至少腳本的語法是正確的。

terraform apply,當plan沒有報錯後,就可以執行apply命令,它會真正在Azure上創建腳本所指定的資源。這個階段也可能會報錯,例如,資源已經存在,或者資源不足,護著指定的資源不存在。

要註意的是,在沒有特殊指定時,plan和apply會執行當前目錄下的所有配置腳本。所以為什麽會有workspace的設置,這就可以理解了。不過按我的理解,多建幾個目錄會是更簡單和可靠的方法。

如果要刪除資源,也是有命令可以用的。。。。。。

terraform plan -destroy 和 terraform destroy

大概了解了terraform的主要命令後,要開始做一些更復雜的事情了。這次我打算建的一個簡單的應用環境,負載均衡後帶兩臺虛擬機,對外開放80端口,包括健康檢查,獨立的網絡。依然放在上一篇文檔所建立的資源組lyq-testterraform-rg裏。

配置腳本如下:經過上一篇文檔,我就不介紹每一段是幹什麽的了。腳本還是很容易讀懂的。

provider "azurerm" {

subscription_id = "xxxxxxxxxxxxxxxxx"

client_id = "xxxxxxxxxxxxxxxx"

client_secret = "xxxxxxxxxxxxxxxxx"

tenant_id = "xxxxxxxxxxxxxxx"

environment = "china"

}

resource "azurerm_resource_group" "rg" {

name = "${var.resource_group}"

location = "${var.location}"

}

resource "azurerm_storage_account" "stor" {

name = "${var.dns_name}stor"

location = "${var.location}"

resource_group_name = "${azurerm_resource_group.rg.name}"

account_type = "Standard_GRS"

}

resource "azurerm_availability_set" "avset" {

name = "${var.dns_name}avset"

location = "${var.location}"

resource_group_name = "${azurerm_resource_group.rg.name}"

platform_fault_domain_count = 2

platform_update_domain_count = 2

managed = true

}

resource "azurerm_public_ip" "lbpip" {

name = "${var.rg_prefix}-ip"

location = "${var.location}"

resource_group_name = "${azurerm_resource_group.rg.name}"

public_ip_address_allocation = "dynamic"

domain_name_label = "${var.lb_ip_dns_name}"

}

resource "azurerm_virtual_network" "vnet" {

name = "${var.virtual_network_name}"

location = "${var.location}"

address_space = ["${var.address_space}"]

resource_group_name = "${azurerm_resource_group.rg.name}"

}

resource "azurerm_subnet" "subnet" {

name = "${var.rg_prefix}subnet"

virtual_network_name = "${azurerm_virtual_network.vnet.name}"

resource_group_name = "${azurerm_resource_group.rg.name}"

address_prefix = "${var.subnet_prefix}"

}

resource "azurerm_lb" "lb" {

resource_group_name = "${azurerm_resource_group.rg.name}"

name = "${var.rg_prefix}lb"

location = "${var.location}"

frontend_ip_configuration {

name = "LoadBalancerFrontEnd"

public_ip_address_id = "${azurerm_public_ip.lbpip.id}"

}

}

resource "azurerm_lb_backend_address_pool" "backend_pool" {

resource_group_name = "${azurerm_resource_group.rg.name}"

loadbalancer_id = "${azurerm_lb.lb.id}"

name = "BackendPool1"

}

resource "azurerm_lb_nat_rule" "tcp" {

resource_group_name = "${azurerm_resource_group.rg.name}"

loadbalancer_id = "${azurerm_lb.lb.id}"

name = "RDP-VM-${count.index}"

protocol = "tcp"

frontend_port = "5000${count.index + 1}"

backend_port = 3389

frontend_ip_configuration_name = "LoadBalancerFrontEnd"

count = 2

}

resource "azurerm_lb_rule" "lb_rule" {

resource_group_name = "${azurerm_resource_group.rg.name}"

loadbalancer_id = "${azurerm_lb.lb.id}"

name = "LBRule"

protocol = "tcp"

frontend_port = 80

backend_port = 80

frontend_ip_configuration_name = "LoadBalancerFrontEnd"

enable_floating_ip = false

backend_address_pool_id = "${azurerm_lb_backend_address_pool.backend_pool.id}"

idle_timeout_in_minutes = 5

probe_id = "${azurerm_lb_probe.lb_probe.id}"

depends_on = ["azurerm_lb_probe.lb_probe"]

}

resource "azurerm_lb_probe" "lb_probe" {

resource_group_name = "${azurerm_resource_group.rg.name}"

loadbalancer_id = "${azurerm_lb.lb.id}"

name = "tcpProbe"

protocol = "tcp"

port = 80

interval_in_seconds = 5

number_of_probes = 2

}

resource "azurerm_network_interface" "nic" {

name = "nic${count.index}"

location = "${var.location}"

resource_group_name = "${azurerm_resource_group.rg.name}"

count = 2

ip_configuration {

name = "ipconfig${count.index}"

subnet_id = "${azurerm_subnet.subnet.id}"

private_ip_address_allocation = "Dynamic"

load_balancer_backend_address_pools_ids = ["${azurerm_lb_backend_address_pool.backend_pool.id}"]

load_balancer_inbound_nat_rules_ids = ["${element(azurerm_lb_nat_rule.tcp.*.id, count.index)}"]

}

}

resource "azurerm_virtual_machine" "vm" {

name = "vm${count.index}"

location = "${var.location}"

resource_group_name = "${azurerm_resource_group.rg.name}"

availability_set_id = "${azurerm_availability_set.avset.id}"

vm_size = "${var.vm_size}"

network_interface_ids = ["${element(azurerm_network_interface.nic.*.id, count.index)}"]

count = 2

storage_image_reference {

publisher = "${var.image_publisher}"

offer = "${var.image_offer}"

sku = "${var.image_sku}"

version = "${var.image_version}"

}

storage_os_disk {

name = "osdisk${count.index}"

create_option = "FromImage"

}

os_profile {

computer_name = "${var.hostname}"

admin_username = "${var.admin_username}"

admin_password = "${var.admin_password}"

}

}

看完上面腳本,大家是不是覺得上面每個參數都是$的引用,到底引用了什麽?Terraform的這個特性是非常好的,可以很簡單定義不同的參數引用。上面這個腳本對應的所有參數引用在下面這個腳本裏定義:

variable "resource_group" {

description = "The name of the resource group in which to create the virtual network."

default = "lyq-testterraform-rg"

}

variable "rg_prefix" {

description = "The shortened abbreviation to represent your resource group that will go on the front of some resources."

default = "rg"

}

variable "hostname" {

description = "VM name referenced also in storage-related names."

default = "lyqterravm"

}

variable "dns_name" {

description = " Label for the Domain Name. Will be used to make up the FQDN. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system."

default = "lyqterraform"

}

variable "lb_ip_dns_name" {

description = "DNS for Load Balancer IP"

default = "lyqtestterralb"

}

variable "location" {

description = "The location/region where the virtual network is created. Changing this forces a new resource to be created."

default = "chinanorth"

}

variable "virtual_network_name" {

description = "The name for the virtual network."

default = "lyq-test-vnet"

}

variable "address_space" {

description = "The address space that is used by the virtual network. You can supply more than one address space. Changing this forces a new resource to be created."

default = "10.0.0.0/16"

}

variable "subnet_prefix" {

description = "The address prefix to use for the subnet."

default = "10.0.10.0/24"

}

variable "storage_account_tier" {

description = "Defines the Tier of storage account to be created. Valid options are Standard and Premium."

default = "Premium"

}

variable "storage_replication_type" {

description = "Defines the Replication Type to use for this storage account. Valid options include LRS, GRS etc."

default = "LRS"

}

variable "vm_size" {

description = "Specifies the size of the virtual machine."

default = "Standard_D1"

}

variable "image_publisher" {

description = "name of the publisher of the image (az vm image list)"

default = "MicrosoftWindowsServer"

}

variable "image_offer" {

description = "the name of the offer (az vm image list)"

default = "WindowsServer"

}

variable "image_sku" {

description = "image sku to apply (az vm image list)"

default = "2012-R2-Datacenter"

}

variable "image_version" {

description = "version of the image to apply (az vm image list)"

default = "latest"

}

variable "admin_username" {

description = "administrator user name"

default = "lyqadmin"

}

variable "admin_password" {

description = "administrator password (recommended to disable password auth)"

default = "[email protected]"

}

如果我們不給參數定義default值,那麽在執行plan時,就會要求輸入相應的參數,這樣就可以實現自定義配置。

把這兩個腳本分別保存為tf文件,例如2VMLB.tf和variables.tf。然後執行terraform plan和 apply,不出意外的話,我們就可以在azure.cn界面裏看到創建出來的這些資源了。

技術分享

技術分享

技術分享

因為指定的虛擬機用了win2012R2模板,所以需要進虛擬機去開啟IIS,完成後,就可以通過負載均衡的公網IP訪問了。

技術分享技術分享

Code as IaaS for Azure : Terraform 做多一點事情