你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
快速入门:使用 Terraform 创建公共负载均衡器以对 VM 进行负载均衡
本快速入门演示如何使用 Terraform 部署标准负载均衡器,以对虚拟机进行负载均衡。
使用 Terraform 可以定义、预览和部署云基础结构。 使用 Terraform 时,请使用 HCL 语法来创建配置文件。 利用 HCL 语法,可指定 Azure 这样的云提供程序和构成云基础结构的元素。 创建配置文件后,请创建一个执行计划,利用该计划,可在部署基础结构更改之前先预览这些更改。 验证了更改后,请应用该执行计划以部署基础结构。
- 使用 azurerm_resource_group 创建 Azure 资源组
- 使用 azurerm_virtual_network 创建 Azure 虚拟网络
- 使用 azurerm_subnet 创建 Azure 子网
- 使用 azurerm_public_ip 创建 Azure 公共 IP
- 使用 azurerm_lb 创建 Azure 负载均衡器
- 使用 azurerm_network_interface 创建 Azure 网络接口
- 使用 azurerm_network_interface_backend_address_pool_association 创建 Azure 网络接口负载均衡器后端地址池关联
- 使用 azurerm_linux_virtual_machine 创建 Azure Linux 虚拟机
- 使用 azurerm_virtual_machine_extension 创建 Azure 虚拟机扩展
先决条件
实现 Terraform 代码
注意
有关更多示例,请参阅演示如何使用 Terraform 管理 Azure 资源的文章和示例代码
创建用于测试和运行示例 Terraform 代码的目录,并将其设为当前目录。
创建名为
providers.tf
的文件并插入下列代码:terraform { required_version = ">=0.12" required_providers { azapi = { source = "azure/azapi" version = "~>1.5" } azurerm = { source = "hashicorp/azurerm" version = "~>2.0" } random = { source = "hashicorp/random" version = "~>3.0" } } } provider "azurerm" { features {} }
创建名为
main.tf
的文件并插入下列代码:resource "random_string" "my_resource_group" { length = 8 upper = false special = false } # Create Resource Group resource "azurerm_resource_group" "my_resource_group" { name = "test-group-${random_string.my_resource_group.result}" location = var.resource_group_location } # Create Virtual Network resource "azurerm_virtual_network" "my_virtual_network" { name = var.virtual_network_name address_space = ["10.0.0.0/16"] location = azurerm_resource_group.my_resource_group.location resource_group_name = azurerm_resource_group.my_resource_group.name } # Create a subnet in the Virtual Network resource "azurerm_subnet" "my_subnet" { name = var.subnet_name resource_group_name = azurerm_resource_group.my_resource_group.name virtual_network_name = azurerm_virtual_network.my_virtual_network.name address_prefixes = ["10.0.1.0/24"] } # Create Network Security Group and rules resource "azurerm_network_security_group" "my_nsg" { name = var.network_security_group_name location = azurerm_resource_group.my_resource_group.location resource_group_name = azurerm_resource_group.my_resource_group.name security_rule { name = "web" priority = 1008 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "80" source_address_prefix = "*" destination_address_prefix = "10.0.1.0/24" } } # Associate the Network Security Group to the subnet resource "azurerm_subnet_network_security_group_association" "my_nsg_association" { subnet_id = azurerm_subnet.my_subnet.id network_security_group_id = azurerm_network_security_group.my_nsg.id } # Create Public IP resource "azurerm_public_ip" "my_public_ip" { name = var.public_ip_name location = azurerm_resource_group.my_resource_group.location resource_group_name = azurerm_resource_group.my_resource_group.name allocation_method = "Static" sku = "Standard" } # Create Network Interface resource "azurerm_network_interface" "my_nic" { count = 2 name = "${var.network_interface_name}${count.index}" location = azurerm_resource_group.my_resource_group.location resource_group_name = azurerm_resource_group.my_resource_group.name ip_configuration { name = "ipconfig${count.index}" subnet_id = azurerm_subnet.my_subnet.id private_ip_address_allocation = "Dynamic" primary = true } } # Associate Network Interface to the Backend Pool of the Load Balancer resource "azurerm_network_interface_backend_address_pool_association" "my_nic_lb_pool" { count = 2 network_interface_id = azurerm_network_interface.my_nic[count.index].id ip_configuration_name = "ipconfig${count.index}" backend_address_pool_id = azurerm_lb_backend_address_pool.my_lb_pool.id } # Create Virtual Machine resource "azurerm_linux_virtual_machine" "my_vm" { count = 2 name = "${var.virtual_machine_name}${count.index}" location = azurerm_resource_group.my_resource_group.location resource_group_name = azurerm_resource_group.my_resource_group.name network_interface_ids = [azurerm_network_interface.my_nic[count.index].id] size = var.virtual_machine_size os_disk { name = "${var.disk_name}${count.index}" caching = "ReadWrite" storage_account_type = var.redundancy_type } source_image_reference { publisher = "Canonical" offer = "0001-com-ubuntu-server-jammy" sku = "22_04-lts-gen2" version = "latest" } admin_username = var.username admin_password = var.password disable_password_authentication = false } # Enable virtual machine extension and install Nginx resource "azurerm_virtual_machine_extension" "my_vm_extension" { count = 2 name = "Nginx" virtual_machine_id = azurerm_linux_virtual_machine.my_vm[count.index].id publisher = "Microsoft.Azure.Extensions" type = "CustomScript" type_handler_version = "2.0" settings = <<SETTINGS { "commandToExecute": "sudo apt-get update && sudo apt-get install nginx -y && echo \"Hello World from $(hostname)\" > /var/www/html/index.html && sudo systemctl restart nginx" } SETTINGS } # Create Public Load Balancer resource "azurerm_lb" "my_lb" { name = var.load_balancer_name location = azurerm_resource_group.my_resource_group.location resource_group_name = azurerm_resource_group.my_resource_group.name sku = "Standard" frontend_ip_configuration { name = var.public_ip_name public_ip_address_id = azurerm_public_ip.my_public_ip.id } } resource "azurerm_lb_backend_address_pool" "my_lb_pool" { loadbalancer_id = azurerm_lb.my_lb.id name = "test-pool" } resource "azurerm_lb_probe" "my_lb_probe" { resource_group_name = azurerm_resource_group.my_resource_group.name loadbalancer_id = azurerm_lb.my_lb.id name = "test-probe" port = 80 } resource "azurerm_lb_rule" "my_lb_rule" { resource_group_name = azurerm_resource_group.my_resource_group.name loadbalancer_id = azurerm_lb.my_lb.id name = "test-rule" protocol = "Tcp" frontend_port = 80 backend_port = 80 disable_outbound_snat = true frontend_ip_configuration_name = var.public_ip_name probe_id = azurerm_lb_probe.my_lb_probe.id backend_address_pool_ids = [azurerm_lb_backend_address_pool.my_lb_pool.id] } resource "azurerm_lb_outbound_rule" "my_lboutbound_rule" { resource_group_name = azurerm_resource_group.my_resource_group.name name = "test-outbound" loadbalancer_id = azurerm_lb.my_lb.id protocol = "Tcp" backend_address_pool_id = azurerm_lb_backend_address_pool.my_lb_pool.id frontend_ip_configuration { name = var.public_ip_name } }
创建名为
variables.tf
的文件并插入下列代码:variable "resource_group_location" { type = string default = "eastus" description = "Location of the resource group." } variable "username" { type = string default = "microsoft" description = "The username for the local account that will be created on the new VM." } variable "password" { type = string default = "Microsoft@123" description = "The passoword for the local account that will be created on the new VM." } variable "virtual_network_name" { type = string default = "test-vnet" description = "Name of the Virtual Network." } variable "subnet_name" { type = string default = "test-subnet" description = "Name of the subnet." } variable public_ip_name { type = string default = "test-public-ip" description = "Name of the Public IP." } variable network_security_group_name { type = string default = "test-nsg" description = "Name of the Network Security Group." } variable "network_interface_name" { type = string default = "test-nic" description = "Name of the Network Interface." } variable "virtual_machine_name" { type = string default = "test-vm" description = "Name of the Virtual Machine." } variable "virtual_machine_size" { type = string default = "Standard_B2s" description = "Size or SKU of the Virtual Machine." } variable "disk_name" { type = string default = "test-disk" description = "Name of the OS disk of the Virtual Machine." } variable "redundancy_type" { type = string default = "Standard_LRS" description = "Storage redundancy type of the OS disk." } variable "load_balancer_name" { type = string default = "test-lb" description = "Name of the Load Balancer." }
创建名为
outputs.tf
的文件并插入下列代码:output "public_ip_address" { value = "http://${azurerm_public_ip.my_public_ip.ip_address}" }
初始化 Terraform
运行 terraform init,将 Terraform 部署进行初始化。 此命令将下载管理 Azure 资源所需的 Azure 提供程序。
terraform init -upgrade
要点:
- 参数
-upgrade
可将必要的提供程序插件升级到符合配置版本约束的最新版本。
创建 Terraform 执行计划
运行 terraform plan 以创建执行计划。
terraform plan -out main.tfplan
要点:
terraform plan
命令将创建一个执行计划,但不会执行它。 它会确定创建配置文件中指定的配置需要执行哪些操作。 此模式允许你在对实际资源进行任何更改之前验证执行计划是否符合预期。- 使用可选
-out
参数可以为计划指定输出文件。 使用-out
参数可以确保所查看的计划与所应用的计划完全一致。
应用 Terraform 执行计划
运行 terraform apply,将执行计划应用到云基础结构。
terraform apply main.tfplan
要点:
- 示例
terraform apply
命令假设你先前运行了terraform plan -out main.tfplan
。 - 如果为
-out
参数指定了不同的文件名,请在对terraform apply
的调用中使用该相同文件名。 - 如果未使用
-out
参数,请调用不带任何参数的terraform apply
。
验证结果
应用执行计划时,Terraform 会显示前端公共 IP 地址。 如果已清除屏幕,则可以使用以下 Terraform 命令检索该值:
echo $(terraform output -raw public_ip_address)
将该公共 IP 地址粘贴到浏览器的地址栏。 Nginx Web 服务器的自定义 VM 页会显示在浏览器中。
清理资源
不再需要通过 Terraform 创建的资源时,请执行以下步骤:
运行 terraform plan 并指定
destroy
标志。terraform plan -destroy -out main.destroy.tfplan
要点:
terraform plan
命令将创建一个执行计划,但不会执行它。 它会确定创建配置文件中指定的配置需要执行哪些操作。 此模式允许你在对实际资源进行任何更改之前验证执行计划是否符合预期。- 使用可选
-out
参数可以为计划指定输出文件。 使用-out
参数可以确保所查看的计划与所应用的计划完全一致。
运行 terraform apply 以应用执行计划。
terraform apply main.destroy.tfplan
Azure 上的 Terraform 故障排除
排查在 Azure 上使用 Terraform 时遇到的常见问题
后续步骤
在本快速入门中,请执行以下操作:
- 已创建了一个 Azure 负载均衡器
- 已将 2 个 VM 附加到负载均衡器
- 测试了负载均衡器
若要详细了解 Azure 负载均衡器,请继续学习: