Я попытался создать контейнер хранения внутри учетной записи хранения, но к этой учетной записи хранения не должен быть открыт доступ публике. В основном я следовал этому руководству, чтобы использовать частную конечную точку: https://gmusumeci.medium.com/using-private-endpoint-in-azure-storage-account-with-terraform-49b4734ada34. Я создал его успешно. Но теперь, когда я захочу внести какие-либо изменения, я получу ошибку 403:
Error: retrieving Container "tfstate" (Account "Account \"tfstate2hnq5\" (IsEdgeZone false / ZoneName \"\" / Subdomain Type \"blob\" / DomainSuffix \"core.windows.net\")"): executing request: unexpected status 403 (403 This request is not authorized to perform this operation.) with AuthorizationFailure: This request is not authorized to perform this operation.
У меня есть все необходимые права доступа, я также пробовал использовать Service Principal и также предоставить ему все возможные права. Тем не менее, это не работает. Я что-то здесь упустил из виду? Я также не могу получить доступ к контейнеру хранилища на портале Azure.
Мой основной.tf:
resource "random_string" "resource_code" {
length = 5
special = false
upper = false
}
resource "azurerm_resource_group" "tfstate" {
name = "tfstate"
location = "West Europe"
}
resource "azurerm_virtual_network" "this" {
name = "network-vnet"
address_space = [var.network-vnet-cidr]
resource_group_name = azurerm_resource_group.tfstate.name
location = azurerm_resource_group.tfstate.location
}
resource "azurerm_subnet" "endpoint-subnet" {
name = "endpoint-subnet"
address_prefixes = [var.endpoint-subnet-cidr]
virtual_network_name = azurerm_virtual_network.this.name
resource_group_name = azurerm_resource_group.tfstate.name
private_endpoint_network_policies = "Enabled"
service_endpoints = ["Microsoft.Storage", "Metrics"]
}
resource "azurerm_private_dns_zone" "dns-zone" {
name = "privatelink.blob.core.windows.net"
resource_group_name = azurerm_resource_group.tfstate.name
}
resource "azurerm_private_dns_zone_virtual_network_link" "network_link" {
name = "network_link"
resource_group_name = azurerm_resource_group.tfstate.name
private_dns_zone_name = azurerm_private_dns_zone.dns-zone.name
virtual_network_id = azurerm_virtual_network.this.id
}
resource "azurerm_private_endpoint" "endpoint" {
name = "tfstate_pe"
resource_group_name = azurerm_resource_group.tfstate.name
location = azurerm_resource_group.tfstate.location
subnet_id = azurerm_subnet.endpoint-subnet.id
private_service_connection {
name = "tfstate_psc"
private_connection_resource_id = azurerm_storage_account.tfstate.id
is_manual_connection = false
subresource_names = ["blob"]
}
}
resource "azurerm_private_dns_a_record" "storage_account" {
name = azurerm_storage_account.tfstate.name
zone_name = azurerm_private_dns_zone.dns-zone.name
resource_group_name = azurerm_resource_group.tfstate.name
ttl = 300
records = [azurerm_private_endpoint.endpoint.private_service_connection.0.private_ip_address]
}
resource "azurerm_storage_account" "tfstate" {
name = "tfstate${random_string.resource_code.result}"
resource_group_name = azurerm_resource_group.tfstate.name
location = azurerm_resource_group.tfstate.location
account_tier = "Standard"
account_replication_type = "LRS"
account_kind = "StorageV2"
default_to_oauth_authentication = true
enable_https_traffic_only = true
min_tls_version = "TLS1_2"
blob_properties {
versioning_enabled = true
change_feed_enabled = true
change_feed_retention_in_days = 90
last_access_time_enabled = true
delete_retention_policy {
days = 90
}
container_delete_retention_policy {
days = 30
}
}
}
resource "azurerm_storage_account_network_rules" "rules" {
storage_account_id = azurerm_storage_account.tfstate.id
default_action = "Deny"
bypass = ["AzureServices"]
virtual_network_subnet_ids = [azurerm_subnet.endpoint-subnet.id]
}
resource "azurerm_storage_container" "tfstate" {
name = "tfstate"
storage_account_name = azurerm_storage_account.tfstate.name
container_access_type = "private"
}
resource "azurerm_storage_account_network_rules" "rules" {
storage_account_id = azurerm_storage_account.tfstate.id
default_action = "Deny"
bypass = ["AzureServices"]
virtual_network_subnet_ids = [azurerm_subnet.endpoint-subnet.id]
}
resource "azurerm_storage_container" "tfstate" {
name = "tfstate"
storage_account_name = azurerm_storage_account.tfstate.name
container_access_type = "private"
}
Спасибо, я уже это сделал. Я дал своему пользователю и SP участник данных BLOB-объектов хранилища, владельца, участника учетной записи хранения, участника, владельца данных BLOB-объекта хранилища, считывателя данных BLOB-объекта хранилища. Но все равно не работает, к сожалению
Ошибка, с которой вы столкнулись, связана с ограничением сети, поскольку используемый вами компьютер не находится в диапазоне сети частной конечной точки. Создайте новое сетевое правило, которое разрешает трафик с вашего компьютера, добавив свой общедоступный IP-адрес для создания контейнера или используйте сеть, которая соответствует диапазону IP-адресов вашего сетевого правила @bunus19.
ресурс "azurerm_storage_account_network_rules" "rules" { Storage_account_id = azurerm_storage_account.tfstate.id default_action = "Запретить" ip_rules = ["ваш общедоступный IP-адрес"] bypass = ["AzureServices"] virtual_network_subnet_ids = [azurerm_subnet.endpoint-subnet.id] } Добавить этот фрагмент @bunus19


