怎样在 Vultr 对象存储中存储 Terraform 状态

介绍

Terraform 存储有关已配置资源的状态信息以跟踪元数据,通过减少 API 调用来提高性能,并将本地配置与远程资源同步。 该状态还允许 Terraform 跟踪何时需要删除您已从本地配置中删除的远程资源。

当您使用 Terraform 管理基础架构时,您必须在本地状态文件或远程后端跟踪其状态,因为它将您的本地配置文件与现有资源联系起来。 丢失或破坏状态可能会导致手动操作的悲惨夜晚 terraform import-ing 资源回到一个新的状态文件。

远程存储状态而不是本地文件有一些优势。 它允许多个团队成员在基础设施上工作,而无需跟踪谁拥有当前状态文件。 但是,像 git 这样的源代码控制系统并不理想,因为状态文件可能包含可能违反您的 IT 隐私政策和最佳实践的敏感数据和变量。

具有适当访问控制的对象存储是一个很好的解决方案。 本指南介绍了怎样使用 Vultr 对象存储来存储您的 Terraform 状态。

Vultr 对象存储不提供文件锁定。 因此,您应该采取程序步骤来确保一次只有一个人更新对象存储中的 Terraform 状态。

笔记

  • 您需要一台 Mac 或 Linux 本地计算机来遵循本指南,或者需要一台安装了 WSL 的 Windows 计算机。
  • 本指南使用一些“AWS”或“S3”命名约定来与 Terraform 兼容。 信息存储在 Vultr 对象存储中。

入门

  1. 登录到 Vultr 客户门户并创建一个 新的对象存储订阅.

  2. 打开订阅的概览页面。 在 S3 Credentials 部分中,请注意 密钥, 访问密钥, 和 主机名.

    本指南使用 ewr1.vultrobjects.com 为主机名。

  3. 点击 标签。 创建一个存储桶来存储您的 Terraform 状态。 本指南使用存储桶名称 terraform-state-example.

    已创建存储桶

  4. 在本地命令 shell 中,将密钥导出为环境变量: AWS_SECRET_ACCESS_KEYAWS_ACCESS_KEY.

    $ export AWS_ACCESS_KEY='your access key'
    $ export AWS_SECRET_ACCESS_KEY='your secret key'
    
  5. 在你的 .tf 文件,创建一个 s3 后端配置块。 使用以下信息,替换 terraform-状态-example 使用您的存储桶名称。

    terraform {
      backend "s3" {
        bucket                      = "terraform-state-example"
        key                         = "terraform.tfstate"
        endpoint                    = "ewr1.vultrobjects.com"
        region                      = "us-east-1"
        skip_credentials_validation = true
      }
    }
    
  6. terraform init 初始化后端。

    $ terraform init
    
    Initializing the backend...
    
    Successfully configured the backend "s3"! Terraform will automatically
    use this backend unless the backend configuration changes.
    

    如果您有预先存在的状态,您将看到一个将现有状态复制到对象存储的选项,如下所示:

        Initializing the backend...
    Do you want to copy existing state to the new backend?
      Pre-existing state was found while migrating the previous "local" backend to the
      newly configured "s3" backend. No existing state was found in the newly
      configured "s3" backend. Do you want to copy this state to the new "s3"
      backend? Enter "yes" to copy and "no" to start with an empty state.
    
      Enter a value:
    

    如果要保留当前状态,请选择“是的”。

  7. terraform apply 更新您的配置。 检查您的对象存储桶以确认状态文件已成功存储。

    状态存储

此远程状态将在后续使用 planapply 运行。 如果将 Terraform 配置移动或克隆到新机器或位置,请运行 terraform init 再次与远程后端同步。

环境变量

使用 Terraform s3 后端需要这些环境变量:

  • AWS_ACCESS_KEY:使用对象存储概览选项卡中的值,如上所示。
  • AWS_SECRET_ACCESS_KEY:此值也可在概览选项卡上找到。
  • VULTR_API_KEY: 使用 API 密钥 从客户门户 并确保您已在 访问控制 该页面的部分。

S3 配置块详细信息

参考这个 example 以下详细信息的配置块:

  backend "s3" {
    bucket                      = "terraform-state-example"
    key                         = "terraform.tfstate"
    endpoint                    = "ewr1.vultrobjects.com"
    region                      = "us-east-1"
    skip_credentials_validation = true
  }
  • “s3”: 是必需的后端名称。 始终使用此值。
  • :使用您在 Web 界面中选择的存储桶名称。
  • 钥匙: 这可以是任意名称,但是 terraform.tfstate 是一个不错的选择。 如果您有多个环境或项目,则应为每个环境或项目使用不同的名称,例如 dev.tfstate, qa.tfstate, 或者 prod.tfstate, 等等。
  • 端点:对象存储位置的主机名。
  • 地区: 采用 us-east-1,尽管 Vultr 对象存储会忽略此值。
  • skip_credentials_validation: 一定是 true 用于 Vultr 对象存储。

访问控制

传输到 Vultr 对象存储的文件(对象)是 私人的 默认情况下,需要您的密钥才能访问它们。 如果您修改对象或存储桶权限,请小心谨慎,因为 Terraform 状态文件可能包含敏感信息。

完整示例

这是一个完整的 Terraform example 演示怎样在 Vultr 部署 FreeBSD 服务器并将 Terraform 状态存储在对象存储中。 这 example 假设如下:

  • 环境变量 AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY, 和 VULTR_API_KEY如上所述导出。
  • 您的本地 IP 地址具有 API 访问权限。
  • 您已经创建了一个对象存储桶。 更改 terraform-state-example 到您在 example 以下。

示例步骤

  1. 在本地机器上创建一个项目目录。
  2. 创建一个 example.tf 文件在你的文本编辑器中。

    terraform {
    
      # Use the latest provider release: https://github.com/vultr/terraform-provider-vultr/releases
      required_providers {
        vultr = {
          source  = "vultr/vultr"
          version = "2.11.1"
        }
      }
    
      # Configure the S3 backend
      backend "s3" {
        bucket                      = "terraform-state-example"
        key                         = "terraform.tfstate"
        endpoint                    = "ewr1.vultrobjects.com"
        region                      = "us-east-1"
        skip_credentials_validation = true
      }
    }
    
    # Set the API rate limit
    provider "vultr" {
      rate_limit  = 700
      retry_limit = 3
    }
    
    # Store the New Jersey location code to a variable.
    data "vultr_region" "ny" {
      filter {
        name   = "city"
        values = ["New Jersey"]
      }
    }
    
    # Store the FreeBSD 13 OS code to a variable.
    data "vultr_os" "freebsd" {
      filter {
        name   = "name"
        values = ["FreeBSD 13 x64"]
      }
    }
    
    # Install a public SSH key on the new server.
    resource "vultr_ssh_key" "pub_key" {
      name    = "pub_key"
      ssh_key = "... your public SSH key here ..."
    }
    
    # Deploy a Server using the High Frequency, 2 Core, 4 GB RAM plan. 
    resource "vultr_instance" "freebsd" {
      plan        = "vhf-2c-4gb"
      region      = data.vultr_region.ny.id
      os_id       = data.vultr_os.freebsd.id
      label       = "freebsd"
      tags        = ["runbsd"]
      hostname    = "freebsd.mydomain.tld"
      ssh_key_ids = [vultr_ssh_key.pub_key.id]
    }
    
    # Display the server IP address when complete.
    output "freebsd_main_ip" {
      value = vultr_instance.freebsd.main_ip
    }
    
  3. terraform init

  4. terraform plan
  5. terraform apply
  6. 您可以以 root 身份通过 SSH 连接到部署后打印的 IP 地址的服务器。

更多信息

要了解有关 Terraform 状态和 S3 的更多信息,请参阅 HasiCorp 的以下资源:

注:本教程在Vultr VPS上测试通过,如需部署请前往Vultr.com