Terraform生成带SAS的Azure Blob下载URL报ResourceNotFound错误
Azure存储Blob SAS URL生成报错ResourceNotFound的排查与解决
我通过Terraform的azurerm_storage_account_sas数据源生成SAS令牌,拼接至azurerm_storage_blob导出的URL后,访问时返回<Error><Code>ResourceNotFound</Code><Message>指定资源不存在</Message></Error>错误。以下是相关代码、无效URL示例和Azure Storage Explorer生成的可用URL示例:
Terraform代码
terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "~>3.0.0" } azuread = { source = "hashicorp/azuread" } } backend "azurerm" { resource_group_name = "example" storage_account_name = "example" container_name = "example" key = "terraform.tfstate" } } provider "azurerm" { features {} } resource "azurerm_storage_account" "example" { name = "${var.name}" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location account_tier = "Standard" account_replication_type = "LRS" enable_https_traffic_only = true min_tls_version = "TLS1_2" } resource "azurerm_storage_container" "example" { name = "${var.name}-exampleconfig" storage_account_name = azurerm_storage_account.example.name container_access_type = "private" } resource "azurerm_storage_blob" "example" { name = var.profile_name storage_account_name = azurerm_storage_account.example.name storage_container_name = azurerm_storage_container.example.name type = "Block" source = ".\\example\\exampleconfig.xml" } locals { current_time = timestamp() twoweeks = timeadd(local.current_time, "336h") ## adds two weeks for use in the sas string below } data "azurerm_storage_account_sas" "example" { connection_string = azurerm_storage_account.example.primary_connection_string https_only = true start = local.current_time expiry = local.twoweeks signed_version = "2020-10-02" resource_types { service = false container = true object = false } services { blob = true queue = false table = false file = false } permissions { read = true write = false delete = false list = false add = false create = false update = false process = false tag = false filter = false } } locals { ## attempting to parse the strings together using storage account name and blob and just the storage blob url ### sas_url_string = "https://${azurerm_storage_account.example.name}.blob.core.windows.net/${azurerm_storage_container.example.name}/${var.profile_name}${data.azurerm_storage_account_sas.example.sas}" sas_uri_string = "${azurerm_storage_blob.example.url}${data.azurerm_storage_account_sas.example.sas}" } output "sas_url_query_string" { description = "Link to XML File" value = local.sas_url_string sensitive = true } output "sas_uri_query_string" { description = "Link to XML File" value = local.sas_uri_string sensitive = true }
生成的无效URL示例
{ "sas_uri_query_string": { "sensitive": true, "type": "string", "value": "https://example.blob.core.windows.net/example-exampleconfig/exampleconfig.xml?sv=2020-10-02\u0026ss=b\u0026srt=c\u0026sp=r\u0026se=2023-08-10T18:16:49Z\u0026st=2023-07-27T18:16:49Z\u0026spr=https\u0026sig=U7ezaedrqqqAMEtEdeqLCwsEqghqRgSrzFMMpkhwBkk%3D" }, "sas_url_query_string": { "sensitive": true, "type": "string", "value": "https://example.blob.core.windows.net/example-exampleconfig/exampleconfig.xml?sv=2020-10-02\u0026ss=b\u0026srt=c\u0026sp=r\u0026se=2023-08-10T18:16:49Z\u0026st=2023-07-27T18:16:49Z\u0026spr=https\u0026sig=U7ezaedrqqqAMEtEdeqLCwsEqghqRgSrzFMMpkhwBkk%3D" } }
Azure Storage Explorer生成的可用URL示例
https://example.blob.core.windows.net/exampleexample/exampleconfig.xml?sv=2020-10-02&st=2023-07-27T17%3A59%3A56Z&se=2023-07-28T17%3A59%3A56Z&sr=b&sp=r&sig=nK%2FbGwwXXEb6e86rD2k3Poz8zGJaptv%2F6BeHdWCIypY%3D
问题分析
对比无效URL和可用URL的查询参数,核心差异在于资源权限范围:
- 无效URL包含
srt=c,表示该SAS仅授予容器级权限,只能用于容器相关操作(如列出Blob),无法直接访问单个Blob对象。 - 可用URL包含
sr=b,表示该SAS授予Blob对象级权限,可直接访问指定Blob。
原因定位
你的azurerm_storage_account_sas数据源配置中,resource_types仅开启了container=true、关闭了object=false,生成的是容器级SAS令牌。用该令牌访问Blob时,Azure权限验证不通过,因此返回"资源不存在"错误。
修复方案
方案1:调整azurerm_storage_account_sas的资源类型配置
修改resource_types部分,开启object=true,让SAS包含Blob对象的访问权限:
data "azurerm_storage_account_sas" "example" { connection_string = azurerm_storage_account.example.primary_connection_string https_only = true start = local.current_time expiry = local.twoweeks signed_version = "2020-10-02" resource_types { service = false container = false # 无需容器权限可关闭,仅保留object即可 object = true # 开启Blob对象级权限 } services { blob = true queue = false table = false file = false } permissions { read = true write = false delete = false list = false add = false create = false update = false process = false tag = false filter = false } }
若需要同时保留容器和Blob权限,可设置container=true和object=true,此时生成的SAS会包含srt=co,访问时Azure会自动识别目标资源类型。
方案2:使用azurerm_storage_blob_sas数据源(更精准)
直接使用专门针对Blob的SAS数据源,无需手动拼接权限范围:
data "azurerm_storage_blob_sas" "example" { connection_string = azurerm_storage_account.example.primary_connection_string container_name = azurerm_storage_container.example.name blob_name = azurerm_storage_blob.example.name https_only = true start = local.current_time expiry = local.twoweeks signed_version = "2020-10-02" permissions { read = true } } # 拼接URL locals { sas_uri_string = "${azurerm_storage_blob.example.url}${data.azurerm_storage_blob_sas.example.sas}" }
验证结果
修改后生成的URL会包含sr=b参数,与Storage Explorer生成的可用URL参数逻辑一致,即可正常访问目标Blob资源。
内容的提问来源于stack exchange,提问作者user18582981
相关产品推荐
相关产品推荐

