基础设施即代码简介(第三部分):使用 Terraform 和 Azure 进行 IaC 实践





5.00/5 (2投票s)
如何自动配置资源。
本系列的第一篇文章介绍了基础设施即代码 (IaC) 的基本概念及其解决的问题。它还解释了特定厂商和多云 IaC 工具之间的区别以及它们支持的模板语言。
本系列的第二篇文章介绍了 Azure ARM 模板,并解释了 JSON 和 Bicep 的语法差异。然后,使用 Bicep,它提供了一个教程,通过创建多个虚拟机 (VM) 及其 PostgreSQL 数据库依赖项来创建用于 Web 应用的基础设施模板。
这篇最后的文章使用 HCL 编写 Terraform 计划,以创建多个虚拟机和 SQL Server 数据库来部署 Web 应用的基础设施。我们还将将其与上一篇文章中使用的 ARM 模板进行对比,并强调两种语言之间的相似之处和差异。
请按照本教程的步骤操作,让您的 Azure 部署运行起来,并查看此GitHub 仓库以查看最终的 IaC 模板。
要求
要遵循本教程,请务必
- 遵循说明部分,如果您还没有订阅,请创建一个免费的 Azure 帐户。
- 安装Azure CLI。
- 下载 Terraform CLI.
Terraform 和 HCL
HashiCorp Terraform 是最流行的 IaC 工具之一。Terraform 是开源的,支持大量云提供商。Terraform 语言的创建者使用一种名为 HashiCorp Configuration Language (HCL) 的语法来定义它。HCL 是一种声明式配置文件语言,旨在让人们易于阅读。此外,它还有一种基于 JSON 的变体,机器可以更有效地解析。
创建 Terraform 模板以部署 VM 和 Azure SQL 数据库
本节使用 Terraform 计划创建一个模板,该模板通过创建多个 VM 和 Azure SQL Server 数据库来部署 Web 应用的基础设施。此过程的结构如下图所示
与本系列第二篇文章类似,这里的目标是创建两种类型的资源:VM(多个)和 Azure SQL Server。这些资源依赖于我们需要创建的辅助资源。
构建和执行 Terraform 计划
运行以下命令以启动登录会话
> az login
然后运行以下命令来定义您的活动订阅
> az account set --subscription "YOUR-SUBSCRIPTION-NAME"
现在,我们将使用 HCL 语法构建一个 Terraform 模板。稍后,我们将使用 Terraform 命令行界面 (CLI) 来运行 terraform 命令及其子命令,以创建 Terraform 计划并应用它来部署我们的基础设施。
将 Azure 资源管理器定义为 Terraform 提供程序
与我们在上一篇文章中配置的 ARM 模板不同,Terraform 不直接与云交互。相反,它依赖于充当中介的提供程序,使它能够与 Azure 等云提供商进行交互。在我们的例子中,Terraform 需要一个 Azure 资源管理器提供程序,以便它可以创建和使用 Azure 资源。
创建一个名为 providers.tf 的新文件,其中包含以下代码
terraform {
required_version = ">=0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.0"
}
}
}
provider "azurerm" {
features {}
}
声明资源组
让我们创建一个 main.tf 文件,其中包含以下代码
variable "vm_instance_count" {
description = "Specify the number of vm instances."
type = number
default = 3
}
resource "azurerm_resource_group" "rg" {
name = "t3rr4f0rm-rg"
location = "eastus"
}
在上面的代码中,我们定义了一个 vm_instance_count
变量。vm_instance_count
参数指定了我们部署的 VM 实例数量。
接下来,我们使用 resource
关键字添加了一个资源声明。我们将我们的资源组命名为 t3rr4f0rm-rg
,并将其位置设置为 East US,为其设置符号名称 rg
。就像命令式编程语言中的变量名一样,这个符号名称在 Terraform 文件中的其他部分代表资源组。
声明网络安全组
网络安全组 (NSG) 会过滤到虚拟网络中的 Azure 资源以及从这些资源传出的网络流量。网络安全组规则允许或拒绝我们创建的 VM 和数据库资源的入站或出站流量。这些规则允许我们指定源、目标、端口和协议。
resource "azurerm_network_security_group" "myterraformnsg" {
name = "t3rr4f0rm-nsg"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "SSH"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
声明虚拟网络
虚拟网络 (VNet) 使我们的 VM 和数据库服务器能够安全地相互通信、与 Internet 通信以及与本地网络通信。要创建 VNet,请将此代码添加到 main.tf 文件中
resource "azurerm_virtual_network" "myterraformnetwork" {
name = "t3rr4f0rm-vn"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_subnet" "myterraformsubnet" {
name = "t3rr4f0rm-sn"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.myterraformnetwork.name
address_prefixes = ["10.0.1.0/24"]
}
声明公共 IP
VM 依赖于网络接口,而网络接口又依赖于公共 IP (PIP) 地址。要创建公共 IP 地址,请在 main.tf 文件中声明以下资源
resource "azurerm_public_ip" "publicIPs" {
count = var.vm_instance_count
name = "t3rr4f0rm-ip-${count.index}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Dynamic"
}
您可以使用 count
属性迭代集合中的项并创建多个资源。上面的代码使用整数索引来创建多个公共 IP 地址实例。IP 地址的数量取决于 vm_instance_count
变量。
声明网络接口
在 Azure 中,网络接口连接 VM 和底层软件网络。在这里,我们声明了一个动态 public
IP 地址的网络接口集合。
resource "azurerm_network_interface" "myterraformnic" {
count = var.vm_instance_count
name = "t3rr4f0rm-nic-${count.index}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "ipconfig1"
public_ip_address_id = azurerm_public_ip.publicIPs[count.index].id
private_ip_address_allocation = "Dynamic"
subnet_id = azurerm_subnet.myterraformsubnet.id
}
}
resource "azurerm_network_interface_security_group_association" "example" {
count = var.vm_instance_count
network_interface_id = azurerm_network_interface.myterraformnic[count.index].id
network_security_group_id = azurerm_network_security_group.myterraformnsg.id
}
声明虚拟机
在声明辅助资源之后,我们终于可以声明一个 VM 集合了。但您必须找出您的订阅中有哪些 VM 大小可用。幸运的是,有一个 Azure CLI 命令可以做到这一点。例如,由于我将 VM 托管在 East US 区域,我可以运行以下命令并选择一个 Restrictions
列值为 None
的 VM 大小
> az vm list-skus --location eastus --all --output table
Name Zones Restrictions
------------------------- ------- -----------------------------------
Standard_B2s 1,2,3 None
Standard_B4ms 1,2,3 None
Standard_D1 3 ['NotAvailableForSubscription, ...
Standard_D11 3 ['NotAvailableForSubscription, ...
现在,您可以使用适当的 VM 大小来定义您的 VM 资源。在我的例子中,我选择了 Standard_B2s
,因为它在 East US 区域的订阅中可用。但请注意,您可能需要选择其他 VM 大小。其他 VM 属性包括存储配置文件、操作系统和网络配置文件
resource "azurerm_linux_virtual_machine" "myterraformvm" {
count = var.vm_instance_count
name = "t3rr4f0rm-vm-${count.index}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.myterraformnic[count.index].id]
size = "Standard_B2s"
os_disk {
name = "t3rr4f0rm-os-disk-${count.index}"
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
computer_name = "t3rr4f0rm-vm-${count.index}"
admin_username = "azureuser"
admin_password = "Adm1nP@55w0rd"
disable_password_authentication = false
}
声明 Azure SQL Server 数据库实例
最后,我们声明一个 Azure SQL Server 数据库资源,即数据库即服务。我们定义 SQL Server 版本和管理员凭据
resource "azurerm_sql_server" "example" {
name = "t3rr4f0rmsqlserver"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
version = "12.0"
administrator_login = "MyAdministrator"
administrator_login_password = "Adm1nP@55w0rd"
}
使用 Terraform 文件进行部署
让我们初始化一个包含 Terraform 配置文件的工作目录。这是在编写新的 Terraform 配置后应运行的第一个命令
> terraform init
运行 terraform plan 命令,根据 main.tf 文件创建执行计划
terraform plan -out main.tfplan
在上面的代码中,terraform plan 命令生成一个执行计划,该计划计算创建 HCL 语法声明的配置所需的动作。此计划步骤允许您在创建新资源或更改现有资源之前审查和批准执行计划。
最后,运行 terraform apply
命令将执行计划应用于您的云基础设施
terraform apply main.tfplan
上面的 terraform apply
命令执行之前创建的 main.tfplan Terraform 计划文件,并创建或修改您云基础设施中的资源。
最终部署的基础设施
现在让我们看看我们在 Azure 上完全部署的基础设施是什么样的。
在 Azure 门户中,打开 t3rr4f0rm-rg
资源组,然后单击 资源可视化工具 菜单。资源可视化工具允许您查看和理解通过 Terraform 模板部署的组件。
要更详细地查看已部署的资源,请转到 Azure 门户仪表板,然后单击 所有资源。
Bicep 与 HCL 对比
Azure Bicep 和 HashiCorp 的 HCL 都是声明式语言,并且两者都提供 CLI 工具,我们可以使用它们来构建和部署云应用程序。我们在本系列第二篇文章中使用了 Bicep 来创建 ARM 模板。在本篇文章中,我们使用 HCL 构建了 Terraform 计划。与我们在上一篇文章中配置的 ARM 模板不同,Terraform 不直接与云交互。相反,它依赖于充当中介的提供程序,使它能够与 Azure 等云提供商进行交互。在我们的例子中,Terraform 需要一个 Azure 资源管理器提供程序,以便它可以创建和使用 Azure 资源。
ARM 模板和 Terraform 计划与云交互的不同方式,使得在比较 ARM 模板和 Terraform 计划来管理云基础设施时,考虑目标云环境至关重要。Bicep 特定于 Azure,不打算与其他云服务一起使用。Terraform 是一种多用途语言,您可以在不同的云环境中使用它。
如果您的目标是自动化部署到以下环境,Terraform 可能是更好的选择,因为它支持
- 虚拟化环境。
- 多种云环境,例如 Azure 与其他云。
- 本地工作负载。
然而,如果您的公司正在使用 ARM 模板并且主要或仅使用 Azure Cloud 来托管基础设施,那么 Bicep 可能是更好的选择。
结论
在这篇 IaC 系列的最后一篇文章中,我们介绍了 Terraform 和 HashiCorp Configuration Language (HCL)。我们使用 HCL 编写了 Terraform 计划,该计划通过创建多个虚拟机和 SQL Server 数据库来部署 Web 应用的基础设施。
使用 HCL 语法,我们创建了一个模板来部署 Web 应用的基础设施,方法是创建多个虚拟机和一个 Azure SQL 数据库。在文章结尾,我们演示了在 Azure 上完全部署的基础设施。
最后,本文比较了 Terraform 与 Bicep(我们在上一篇文章中使用过),并解释了两种语言之间的一些相似之处和差异。
您可以通过访问 Azure 网站,了解更多关于如何构建一致的 Azure 基础设施和 IaC 的信息。
要了解更多关于如何使用 Bicep 定义 Azure 网络资源的信息,请参阅资源使用 Bicep 创建虚拟网络资源。