接下来我们就实际演示下Terraform是怎么部署资源的,以Azure为例,我们首先需要准备Azure CLI,CLI可以用来做身份验证,terraform本身是没有身份验证功能的,如何判定我们是否有权限进行资源的部署/更改主要还是靠云平台本身,所以我们需要首先验证好我们的身份,然后才能进行云资源的部署和变更。
Azure CLI可以使用service principle进行登录,我们首先可以先创建一个SP
$sp = New-AzADServicePrincipal -Scope /subscriptions/6dxxxxxxxxxxxxxxxxxx
可以在application registration里看到新建的sp
然后可以针对这个sp进行授权,可以先给这个sp一个资源组的contributor权限或者subscription权限
接下来就可以在Azure CLI里登录了,首先将登录环境指定为中国
az cloud set --name AzureChinaCloud
az login
弹出浏览器登录窗口,输入密码登陆
云环境已经准备完毕,接下来就可以编写Terraform代码了,如果只是简单创建一台虚拟机,其实terraform代码会很简单,至于创建虚拟机时候需要指定的参数,比如虚拟机的名称,size等等我们都可以定义成变量,这点和其他编程语言非常类似
Terraform 0.13以上的版本需要按照以下方式先定义provider,required provider里要先制定好要是用的provider版本,可以是一个固定的版本,也可以指定一个范围
terraform { required_providers { azure = { source = "hashicorp/azurerm" version = "2.14.0" } } }
接下来就是资源的定义
locals里定义的一般都是一些可重复使用的常量,在部署时不需要像变量一样需要赋值,而是可以直接拿来用
locals { vm_name = "AzureVM" }
下边开始就是Azure资源的定义了,包括资源组,虚拟网络,网卡等
resource "azurerm_resource_group" "main" { name = "${var.prefix}-resources" location = var.location } resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] location = azurerm_resource_group.main.location resource_group_name = azurerm_resource_group.main.name subnet{ name = "Subnet1" address_prefix = "10.0.2.0/24" security_group = azurerm_network_security_group.example.id } subnet{ name = "Subnet2" address_prefix = "10.0.3.0/24" security_group = azurerm_network_security_group.example.id } } resource "azurerm_network_interface" "main" { name = "${var.prefix}-nic" resource_group_name = azurerm_resource_group.main.name location = azurerm_resource_group.main.location ip_configuration { name = "internal" subnet_id = element(azurerm_virtual_network.main.subnet.*.id, 1) private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.example.id } } resource "azurerm_virtual_machine" "main" { name = "${var.prefix}-vm" resource_group_name = azurerm_resource_group.main.name location = azurerm_resource_group.main.location vm_size = "Standard_DS2_v2" network_interface_ids = [ azurerm_network_interface.main.id ] storage_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2016-Datacenter" version = "latest" } storage_os_disk { name = "myosdisk1" caching = "ReadWrite" create_option = "FromImage" managed_disk_type = "Standard_LRS" } storage_data_disk{ name = "DataDisk" caching = "None" create_option = "Empty" disk_size_gb = 500 lun = 0 managed_disk_type = "Premium_LRS" } os_profile { computer_name = local.vm_name admin_username = var.username admin_password = var.password } os_profile_windows_config { enable_automatic_upgrades = false provision_vm_agent = false } }
定义好IAC的代码,首先我们先使用terraform init下载需要的provider,可以看到正在下载Terraform azurerm provider
下载完成后,尝试进行plan来看下部署时将要发生的变化,可以看到前边有很多+,代表这些资源都是会被添加的,如果是destroy的话可能会看到很多-的标志,另外,terraform做资源的变更其实主要是看tfstate里的状态,我们因为是个空的state,所以创建任何资源都是会被判断为新增,如果是一个已有的state的话,那就要先看看state里都有啥了
接下来直接apply进行创建,输入yes进行确认
可以看到资源一直在创建,这个输出界面感觉比ARM Template要友好不少
部署完成后,登录portal,可以看到资源已经创建好了