terraform init 期间的“变量可能不会在此处使用”

我正在使用 Terraform 雪花插件。我想在 ${terraform.workspace} 范围内使用 terraform 变量。

terraform {
  required_providers {
    snowflake = {
      source  = "chanzuckerberg/snowflake"
      version = "0.20.0"
    }
  }
  backend "s3" {
    bucket         = "data-pf-terraform-backend-${terraform.workspace}"
    key            = "backend/singlife/landing"
    region         = "ap-southeast-1"
    dynamodb_table = "data-pf-snowflake-terraform-state-lock-${terraform.workspace}"
  }
}

但我得到了这个错误。变量在此范围内不可用?

Error: Variables not allowed

  on provider.tf line 9, in terraform:
   9:     bucket         = "data-pf-terraform-backend-${terraform.workspace}"

Variables may not be used here.

Error: Variables not allowed

  on provider.tf line 12, in terraform:
  12:     dynamodb_table = "data-pf-snowflake-terraform-state-lock-${terraform.workspace}"

Variables may not be used here.
stack overflow "Variables may not be used here" during terraform init
原文答案

答案:

作者头像
  • 设置后端.tf

    terraform {
      backend "azurerm" {}
    }
    
  • 创建文件 backend.conf

    storage_account_name = "deploymanager"
    container_name       = "terraform"
    key                  = "production.terraform.tfstate"
    
  • 跑:

    terraform init -backend-config=backend.conf
    
作者头像

terraform backend docs 状态:

后端块不能引用命名值(如输入变量、本地变量或数据源属性)。

但是, s3 backend docs 向您展示了如何根据当前的 workspace 对一些 s3 存储进行分区,因此每个工作区都有自己的独立状态文件。您只是不能为每个工作区指定不同的存储桶。您只能为所有工作空间指定一个存储桶,但 s3 后端将添加 workspace prefix to the path

使用非默认工作区时,状态路径将为 /workspace_key_prefix/workspace_name/key(另请参见 workspace_key_prefix 配置)。

一张发电机表足以满足所有工作空间。所以只需使用:

  backend "s3" {
    bucket         = "data-pf-terraform-backend"
    key            = "terraform.tfstate"
    region         = "ap-southeast-1"
    dynamodb_table = "data-pf-snowflake-terraform-state-lock"
  }

并在部署前酌情切换工作空间。

作者头像

首先检查Jhonny的解决方案:

(保留这个供历史参考)


似乎是Terraform中更常见问题的特定实例:串联变量。

使用当地人来加以修复。请参阅 https://www.terraform.io/docs/configuration/locals.html

https://stackoverflow.com/a/61506549/132438 的示例:

locals {
  BUCKET_NAME = [
    "bh.${var.TENANT_NAME}.o365.attachments",
    "bh.${var.TENANT_NAME}.o365.eml"
  ]
}

resource "aws_s3_bucket" "b" {
  bucket = "${element(local.BUCKET_NAME, 2)}"
  acl    = "private"
}