使用 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"
这是我的服务主体,它在同一订阅中具有 Contributor
和 User Access Administrator
角色。有趣的是,当我以我自己的身份(使用 Owner
角色)登录到 Azure 门户时,我可以添加和删除存储容器,而不管网络规则是否存在。
那么,有没有一种方法可以设置 Terraform 依赖项,以便可以在不遇到任何身份验证冲突的情况下构建和销毁它们?或者,将我的 SP 的角色升级到 Owner
(或添加另一个更有针对性的角色)是否可以解决问题?
这是预期的行为,因为您将存储帐户的 network rules
设置为 deny
,并且仅 bypassing
Azure Services
.
当您 deny
和 bypass Azure Services
像 Azure 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
]
}
输出:
我正在尝试编写 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"
这是我的服务主体,它在同一订阅中具有 Contributor
和 User Access Administrator
角色。有趣的是,当我以我自己的身份(使用 Owner
角色)登录到 Azure 门户时,我可以添加和删除存储容器,而不管网络规则是否存在。
那么,有没有一种方法可以设置 Terraform 依赖项,以便可以在不遇到任何身份验证冲突的情况下构建和销毁它们?或者,将我的 SP 的角色升级到 Owner
(或添加另一个更有针对性的角色)是否可以解决问题?
这是预期的行为,因为您将存储帐户的 network rules
设置为 deny
,并且仅 bypassing
Azure Services
.
当您 deny
和 bypass Azure Services
像 Azure 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
]
}
输出: