Code as IaaS for Azure : Terraform 初步
節前有用戶提了兩個需求,PostgreSQL和Terraform,趁著過節有大塊的時間,把這兩個都粗略的過了下。之前已經把PostgreSQL相關測試結果寫了篇文檔,正好把Terraform的學習經歷也記錄下來,寫個文檔。
Terraform的網站上是這麽介紹的“Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.”。在我看來它是一個可以實現跨雲的代碼即基礎架構工具。目前Terraform支持的公有/私有雲平臺包括: AWS,Azure(ARM和ASM),阿裏雲,Google Cloud,Oracle Cloud,OpenStack,CloudStack,VMware等等等等等。嗯,要是還能支持AzureStack就完美了。
Terraform具體的功能可以在www.terraform.io上學習,它的文檔和示例都寫得很不錯,我在這就簡單介紹下怎麽用Terraform來管理Azure上的基礎架構。
目前Terraform支持Azure ARM的功能如下
Base Resource |
azurerm_resource_group |
Creates a new resource group on Azure. |
Template |
azurerm_template_deployment |
Create a template deployment of resources |
Web App |
azurerm_app_service_plan |
Create an App Service Plan component |
azurerm_app_service |
Manages an App Service (within an App Service Plan) |
|
Virtual Machine |
azurerm_virtual_machine |
Create a virtual machine. |
azurerm_availability_set |
Create an availability set for virtual machines. |
|
azurerm_virtual_machine_extension |
Creates a new Virtual Machine Extension to provide post deployment configuration and run automated tasks. |
|
azurerm_virtual_machine_scale_set |
Create a virtual machine scale set. |
|
Storage |
azurerm_storage_account |
Create an Azure Storage Account. |
azurerm_storage_container |
Create an Azure Storage Container. |
|
azurerm_storage_blob |
Create an Azure Storage Blob. |
|
azurerm_storage_queue |
Create an Azure Storage Queue. |
|
azurerm_storage_share |
Create an Azure Storage File Share. |
|
azurerm_storage_table |
Create an Azure Storage Table. |
|
Managed Disk |
azurerm_managed_disk |
Create a managed disk. |
azurerm_image |
Create a custom virtual machine image that can be used to create virtual machines. |
|
Network |
azurerm_express_route_circuit |
Creates an ExpressRoute circuit. |
azurerm_local_network_gateway |
Creates a new local network gateway connection over which specific connections can be configured. |
|
azurerm_network_interface |
Manages a Network Interface located in a Virtual Network, usually attached to a Virtual Machine. |
|
azurerm_network_security_group |
Create a network security group that contains a list of network security rules. |
|
azurerm_network_security_rule |
Create a Network Security Rule. |
|
azurerm_public_ip |
Create a Public IP Address. |
|
azurerm_route |
Creates a new Route Resource |
|
azurerm_route_table |
Creates a new Route Table Resource |
|
azurerm_subnet |
Creates a new subnet. Subnets represent network segments within the IP space defined by the virtual network. |
|
azurerm_traffic_manager_endpoint |
Creates a Traffic Manager Endpoint. |
|
azurerm_traffic_manager_profile |
Creates a Traffic Manager Profile to which multiple endpoints can be attached. |
|
azurerm_virtual_network |
Creates a new virtual network including any configured subnets. Each subnet can optionally be configured with a security group to be associated with the subnet. |
|
azurerm_virtual_network_peering |
Creates a new virtual network peering which allows resources to access other resources in the linked virtual network. |
|
Load Balance |
azurerm_lb |
Create a LoadBalancer Resource. |
azurerm_lb_backend_address_pool |
Create a LoadBalancer Backend Address Pool. |
|
azurerm_lb_rule |
Create a LoadBalancer Rule. |
|
azurerm_lb_nat_rule |
Create a LoadBalancer NAT Rule. |
|
azurerm_lb_nat_pool |
Create a LoadBalancer NAT pool. |
|
azurerm_lb_probe |
Create a LoadBalancer Probe Resource. |
|
Automation |
azurerm_automation_account |
Creates a new Automation Account. |
azurerm_automation_credential |
Creates a new Automation Credential. |
|
azurerm_automation_runbook |
Creates a new Automation Runbook. |
|
azurerm_automation_schedule |
Creates a new Automation Schedule. |
除了這些基礎服務,Terraform還支持更多服務,包括Database:MySQL,SQL Server,還有Azure.com支持的PostgreSQL和CosmosDB。DNS 服務,KeyVault服務,消息隊列:Event Hub,Service Bus。Redis服務,CDN服務,容器服務(Azure.com支持)。
要使用Terraform來部署Azure資源,官方建議是通過Service Principal 來通過Azure認證。我們會在每個部署腳本最前面看到這樣一段內容:
provider "azurerm" {
subscription_id = "..."
client_id = "..."
client_secret = "..."
tenant_id = "..."
}
在這段腳本裏指定了登錄到哪個Azure環境,使用哪個訂閱,以及用戶認證。所以接下來我們首先要獲得這幾個參數。
首先,我們通過Azure Cli登錄Azure。如果要登錄Azure.cn,記得先用“az cloud set -n AzureChinaCloud” 設置登錄環境。
用 az login 命令登錄,按照提示進行網頁驗證。登錄成功後會看到類似以下的返回:
[
{
"cloudName": "AzureChinaCloud",
"id": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
"isDefault": true,
"name": "Microsoft Azure Enterprise \u8bd5\u7528\u7248",
"state": "Enabled",
"tenantId": "XXXXXXXXXXXXXXXXXXXXXXXXX",
"user": {
"name": "[email protected]",
"type": "user"
}
}
]
註意,這其中的id和tenantid就對應了我們需要的subscription_id和tenant_id這兩個參數。
接下來用az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/<subscription_id>" 這個命令來創建 Service Principal . 順利的話可以看到以下返回:
Retrying role assignment creation: 1/36
Retrying role assignment creation: 2/36
Retrying role assignment creation: 3/36
{
"appId": "XXXXXXXXXXXXXXXXXXXXXXXXX",
"displayName": "azure-cli-2017-09-28-08-01-33",
"name": "http://azure-cli-2017-09-28-08-01-33",
"password": "XXXXXXXXXXXXXXXXXXXXXXXXXXX",
"tenant": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
其中appId和password分別對應了我們需要的參數client_id和client_secret
其實也可以在GUI界面裏進行相同的工作,結果大致如下圖所示
順便說一下,按照這個思路,我最後寫了4個腳本,可以分別在Azure CLI和Powershell環境下登錄Azure.com和Azure.cn。不需要在本機或Azure上保存任何證書都可以使用。還是很方便的。大家如果有興趣以後再寫一個文檔說明是怎麽做的。
獲得所需要的Azure登錄參數,我們就可以正式來寫一個Terraform腳本來部署一個虛機了。
這次我們用到的腳本如下:
variable "resourcesname" {
default = "helloterraform"
}
# 這段是配置Azure的使用環境
# 註意,因為使用的是Azure.cn,所以要加上參數environment = "china",默認是azure.com,參數使用上面所講的步驟裏獲得的那幾個參數
provider "azurerm" {
subscription_id = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
client_id = "XXXXXXXXXXXXXXXXXXXXXXXXXXX"
client_secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
tenant_id = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
environment = "china"
}
# 創建一個Resource Group,名字是lyq-testterraform-rg,位置是北京
resource "azurerm_resource_group" "helloterraform" {
name = "lyq-testterraform-rg"
location = "China North"
}
# 創建一個虛擬網絡,給定name,IP,位置和所屬資源組
resource "azurerm_virtual_network" "helloterraformnetwork" {
name = "tfvn"
address_space = ["10.0.0.0/16"]
location = "China North"
resource_group_name = "${azurerm_resource_group.helloterraform.name}"
}
# 創建一個虛擬子網
resource "azurerm_subnet" "helloterraformsubnet" {
name = "tfsub"
resource_group_name = "${azurerm_resource_group.helloterraform.name}"
virtual_network_name = "${azurerm_virtual_network.helloterraformnetwork.name}"
address_prefix = "10.0.2.0/24"
}
# 創建一個公網地址
resource "azurerm_public_ip" "helloterraformips" {
name = "terraformtestip"
location = "China North"
resource_group_name = "${azurerm_resource_group.helloterraform.name}"
public_ip_address_allocation = "dynamic"
tags {
environment = "TerraformDemo"
}
}
# 創建一塊虛擬網卡
resource "azurerm_network_interface" "helloterraformnic" {
name = "tfni"
location = "China North"
resource_group_name = "${azurerm_resource_group.helloterraform.name}"
ip_configuration {
name = "testconfiguration1"
subnet_id = "${azurerm_subnet.helloterraformsubnet.id}"
private_ip_address_allocation = "static"
private_ip_address = "10.0.2.5"
public_ip_address_id = "${azurerm_public_ip.helloterraformips.id}"
}
}
# 創建一個隨機數,我們知道存儲賬戶是要求一個不沖突的獨立命名,這個隨機數就是用在存儲賬戶裏的
resource "random_id" "randomId" {
byte_length = 4
}
# 創建一個存儲賬戶,也可以創建一個managed disk
resource "azurerm_storage_account" "helloterraformstorage" {
name = "tfstorage${random_id.randomId.hex}"
resource_group_name = "${azurerm_resource_group.helloterraform.name}"
location = "China North"
account_type = "Standard_LRS"
tags {
environment = "staging"
}
}
# 創建一個存儲容器
resource "azurerm_storage_container" "helloterraformstoragestoragecontainer" {
name = "vhd"
resource_group_name = "${azurerm_resource_group.helloterraform.name}"
storage_account_name = "${azurerm_storage_account.helloterraformstorage.name}"
container_access_type = "private"
depends_on = ["azurerm_storage_account.helloterraformstorage"]
}
# 創建虛擬機,用Ubuntu系統,將之前創建的虛擬網卡,存儲都掛載好,設定用戶名和密碼,在生產環境裏建議disable_password_authentication = true,這樣需要指定證書登錄。
resource "azurerm_virtual_machine" "helloterraformvm" {
name = "terraformvm"
location = "China North"
resource_group_name = "${azurerm_resource_group.helloterraform.name}"
network_interface_ids = ["${azurerm_network_interface.helloterraformnic.id}"]
vm_size = "Standard_A0"
storage_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "14.04.2-LTS"
version = "latest"
}
storage_os_disk {
name = "myosdisk"
vhd_uri = "${azurerm_storage_account.helloterraformstorage.primary_blob_endpoint}${azurerm_storage_container.helloterraformstoragestoragecontainer.name}/myosdisk.vhd"
caching = "ReadWrite"
create_option = "FromImage"
}
os_profile {
computer_name = "hostname"
admin_username = "testadmin"
admin_password = "Password1234!"
}
os_profile_linux_config {
disable_password_authentication = false
}
tags {
environment = "staging"
}
}
這樣就可以創建一個虛擬機了。可以先用terraform plan命令來驗證腳本是否正確,還可以用-out參數來輸出一個執行腳本,例如:terraform plan -out lyqdemo .
驗證沒有問題後,用 terraform apply lyqdemo 命令來執行變更。等執行完成後,我們可以在Azure.cn界面裏查看下創建的是否正確
創建虛擬機可以說是最簡單的一個動作了,接下來我們會做一些更復雜的事情。
Code as IaaS for Azure : Terraform 初步