在 Azure 存储中存储 Terraform 状态

使用 Terraform 可以定义、预览和部署云基础结构。 使用 Terraform 时,请使用 HCL 语法来创建配置文件。 利用 HCL 语法,可指定 Azure 这样的云提供程序和构成云基础结构的元素。 创建配置文件后,请创建一个执行计划,利用该计划,可在部署基础结构更改之前先预览这些更改。 验证了更改后,请应用该执行计划以部署基础结构。

Terraform 状态用于对已部署资源和 Terraform 配置进行对帐。 借助“状态”,Terraform 就可以知道要添加、更新或删除哪些 Azure 资源。

Terraform 状态会默认本地存储,但由于以下原因,存储不理想:

  • 本地状态不适用于团队或协作环境。
  • Terraform 状态可能包含敏感信息。
  • 本地存储状态会增加意外删除的可能性。

在本文中,学习如何:

  • 创建 Azure 存储帐户
  • 使用 Azure 存储来存储远程 Terraform 状态。
  • 了解状态锁定
  • 了解静态加密

1.配置环境

  • Azure 订阅:如果没有 Azure 订阅,请在开始之前创建一个免费帐户。

2. 配置远程状态存储帐户

必须先创建存储帐户,才能将 Azure 存储用作后端。

运行以下命令或配置,来创建一个 Azure 存储帐户和容器:

#!/bin/bash

RESOURCE_GROUP_NAME=tfstate
STORAGE_ACCOUNT_NAME=tfstate$RANDOM
CONTAINER_NAME=tfstate

# Create resource group
az group create --name $RESOURCE_GROUP_NAME --location eastus

# Create storage account
az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob

# Create blob container
az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME

要点

  • Azure 存储帐户需要具有全局唯一名称。 若要详细了解如何对存储帐户名称进行故障排除,请参阅消除存储帐户名称方面的错误
  • Terraform 状态以纯文本形式存储,可能包含机密。 如果状态受到错误保护,则未经授权的系统访问和数据丢失可能会导致。
  • 在此示例中,Terraform 使用访问密钥向 Azure 存储帐户进行身份验证。 在生产部署中,建议评估 azurerm 后端支持的可用 身份验证选项 ,并针对用例使用最安全的选项。
  • 在此示例中,允许对此 Azure 存储帐户进行公用网络访问。 在生产部署中,建议使用 存储防火墙、服务终结点或专用终结点限制对此存储帐户的访问。

3. 配置 Terraform 后端状态

若要配置后端状态,需要以下 Azure 存储信息:

  • storage_account_name:Azure 存储帐户的名称。
  • container_name:Blob 容器的名称。
  • key:要创建的状态存储文件的名称。
  • access_key:存储访问密钥。

其中每个值都可以在 Terraform 配置文件中或在命令行上指定。 建议对 access_key 值使用环境变量。 使用环境变量可防止将密钥写入磁盘。

运行以下命令来获取存储访问密钥,并将其存储为环境变量:

ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
export ARM_ACCESS_KEY=$ACCOUNT_KEY

要点

  • 若要进一步保护 Azure 存储帐户访问密钥,请将其存储在 Azure Key Vault 中。 然后可使用如下命令设置该环境变量。 有关 Azure Key Vault 的详细信息,请参阅 Azure Key Vault 文档

    export ARM_ACCESS_KEY=$(az keyvault secret show --name terraform-backend-key --vault-name myKeyVault --query value -o tsv)
    

使用 backend 配置块创建 Terraform 配置。

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.0"
    }
  }
  backend "azurerm" {
      resource_group_name  = "tfstate"
      storage_account_name = "<storage_account_name>"
      container_name       = "tfstate"
      key                  = "terraform.tfstate"
  }

}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "state-demo-secure" {
  name     = "state-demo"
  location = "eastus"
}

<storage_account_name> 替换为 Azure 存储帐户的名称。

运行以下命令来初始化配置:

terraform init

运行以下命令来运行配置:

terraform apply

现可在 Azure 存储 blob 中找到状态文件。

4. 了解状态锁定

在执行任何写入状态的操作之前,Azure 存储 blob 都会自动锁定。 此模式可防止并发状态操作(可能导致损坏)。

有关详细信息,请参阅 Terraform 文档中的状态锁定

通过 Azure 门户或其他 Azure 管理工具检查 blob 时,可以查看该锁。

Azure blob with lock

5. 了解静态加密

Azure blob 中存储的数据会在保存之前进行加密。 如有需要,Terraform 会从后端检索状态并将其存储在本地内存中。 如果使用此模式,则永远不会将状态写入本地磁盘。

有关 Azure 存储加密的详细信息,请参阅静态数据的 Azure 存储服务加密

Azure 上的 Terraform 故障排除

排查在 Azure 上使用 Terraform 时遇到的常见问题

后续步骤