我正在尝试编写 Terraform,它将创建一个 Azure 存储帐户,然后在其中创建一堆存储容器。一个重要的细节是存储帐户具有限制对特定地址空间的访问的网络规则。这导致容器创建失败。
我设法通过使用
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 身份验证错误:
错误:检索容器“数据”(帐户“XXX”/资源组“XXX”):container.Client#GetProperties:响应请求失败:StatusCode=403 -- 原始错误:autorest/azure:服务返回错误。 Status=403 Code="AuthorizationFailure" Message="该请求无权执行该操作。 请求ID:XXX 时间:XXX”
这是我的服务主体,它在同一订阅上具有
Contributor
和 User Access Administrator
角色。有趣的是,当我以自己的身份登录 Azure 门户(使用 Owner
角色)时,无论是否存在网络规则,我都可以添加和删除存储容器。
那么,有没有一种方法可以设置 Terraform 依赖项,以便可以构建和销毁它们而不会遇到任何身份验证冲突?或者,将我的 SP 角色升级为
Owner
(或添加另一个更有针对性的角色)可以解决问题吗?
这是预期行为,因为您将存储帐户的
network rules
设置为 deny
并且仅设置 bypassing
Azure Services
。
当您
deny
和 bypass Azure Services
Azure Services
(例如 Azure Portal's IP
)获得对存储帐户的访问权限时,您可以将其删除。但同时,当您使用 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
]
}
输出: