在本快速入门中,你将使用 Terraform 创建 Azure Windows 虚拟机(VM)和相关资源。 Azure Windows VM 是 Azure 提供的可缩放计算资源。 它是 Azure 云中的按需虚拟化 Windows 服务器。 可以使用它来部署、测试和运行应用程序,等等。 除了 VM,此代码还创建虚拟网络、子网、公共 IP、网络安全组、网络接口、存储帐户、Azure 备份恢复服务保管库和备份策略。
使用 Terraform 可以定义、预览和部署云基础结构。 使用 Terraform 时,请使用 HCL 语法来创建配置文件。 利用 HCL 语法,可指定 Azure 这样的云提供程序和构成云基础结构的元素。 创建配置文件后,请创建一个执行计划,利用该计划,可在部署基础结构更改之前先预览这些更改。 验证了更改后,请应用该执行计划以部署基础结构。
在这篇文章中,你将学会如何:
- 创建具有唯一名称的 Azure 资源组。
- 创建具有唯一名称和指定地址空间的虚拟网络。
- 在虚拟网络中创建具有唯一名称和指定地址前缀的子网。
- 创建具有唯一名称的公共 IP 地址。
- 创建一个网络安全组,其中包含两个用于远程桌面协议和 Web 流量的安全规则。
- 创建具有唯一名称的网络接口,并将其附加到子网和公共 IP 地址。
- 将网络安全组与网络接口相关联。
- 生成唯一存储帐户名称的随机 ID,并插入用于启动诊断的存储帐户。
- 创建具有唯一名称的 Windows VM,并为 VM 生成随机密码。
- 创建具有唯一名称的备份恢复服务保管库。
- 为 VM 创建每日频率和保留期为 7 天的备份策略。
- 使用创建的备份策略保护 VM。
- 创建具有活动订阅的 Azure 帐户。 可创建试用帐户。
- 安装和配置Terraform。
本文中的示例代码位于 Azure Terraform GitHub 存储库中。 你可以查看包含当前和以前 Terraform 版本的测试结果的日志文件。 请参阅更多 文章和示例代码,了解如何使用 Terraform 管理 Azure 资源。
创建用于测试和运行示例 Terraform 代码的目录,并将其设为当前目录。
创建名为
main.tf
的文件并插入以下代码:
resource "random_pet" "rg_name" {
prefix = var.resource_group_name_prefix
}
resource "azurerm_resource_group" "rg" {
location = var.resource_group_location
name = random_pet.rg_name.id
}
resource "random_string" "name" {
length = 12
lower = true
upper = false
numeric = false
special = false
}
# Create virtual network
resource "azurerm_virtual_network" "my_terraform_network" {
name = "${random_string.name.id}-vnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
# Create subnet
resource "azurerm_subnet" "my_terraform_subnet" {
name = "${random_string.name.id}-subnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.my_terraform_network.name
address_prefixes = ["10.0.1.0/24"]
}
# Create public IPs
resource "azurerm_public_ip" "my_terraform_public_ip" {
name = "${random_string.name.id}-public-ip"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Dynamic"
}
# Create Network Security Group and rules
resource "azurerm_network_security_group" "my_terraform_nsg" {
name = "${random_string.name.id}-nsg"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "RDP"
priority = 1000
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "3389"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "web"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
# Create network interface
resource "azurerm_network_interface" "my_terraform_nic" {
name = "${random_string.name.id}-nic"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "my_nic_configuration"
subnet_id = azurerm_subnet.my_terraform_subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.my_terraform_public_ip.id
}
}
# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "example" {
network_interface_id = azurerm_network_interface.my_terraform_nic.id
network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id
}
# Create storage account for boot diagnostics
resource "azurerm_storage_account" "my_storage_account" {
name = "diag${random_id.random_id.hex}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
account_tier = "Standard"
account_replication_type = "LRS"
}
# Create virtual machine
resource "azurerm_windows_virtual_machine" "main" {
name = "${random_string.name.id}-vm"
admin_username = "azureuser"
admin_password = random_password.password.result
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.my_terraform_nic.id]
size = "Standard_DS1_v2"
vm_agent_platform_updates_enabled = true
os_disk {
name = "myOsDisk"
caching = "ReadWrite"
storage_account_type = "Premium_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2022-datacenter-azure-edition"
version = "latest"
}
boot_diagnostics {
storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint
}
}
# Generate random text for a unique storage account name
resource "random_id" "random_id" {
keepers = {
# Generate a new ID only when a new resource group is defined
resource_group = azurerm_resource_group.rg.name
}
byte_length = 8
}
resource "random_password" "password" {
length = 20
min_lower = 1
min_upper = 1
min_numeric = 1
min_special = 1
special = true
}
resource "azurerm_recovery_services_vault" "example" {
name = "${random_string.name.id}-vault"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
sku = "Standard"
soft_delete_enabled = var.soft_delete_enabled
}
resource "azurerm_backup_policy_vm" "example" {
name = "${random_string.name.id}-policy"
resource_group_name = azurerm_resource_group.rg.name
recovery_vault_name = azurerm_recovery_services_vault.example.name
backup {
frequency = "Daily"
time = "23:00"
}
retention_daily {
count = 7
}
}
resource "azurerm_backup_protected_vm" "example" {
resource_group_name = azurerm_resource_group.rg.name
recovery_vault_name = azurerm_recovery_services_vault.example.name
source_vm_id = azurerm_windows_virtual_machine.main.id
backup_policy_id = azurerm_backup_policy_vm.example.id
}
- 创建名为
outputs.tf
的文件并插入以下代码:
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
output "azurerm_recovery_services_vault_name" {
value = azurerm_recovery_services_vault.example.name
}
output "azurerm_backup_policy_vm_name" {
value = azurerm_backup_policy_vm.example.name
}
output "azurerm_windows_virtual_machine_name" {
value = azurerm_windows_virtual_machine.main.name
}
output "public_ip_address" {
value = azurerm_windows_virtual_machine.main.public_ip_address
}
output "admin_password" {
sensitive = true
value = azurerm_windows_virtual_machine.main.admin_password
}
- 创建名为
providers.tf
的文件并插入以下代码:
terraform {
required_version = ">=1.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.0"
}
random = {
source = "hashicorp/random"
version = "~>3.0"
}
}
}
provider "azurerm" {
features {
recovery_service {
vm_backup_stop_protection_and_retain_data_on_destroy = true
purge_protected_items_from_vault_on_destroy = true
}
}
}
- 创建名为
variables.tf
的文件并插入以下代码:
variable "resource_group_location" {
type = string
default = "chinanorth"
description = "Location of the resource group."
}
variable "resource_group_name_prefix" {
type = string
default = "rg"
description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
}
variable "soft_delete_enabled" {
type = bool
default = false
nullable = false
description = "Is soft delete enable for the recovery services vault?"
}
重要
如果使用 4.x azurerm 提供程序,则必须在运行 Terraform 命令之前 显式指定要向 Azure 进行身份验证的 Azure 订阅 ID 。
一种指定 Azure 订阅 ID 的方法是在名为 providers
的环境变量中指定订阅 ID,而不是将其放在 ARM_SUBSCRIPTION_ID
块中。
有关详细信息,请参阅 Azure 提供程序参考文档。
运行 terraform init,将 Terraform 部署进行初始化。 此命令将下载管理 Azure 资源所需的 Azure 提供程序。
terraform init -upgrade
要点:
- 参数
-upgrade
可将必要的提供程序插件升级到符合配置版本约束的最新版本。
运行 terraform plan 以创建执行计划。
terraform plan -out main.tfplan
要点:
-
terraform plan
命令将创建一个执行计划,但不会执行它。 相反,它会确定需要执行哪些操作,以创建配置文件中指定的配置。 此模式允许你在对实际资源进行任何更改之前验证执行计划是否符合预期。 - 使用可选
-out
参数可以为计划指定输出文件。 使用-out
参数可以确保所查看的计划与所应用的计划完全一致。
运行 terraform apply 以将执行计划应用到您的云基础架构。
terraform apply main.tfplan
要点:
- 示例
terraform apply
命令假设你先前运行了terraform plan -out main.tfplan
。 - 如果为
-out
参数指定了不同的文件名,请在对terraform apply
的调用中使用该相同文件名。 - 如果未使用
-out
参数,请调用不带任何参数的terraform apply
。
获取 Azure 资源组名称。
resource_group_name = $(terraform outout -raw azurerm_resource_group_name)
获取备份恢复服务保管库名称。
recovery_services_vault_name = $(terraform output -raw azurerm_recovery_services_vault_name)
获取 Windows VM 名称。
windows_virtual_machine_name = $(terraform output -raw azurerm_windows_virtual_machine_name)
运行
az backup protection backup-now
以启动备份作业。az backup protection backup-now --resource-group $resource_group_name \ --vault-name $recovery_services_vault_name \ --container-name $windows_virtual_machine_name \ --item-name $windows_virtual_machine_name \ --backup-management-type AzureIaaSVM
运行
az backup job list
以监视备份作业。 当备份作业的“状态”报告“已完成”时,VM 将接受备份恢复服务的保护,并已存储完整的恢复点。az backup job list --resource-group $resource_group_name \ --vault-name $recovery_services_vault_name \ --output table
不再需要通过 Terraform 创建的资源时,请执行以下步骤:
运行 terraform plan 并指定
destroy
标志。terraform plan -destroy -out main.destroy.tfplan
要点:
-
terraform plan
命令将创建一个执行计划,但不会执行它。 相反,它会确定需要执行哪些操作,以创建配置文件中指定的配置。 此模式允许你在对实际资源进行任何更改之前验证执行计划是否符合预期。 - 使用可选
-out
参数可以为计划指定输出文件。 使用-out
参数可以确保所查看的计划与所应用的计划完全一致。
-
运行 terraform apply 来应用执行计划。
terraform apply main.destroy.tfplan