Создание контейнера с использованием terraform и учетной записи хранения с частной конечной точкой.
Проблема, с которой вы столкнулись, связана с сетевым правилом брандмауэра, не позволяющим создавать внутри него контейнер. Чтобы это работало, нам нужно создать новое правило, позволяющее IP-адресу получать доступ для создания контейнера, или выбрать IP-адрес, который разрешается брандмауэром.
Конфигурация терраформа:
provider "azurerm" {
features {}
}
resource "random_string" "resource_code" {
length = 5
special = false
upper = false
}
resource "azurerm_resource_group" "tfstate" {
name = "tfstate"
location = "West Europe"
}
resource "azurerm_virtual_network" "this" {
name = "network-vnet"
address_space = ["10.0.0.0/16"]
resource_group_name = azurerm_resource_group.tfstate.name
location = azurerm_resource_group.tfstate.location
}
resource "azurerm_subnet" "endpoint-subnet" {
name = "endpoint-subnet"
address_prefixes = ["10.0.1.0/24"]
virtual_network_name = azurerm_virtual_network.this.name
resource_group_name = azurerm_resource_group.tfstate.name
private_endpoint_network_policies = "Enabled"
service_endpoints = ["Microsoft.Storage"]
}
resource "azurerm_private_dns_zone" "dns-zone" {
name = "privatelink.blob.core.windows.net"
resource_group_name = azurerm_resource_group.tfstate.name
}
resource "azurerm_private_dns_zone_virtual_network_link" "network_link" {
name = "network_link"
resource_group_name = azurerm_resource_group.tfstate.name
private_dns_zone_name = azurerm_private_dns_zone.dns-zone.name
virtual_network_id = azurerm_virtual_network.this.id
}
resource "azurerm_private_endpoint" "endpoint" {
name = "tfstate_pe"
resource_group_name = azurerm_resource_group.tfstate.name
location = azurerm_resource_group.tfstate.location
subnet_id = azurerm_subnet.endpoint-subnet.id
private_service_connection {
name = "tfstate_psc"
private_connection_resource_id = azurerm_storage_account.tfstate.id
is_manual_connection = false
subresource_names = ["blob"]
}
}
resource "azurerm_private_dns_a_record" "storage_account" {
name = azurerm_storage_account.tfstate.name
zone_name = azurerm_private_dns_zone.dns-zone.name
resource_group_name = azurerm_resource_group.tfstate.name
ttl = 300
records = [azurerm_private_endpoint.endpoint.private_service_connection.0.private_ip_address]
}
resource "azurerm_storage_account" "tfstate" {
name = "tfstate${random_string.resource_code.result}"
resource_group_name = azurerm_resource_group.tfstate.name
location = azurerm_resource_group.tfstate.location
account_tier = "Standard"
account_replication_type = "LRS"
account_kind = "StorageV2"
default_to_oauth_authentication = true
enable_https_traffic_only = true
min_tls_version = "TLS1_2"
blob_properties {
versioning_enabled = true
change_feed_enabled = true
change_feed_retention_in_days = 90
last_access_time_enabled = true
delete_retention_policy {
days = 90
}
container_delete_retention_policy {
days = 30
}
}
}
resource "azurerm_storage_account_network_rules" "rules" {
storage_account_id = azurerm_storage_account.tfstate.id
default_action = "Deny"
ip_rules = ["125.19.127.99"]
bypass = ["AzureServices"]
virtual_network_subnet_ids = [azurerm_subnet.endpoint-subnet.id]
}
resource "azurerm_storage_container" "tfstate" {
name = "tfstate"
storage_account_name = azurerm_storage_account.tfstate.name
container_access_type = "private"
depends_on = [ azurerm_storage_account_network_rules.rules ]
}
Деполиляция прошла успешно:



Ссылка:
https://learn.microsoft.com/en-us/azure/storage/common/storage-private-endpoints
Спасибо за ваш быстрый ответ! Да, конечно, для меня это имеет смысл. А как насчет конвейеров CI/CD, таких как действия Github, где вы не знаете IP-адрес? Я думаю, что добавить туда IP-адреса невозможно.
В конвейерах CI/CD с динамическими или неизвестными IP-адресами диапазоны IP-адресов Azure DevOps можно использовать для внесения в белый список IP-адресов, а для предоставления доступа можно использовать теги служб, такие как AzureCloud. В качестве альтернативы также можно настроить учетную запись хранения для использования частных конечных точек и подключения исполнителей CI/CD к той же виртуальной сети. @bunus19 См.: Learn.microsoft.com/en-us/azure/storage/common/… и Learn.microsoft.com/en-us/azure/virtual-network/…
@VinayB да, конечно, спасибо! Просто хотел спросить, есть ли какие-либо ресурсы для подключения бегунов CI/CD или моего локального компьютера к виртуальной сети через частные конечные точки. Спасибо!
проверьте, назначена ли вашему пользователю или поставщику услуг роль участника данных Storage Blob, назначенная учетной записи хранения @bunus19.