【问题标题】:terraform backend state file storage using keys instead of AD accountterraform 后端状态文件存储使用密钥而不是 AD 帐户
【发布时间】:2021-11-17 08:27:05
【问题描述】:

似乎 Terraform 在持久保存到 Azure 存储帐户时将密钥用于后端状态文件。我希望为不同的服务主体使用带有专用文件夹的单个存储帐户,但没有跨文件夹写访问权限。我试图避免不同服务主体意外覆盖状态文件。但由于 Terraform 使用密钥来更新存储帐户,因此每个服务主体在技术上都有权更新每个文件。并且开发人员必须注意不要意外引用错误的状态文件进行更新。关于如何防止这种情况的任何想法?

【问题讨论】:

  • 你好@JakeUT,有什么更新吗??我可以知道问题是否解决了吗?

标签: terraform azure-storage azure-storage-account


【解决方案1】:

您可以使用为容器生成的 SAS 令牌,仅供该服务主体使用,其他服务主体不得使用。

我用下面的东西进行了测试:

data "terraform_remote_state" "foo" {
  backend = "azurerm"
  config = {
    storage_account_name = "cloudshellansuman"
    container_name       = "test"
    key                  = "prod.terraform.tfstate"
   sas_token = "sp=racwdl&st=2021-09-28T05:49:01Z&se=2023-04-01T13:49:01Z&sv=2020-08-04&sr=c&sig=O87nHO01sPxxxxxxxxxxxxxsyQGQGLSYzlp6F8%3D"

  }
}
provider "azurerm" {
  features {}
  use_msi = true
  subscription_id = "948d4068-xxxxx-xxxxxx-xxxxxxxxxx"
  tenant_id = "72f988bf-xxxx-xxxxx-xxxxxx-xxxxxxx"
}

resource "azurerm_resource_group" "test" {
    name="xterraformtest12345"
    location ="east us"
}

但是,如果我将容器名称更改为另一个容器,那么我将无法写入,因为它会错误提示身份验证失败,因为 SAS 令牌用于 Test 容器而不是 Test1 容器。

有关如何为容器生成 SAS 令牌以及如何为 terraform 设置后端 azurerm 的更多信息,请参考以下链接:

Generate shared access signature (SAS) token for containers and blobs with Azure portal. | Microsoft Docs

Use Azure storage for Terraform remote state


在将storage blob data contributor/owner 角色分配给将使用该特定容器的服务主体之后,您可以将容器身份验证方法设置为azure ad user account

然后你可以使用类似下面的东西:

data "terraform_remote_state" "foo" {
  backend = "azurerm"
  config = {
    storage_account_name = "cloudshellansuman"
    container_name       = "test1"
    key                  = "prod.terraform.tfstate"
    subscription_id = "b83c1ed3-xxxx-xxxxxx-xxxxxxx"
    tenant_id = "72f988bf-xxx-xxx-xxx-xxx-xxxxxx"
    client_id = "f6a2f33d-xxxx-xxxx-xxx-xxxxx"
    client_secret = "y5L7Q~oiMOoGCxm7fK~xxxxxxxxxxxxxxxxx"
    use_azuread_auth =true
  }
}

provider "azurerm"{
    subscription_id = "b83c1ed3-xxxx-xxxxxx-xxxxxxx"
    tenant_id = "72f988bf-xxx-xxx-xxx-xxx-xxxxxx"
    client_id = "f6a2f33d-xxxx-xxxx-xxx-xxxxx"
    client_secret = "y5L7Q~oiMOoGCxm7fK~xxxxxxxxxxxxxxxxx"
    features {}
}

data "azurerm_resource_group" "test" {
    name="resourcegroupname"
}

resource "azurerm_virtual_network" "example" {
  name                = "example-network"
  resource_group_name = data.azurerm_resource_group.test.name
  location            = data.azurerm_resource_group.test.location
  address_space       = ["10.254.0.0/16"]
}

输出:

如果服务主体没有为容器分配角色,那么它将给出如下错误:

注意:对于第一个场景,我使用了托管系统身份,但同样可以用于服务主体。

【讨论】:

  • 感谢 AnsumanBal-MT!这看起来很有希望。让我对此进行一些测试,看看它是否能达到我希望的粒度!
  • 第一个解决方案适用于我的场景,因为我有文件夹。看来您也可以在文件夹级别生成 SAS 令牌。如果我将所有东西都放在单独的容器中,那么第二种解决方案将起作用,不幸的是这不是我的设计。所以再次感谢您的帮助!!... :)
猜你喜欢
  • 1970-01-01
  • 2021-10-29
  • 2021-05-20
  • 2019-07-28
  • 2019-05-02
  • 2021-04-23
  • 2021-08-01
  • 2020-11-02
  • 1970-01-01
相关资源
最近更新 更多