Terraform: ошибка: получение статических свойств веб-сайта для учетной записи хранения (подписка: ***: превышен крайний срок контекста)

Когда я развертываю учетную запись хранения Azure с помощью terraform, я получаю сообщение об ошибке типа: Ошибка: получение статических свойств веб-сайта для учетной записи хранения (подписка: ***: превышен крайний срок контекста.

Когда я удаляю код для создания частной конечной точки, учетная запись хранения развертывается. Но когда я использую весь код вместе для учетной записи хранения и частной конечной точки, мой конвейер выходит из строя с упомянутой выше ошибкой.

мой код файла main.tf приведен ниже –

resource "azurerm_storage_account" "saflow" {
  name                     = .......
  resource_group_name      = data.azurerm_resource_group.rg.name
  location                 = data.azurerm_resource_group.rg.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  min_tls_version         = "TLS1_2"
  allow_nested_items_to_be_public = false
  identity {
    type = "SystemAssigned"
  }
  
  blob_properties {
    delete_retention_policy {
      days = 30
    }
    container_delete_retention_policy {
      days = 30
    }
    versioning_enabled = true
  }


queue_properties  {
    logging {
        delete                = true
        read                  = true
        write                 = true
        version               = "1.0"
        retention_policy_days = 10
    }
    hour_metrics {
      enabled                   = true
      include_apis              = true
      retention_policy_days     = 10
      version                   = "1.0"

    }
    minute_metrics {
      enabled                  = true
      include_apis             = true
      retention_policy_days    = 10
      version                  = "1.0"

      
    }
    
  }
}

resource "azurerm_storage_container" "container" {
  count                 = "${length(var.containername)}"
  name                  = "${element(var.containername,count.index)}"
  storage_account_name  = azurerm_storage_account.saflow.name
  container_access_type = "private"
  depends_on = [azurerm_storage_account.saflow]

}

resource "null_resource" "log_enabler" {
  triggers = {
  always_run = "${timestamp()}"
  }
  depends_on = [
    azurerm_storage_account.saflow
  ]
  provisioner "local-exec" {
    command = "az storage logging update --log rwd --retention 30 --services qtb --account-name ${azurerm_storage_account.saflow.name} --account-key ${azurerm_storage_account.saflow.primary_access_key}"
  } 
}

resource "azurerm_private_endpoint" "endpoint" {
   
  name                     = .......
  resource_group_name      = data.azurerm_resource_group.rgnetwork.name
  location                 = data.azurerm_resource_group.rgnetwork.location
  subnet_id                = data.azurerm_subnet.subnet.id
  private_dns_zone_group {
    name                 = ....
    private_dns_zone_ids = [data.azurerm_private_dns_zone.dns.id]
  }
  private_service_connection {
    name                           = ....
    is_manual_connection           = false
    private_connection_resource_id = azurerm_storage_account.saflow.id
    subresource_names              = ["blob"]
  }

  depends_on = [azurerm_storage_container.container]
}

resource "azurerm_private_dns_a_record" recordglobal {
  provider            = "azurerm.globalsub"
  name                = azurerm_storage_account.saflow.name
  zone_name           = data.azurerm_private_dns_zone.dns.name
  resource_group_name = data.azurerm_resource_group.rgglobal.name
  ttl                 = 10
  records             = [azurerm_private_endpoint.endpoint.private_service_connection[0].private_ip_address]
  depends_on = [azurerm_private_endpoint.endpoint]
}

resource azurerm_storage_account_network_rules networkrule {
  
   storage_account_id       = azurerm_storage_account.saflow.id
  default_action             = "Deny"
  virtual_network_subnet_ids = data.azurerm_subnet.subnet.id,data.azurerm_subnet.subnet-global.id
  bypass                     = ["AzureServices"]
  depends_on = [azurerm_private_endpoint.endpoint, azurerm_private_dns_a_record.recordglobal]
}

Пожалуйста, помогите, если что-то не так с этим кодом терраформирования.

Я удалил код для частной конечной точки, и учетная запись хранения была создана. Затем опубликуйте, что я добавил код для частной конечной точки, и частная конечная точка создана. Но почему он не создается, когда у меня есть оба кода для учетной записи хранения и частной конечной точки.

Иногда (не всегда) эта проблема возникает из-за устаревших записей в кэше DNS клиента или задержек распространения DNS. Можете ли вы воспроизвести проблему на своей локальной рабочей станции (вместо того, чтобы запускать ее через конвейер)? Если да и это возможно, попробуйте это на своей локальной рабочей станции: уничтожьте конфигурацию Terraform (при условии, что это нормально), затем несколько раз запустите nslookup для имени хоста учетной записи хранения, пока не будет найдена запись DNS. Затем повторно разверните конфигурацию.

cdub 31.05.2024 04:17

Превышение крайнего срока контекста происходит, когда запрос, сделанный Terraform, занимает больше времени, чем значение таймаута по умолчанию. Чтобы решить эту проблему, вы можете попробовать увеличить значение тайм-аута. Вы можете сделать это, установив блок таймаутов в ресурсе azurerm_storage_account, используя timeouts { create = "30m" update = "30m" delete = "30m" }. Для решения той же проблемы перейдите по ссылке .

Venkat V 31.05.2024 05:41
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
2
861
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Terraform: ошибка: получение статических свойств веб-сайта для учетной записи хранения (подписка: ***: превышен крайний срок контекста)

Превышение крайнего срока контекста происходит, когда запрос, сделанный Terraform, занимает больше времени, чем значение по умолчанию timeout. Чтобы решить эту проблему, вы можете попробовать увеличить значение тайм-аута. после создания учетной записи хранения она может быть не готова сразу принять соединение private endpoint, что приведет к ошибкам.

Чтобы решить эту проблему, вы можете добавить атрибут depends_on для ресурса azurerm_private_endpoint и добавить блок timeout в блок storage account. Это гарантирует, что он ожидает полного выполнения null_resource.log_enabler, тем самым гарантируя, что учетная запись хранения будет полностью настроена до начала создания private endpoint.

Вот обновленный код Terraform для создания учетной записи хранения, частной конечной точки и других ресурсов за один запуск.

provider "azurerm" {
  features {}
}

data "azurerm_resource_group" "rg" {
  name = "RG_Name"
}

resource "azurerm_private_dns_zone" "example" {
  name                = "mydomain.com"
  resource_group_name = data.azurerm_resource_group.rg.name
}

resource "azurerm_virtual_network" "example" {
  name                = "storage-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = data.azurerm_resource_group.rg.location
  resource_group_name = data.azurerm_resource_group.rg.name

  depends_on = [azurerm_private_dns_zone.example]
}

resource "azurerm_subnet" "example" {
  name                 = "storage-subnet"
  resource_group_name  = data.azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.2.0/24"]
  service_endpoints    = ["Microsoft.Storage"]


  depends_on = [azurerm_virtual_network.example]
}

resource "azurerm_storage_account" "saflow" {
  name                     = "thejastorage"
  resource_group_name      = data.azurerm_resource_group.rg.name
  location                 = data.azurerm_resource_group.rg.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  min_tls_version          = "TLS1_2"
  allow_nested_items_to_be_public = false
  identity {
    type = "SystemAssigned"
  }
  timeouts {
    create = "30m"
    update = "30m"
    delete = "30m"
  }

  blob_properties {
    delete_retention_policy {
      days = 30
    }
    container_delete_retention_policy {
      days = 30
    }
    versioning_enabled = true
  }

  queue_properties {
    logging {
      delete                = true
      read                  = true
      write                 = true
      version               = "1.0"
      retention_policy_days = 10
    }
    hour_metrics {
      enabled                   = true
      include_apis              = true
      retention_policy_days     = 10
      version                   = "1.0"
    }
    minute_metrics {
      enabled                  = true
      include_apis             = true
      retention_policy_days    = 10
      version                  = "1.0"
    }
  }
}

resource "azurerm_storage_container" "container" {
  name                  = "thejacontainer"
  storage_account_name  = azurerm_storage_account.saflow.name
  container_access_type = "private"
  depends_on = [azurerm_storage_account.saflow]
}

resource "null_resource" "log_enabler" {
  provisioner "local-exec" {
    command = <<EOT
    az storage account keys list --account-name ${azurerm_storage_account.saflow.name} --resource-group ${azurerm_storage_account.saflow.resource_group_name} --query '[0].value' --output tsv > key.txt
    az storage logging update --log rwd --retention 30 --services qtb --account-name ${azurerm_storage_account.saflow.name} --account-key $(cat key.txt)
    rm key.txt
    EOT
  }

  depends_on = [
    azurerm_storage_container.container
  ]
}

resource "azurerm_private_endpoint" "endpoint" {
  name                = "storageendpoint"
  resource_group_name = data.azurerm_resource_group.rg.name
  location            = data.azurerm_resource_group.rg.location
  subnet_id           = azurerm_subnet.example.id

  private_dns_zone_group {
    name                 = "storagedns"
    private_dns_zone_ids = [azurerm_private_dns_zone.example.id]
  }

  private_service_connection {
    name                           = "storageconnection"
    is_manual_connection           = false
    private_connection_resource_id = azurerm_storage_account.saflow.id
    subresource_names              = ["blob"]
  }

  depends_on = [null_resource.log_enabler]
}

provider "azurerm" {
  alias    = "globalsub"
  features {}
}

resource "azurerm_private_dns_a_record" "recordglobal" {
  name                = azurerm_storage_account.saflow.name
  zone_name           = azurerm_private_dns_zone.example.name
  resource_group_name = data.azurerm_resource_group.rg.name
  ttl                 = 10
  records             = [azurerm_private_endpoint.endpoint.private_service_connection[0].private_ip_address]
  depends_on = [azurerm_private_endpoint.endpoint]
}

resource "azurerm_storage_account_network_rules" "networkrule" {
  storage_account_id         = azurerm_storage_account.saflow.id
  default_action             = "Deny"
  virtual_network_subnet_ids = [azurerm_subnet.example.id]
  bypass                     = ["AzureServices"]
  depends_on = [azurerm_private_dns_a_record.recordglobal]
}

Терраформ применить

Результат портала

Перейдите по ссылке , чтобы решить Context Deadline Exceeded Error

По-прежнему получаю то же сообщение об ошибке: Ошибка: получение статических свойств веб-сайта для учетной записи хранения (подписка: «***» Имя группы ресурсов: «rg-name» Имя учетной записи хранения: «saflow»

Izzy 31.05.2024 13:45

Пожалуйста, удалите файл состояния и используйте мой код для одновременного создания учетной записи хранения и частной конечной точки.

Venkat V 31.05.2024 13:47

Привет @lzzy, надеюсь, это поможет тебе решить проблему. Дайте мне знать, если вы все еще сталкиваетесь с ошибкой.

Venkat V 06.06.2024 07:16

Привет Венкат! Большое спасибо за вашу помощь. Этот код сработал для меня. Сейчас трубопровод работает успешно.

Izzy 10.06.2024 15:32

У вас возникли проблемы, вызванные базовой конструкцией API Azure и поставщиком AzureRM для Terraform. На эту тему есть обширное обсуждение здесь.

Проблема: вы выполняете Terraform из сети, которая не имеет сетевого подключения к частной конечной точке этой учетной записи хранения, И вы не разрешили своему общедоступному IP-адресу доступ к учетной записи хранения.

Возможное решение 1. Вы предоставляете исключение брандмауэра для общедоступного IP-адреса, с которого вы выполняете свой Terraform. Может противоречить требованиям безопасности, с которыми вы работаете.

Возможное решение 2. Вы выполняете свой terraform в месте, где есть видимость частной конечной точки (например, виртуальная машина, работающая в той же виртуальной сети, через VPN или подобное).

Примечания. Это не проблема с тайм-аутом, в запросе просто указывается тайм-аут, поскольку он заблокирован брандмауэром хранилища BLOB-объектов. Кроме того, первый Terraform всегда завершается успешно, поскольку Terraform просто замечает, что существующего хранилища BLOB-объектов нет -> нет необходимости обновлять его статус.

Чтобы быть исчерпывающим во всех ситуациях, которые могут привести к этой ошибке.

Моя среда использовала

  1. Агент Майкрософт
  2. Частный DNS Azure
  3. Частные конечные точки Azure

Фрагмент кода

module "data-lake-gen2" {
  source = "./modules/datalake"

  region                           = var.rg-location
  resource_group_name              = var.rg-name
  storage_account_name             = var.data-lake-storage-name
  storage_account_replication_type = var.storage_account_replication_type
  blob_soft_delete_retention_days = var.blob_soft_delete_retention_days
  datalake-diag-name              = var.datalake-diag-name

  
  depends_on = [module.dp-rg, module.dp-vnet]

}

module "datalake-private-endpoint" {
  source = "./modules/private-endpoint"

  pe_resource_group_name = var.rg-name
  private_endpoint_name  = var.datalake-private-endpoint
  subresource_names      = ["blob"]
  # endpoint_resource_id   = module.data-lake-gen2.storage_account_id # have to manually use the resource ID to address the race condition
  endpoint_resource_id = var.datalake-endpoint-id
  pe_subnet_id         = module.dp-vnet.vnet_subnet_id[0]
  location             = var.rg-location
  private_ip_address   = var.datalake_private_ip_address
  member_name          = var.datalake_member_name
  subresource_name     = var.datalake_subresource_name


  dns = {
    zone_ids  = [module.dns.dns_zone_ids[1]]
    zone_name = var.dns_zone_names[1]
  }

  depends_on = [module.dp-resourcegroup, module.dp-vnet]
}

Код не вызвал проблем и работал как положено. Клиент хотел защитить свою среду, развернув ее с помощью САМОХОЗЯЙСТВЕННОГО АГЕНТА.

Когда я переключился на самостоятельный агент, я получил эту ошибку.

Сообщение об ошибке

    Error: retrieving static website properties for Storage Account (Subscription: "xxxxxxxx"
│ Resource Group Name: "rg-ae-01"
│ Storage Account Name: "stxxxxxe01"): executing request: Get "https://stxxxxxe01.blob.core.windows.net/?comp=properties&restype=service": context deadline exceeded
│ 
│   with module.data-lake-gen2.azurerm_storage_account.this,
│   on modules/datalake/main.tf line 40, in resource "azurerm_storage_account" "this":
│   40: resource "azurerm_storage_account" "this" {

Решение

Проблема заключалась в состоянии гонки между озером данных и частной конечной точкой. Terraform пытался создать озеро данных, а также пытался найти конечные точки хранилища, используя несуществующую частную конечную точку, подключенную к внутреннему частному DNS.

Мое решение состояло в том, чтобы передать фактический идентификатор endpoint_resource_id, поскольку развертывание частной конечной точки зависело от того, чтобы озеро данных было создано первым, а озеро данных зависело от того, чтобы сначала была создана частная конечная точка.

  # endpoint_resource_id   = module.data-lake-gen2.storage_account_id 
  # have to manually use the resource ID to address the race condition
  endpoint_resource_id = var.datalake-endpoint-id

переменные.tfvars

   datalake-endpoint-id = "/subscriptions/xxxxxxxxxx/resourceGroups/rg-xxx-ae-01/providers/Microsoft.Storage/storageAccounts/stasdsdsdse01"

Другие вопросы по теме