使用 Terraform 在具有网络规则的存储帐户中创建 Azure 存储容器

Creating Azure Storage Containers in a storage account with network rules, with Terraform

我正在尝试编写 Terraform,它将创建一个 Azure 存储帐户,然后在其中创建一堆存储容器。一个重要的细节是存储帐户具有限制访问特定地址 space 的网络规则。这导致容器创建失败。

我设法通过使用 azurerm_storage_account_network_rules 解决了这个问题,具体取决于容器,因此不会阻止它们的创建。像这样:

resource "azurerm_storage_account" "this" {
  name                = local.storage_name
  resource_group_name = azurerm_resource_group.this.name
  location            = var.location

  account_tier             = "Standard"
  account_kind             = "StorageV2"
  is_hns_enabled           = true
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "data" {
  for_each = toset(var.storage_containers)

  name                  = each.value
  storage_account_name  = azurerm_storage_account.this.name
  container_access_type = "private"
}

# FIXME This order prevents destruction of infrastructure :(
resource "azurerm_storage_account_network_rules" "this" {
  storage_account_id   = azurerm_storage_account.this.id

  default_action = "Deny"
  bypass         = ["AzureServices"]

  virtual_network_subnet_ids = [
    # Some address space here...
  ]

  # NOTE The order here matters: We cannot create storage
  # containers once the network rules are locked down
  depends_on = [
    azurerm_storage_container.data
  ]
}

这适用于创建基础结构,但是当我尝试 terraform destroy 时,我收到 403 身份验证错误:

Error: retrieving Container "data" (Account "XXX" / Resource Group "XXX"): containers.Client#GetProperties: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailure" Message="This request is not authorized to perform this operation.\nRequestId:XXX\nTime:XXX"

这是我的服务主体,它在同一订阅中具有 ContributorUser Access Administrator 角色。有趣的是,当我以我自己的身份(使用 Owner 角色)登录到 Azure 门户时,我可以添加和删除存储容器,而不管网络规则是否存在。

那么,有没有一种方法可以设置 Terraform 依赖项,以便可以在不遇到任何身份验证冲突的情况下构建和销毁它们?或者,将我的 SP 的角色升级到 Owner(或添加另一个更有针对性的角色)是否可以解决问题?

这是预期的行为,因为您将存储帐户的 network rules 设置为 deny,并且仅 bypassing Azure Services.

当您 denybypass Azure ServicesAzure Portal's IP 这样的 Azure Services 获得存储帐户的访问权限时,您是能够删除它。但与此同时,当您使用 terraform 执行销毁时,它会拒绝,因为您的机器正在使用 your IP 向 Azure 发送 terraform 请求是 not bypassed .

我用相同的权限测试了你的代码如下:

作为解决方案,您必须在创建存储帐户时添加 ip rules 以添加 client_ip,如下所示:

provider "azurerm" {
    features{}
  client_id="f6a2f33d-xxxx-xxxx-xxxx-xxxx"
  client_secret= "GZ67Q~xxxx~3N-qLT"
  tenant_id = "72f988bf-xxxx-xxxx-xxxx-2d7cd011db47"
  subscription_id="948d4068-xxxx-xxxx-xxxx-xxxx"
}

locals {
  storage_name = "ansumantestsacc12"
  subnet_id_list = [
      "/subscriptions/xxxx/resourceGroups/xxxx/providers/Microsoft.Network/virtualNetworks/xxxx/subnets/xxxx"
  ]
  my_ip = ["xx.xx.xx.xxx"] # IP used by me
}
variable "storage_containers" {
  default = [
      "test",
      "terraform"
  ]
}
data "azurerm_resource_group" "this" {
  name = "ansumantest"
}

resource "azurerm_storage_account" "this" {
  name                = local.storage_name
  resource_group_name = data.azurerm_resource_group.this.name
  location            = data.azurerm_resource_group.this.location

  account_tier             = "Standard"
  account_kind             = "StorageV2"
  is_hns_enabled           = true
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "data" {
  for_each = toset(var.storage_containers)

  name                  = each.value
  storage_account_name  = azurerm_storage_account.this.name
  container_access_type = "private"
}

# FIXED
resource "azurerm_storage_account_network_rules" "this" {
  storage_account_id   = azurerm_storage_account.this.id

  default_action = "Deny"
  bypass         = ["AzureServices"]
  ip_rules       = local.my_ip # need to set this to use terraform in our machine
  virtual_network_subnet_ids = local.subnet_id_list

  # NOTE The order here matters: We cannot create storage
  # containers once the network rules are locked down
  depends_on = [
    azurerm_storage_container.data
  ]
}

输出: