Conditional "azurerm_storage_blob"

I have a file in a Blob storage container that may or may not exist, and I would like for Terraform to conditionally load the file if it does exist.

If I try to do data "azurerm_storage_blob" on the file, it just always fails if the file doesn’t exist.

For the AWS provider there’s “aws_s3_bucket_objects” data source which is like this " aws_s3_bucket_object" (or Azure’s “azurerm_storage_blob”), but conditionally gives you 1 or 0 results depending on if the file exists or not. I’m looking for an Azure equivalent of this “aws_s3_bucket_objects” data source.

data "azurerm_storage_blob"

Use this data source to access information about an existing Storage Blob. If you do not have any blob in the container, the data source would fail.

That’s the problem though. That one fails if the Blob file does not exist.

I would like a solution that does not fail if the file does not exist.

Yes, you won’t be able to achieve that using terraform azurerm provider. You might be to using azapi or script using data_source (null_resource) but I can test and get you feedback on how to.

See below for the solution I came up with and it worked perfect for me.

Created a powershell file named “test.ps1” or you make it a bash file if you wish to run an az cli command. Inside the powershell file I have the following code.

$jsonpayload = [Console]::In.ReadLine()

# Convert JSON to a string
$json = ConvertFrom-Json $jsonpayload

$access_name = $json.storage_account_name
$access_key = $json.storage_account_key
$container_name= $json.container_name
$blob_name= $json.blob_name

$blobExist = az storage blob exists --account-name $access_name --container-name $container_name --name $blob_name --account-key $access_key | ConvertFrom-Json
Write-Output "{ ""blobExist"" : ""$($blobExist.exists)""}" 

The Powershell script will retrieve data from terraform to run az cli and the az cli checks the existence of a blob and return True if exists or False is not.

Now, in my terraform file, I have the following. data source to get storage account and its access key, variable for the container and blob name which are required json payload needed for az cli to run.

provider "azurerm" {
  skip_provider_registration = true
  features {}
}

variable "storage_account_rg" {
  type    = string
  default = "azuredevops"
}

variable "storage_account_name" {
  type    = string
  default = "infrastorageshjhd01"
}

variable "storage_container_name" {
  type    = string
  default = "tfstate"
}

variable "blob_name" {
  type    = string
  default = "state"
}


data "azurerm_storage_account" "storage_account" {
  name                = var.storage_account_name
  resource_group_name = var.storage_account_rg
}

data "external" "external" {
  program = ["Powershell.exe", "./test.ps1"]

  query = {
    storage_account_name = data.azurerm_storage_account.storage_account.name
    storage_account_key  = data.azurerm_storage_account.storage_account.primary_access_key
    container_name       = var.storage_container_name
    blob_name            = var.blob_name
  }
}

resource "azurerm_storage_blob" "storage_blob" {
  count = data.external.external.result.blobExist == "True" ? 0 : 1
  name                   = "file-to-upload"
  storage_account_name   = data.azurerm_storage_account.storage_account.name
  storage_container_name = var.storage_container_name
  type                   = "Block"
  source                 = "file-to-upload"
}

You can now see that I’m using the output of the external data source to conditionally create a blob resource using count.

the count checks if the output of the az cli is True or not. If it’s False, the azurerm_storage_blob is triggered and blob is uploaded to Azure. If it’s True, the azurerm_storage_blob is ignored.

Please let me know if this helps.

1 Like