Automate Image Upload to Azure Blob Storage With Terraform

Ā·

3 min read

Automate Image Upload to Azure Blob Storage With Terraform

September has been a month with new experiences, and one of them involved me getting a bit hands-on with Microsoft Azure, which in turn, means a blogpost!šŸ«£

As an AWS Community Builder, I have mostly stuck to exploring AWS services for my personal projects (and thereā€™s more than enough of those tbh). This means I have never had a need to dive into other cloud providers because well, I donā€™t work as a platform engineer (yet).

However, I recently got an opportunity to try out Azure briefly and one of the tasks I enjoyed was automating the upload of a file to a blob storage with Terraform. It was pretty easy and the documentation was informative enough to know what resources to provision.

In this post, Iā€™ll share the scripts I wrote to provision the necessary Azure resources including the image to be uploaded.

In AWS terms, automate uploading a file to an S3 bucket.

Prerequisites

  • Existing Microsoft Azure account, or a new one - new accounts get $200 worth of free credits that you can use to explore.

  • Terraform installed on your local machine

  • IDE of your choice

Useful Resources

Project Setup

While you can create a folder and simply use one file main.tf, the skeleton template I used had some best practices I mentioned in my first Terraform project.

This was my directory structure:

azure_exercise
|-- main.tf
|-- output.tf
|-- provider.tf
|-- variables.tf
  1. variables.tf
# Define your Variables here
# See: https://www.terraform.io/docs/language/values/variables.html

variable "region" {
  description = "Deployment Region"
  type        = string
  default     = # set value
}

variable "unique-var" {
  description = "User ID"
  type        = string
  default     = # set value
}
  1. provider.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 2.0"
    }
  }
}
provider "azurerm" {
  features {}
  # any other necessary arguments depending on your account
}

data "azurerm_client_config" "current" {}
  1. output.tf
# Define your Outputs here
# See: https://www.terraform.io/docs/language/values/outputs.html

output "urltouploadedfile" {
  value       = azurerm_storage_blob.samplefile.url
  description = "URL of the uploaded file"
}
  1. main.tf

resource "azurerm_resource_group" "tresourcegroup" {
  name     = "rg-blog-${var.unique-var}"
  location = var.region
  tags = {
    # add preferred tags
  }
}

resource "azurerm_storage_account" "storageacc" {
  name                     = "acc${var.unique-var}"
  resource_group_name      = azurerm_resource_group.tresourcegroup.name
  location                 = azurerm_resource_group.tresourcegroup.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  allow_blob_public_access = true
}

resource "azurerm_storage_container" "storagectr" {
  name                  = "ctr-${var.unique-var}"
  storage_account_name  = azurerm_storage_account.storageacc.name
  container_access_type = "blob"
}

resource "azurerm_storage_blob" "samplefile" {
  name                   = "${var.unique-var}-sample.jpg"
  storage_account_name   = azurerm_storage_account.storageacc.name
  storage_container_name = azurerm_storage_container.storagectr.name
  type                   = "Block"
  content_type           = "image/png"
  source                 = # absolute path to the image
}

And thatā€™s it! Run the necessary terraform commands:

  • terraform init

  • terraform plan and review if necessary

  • terraform apply

After successful provisioning, the console should have the publicly available file URL.

NOTE:

You might run into a minor issue with the image downloading via URL instead of opening in browser if you changed the arguments a bit.

It happened to me before I specified the content_type of the azurerm_storage_blob resource. Without specifying, it defaults to application/octet-stream, which is basically code for ā€œIā€™m not sure what type of file this is, so Iā€™m just going to label it a random binary fileā€; hence causing the download.

This StackOverflow discussion helped.


I also worked with some other services and built Azure pipelines for CI/CD; overall, it was a good learning experience to try another cloud provider (a bit frustrating but still nice).

Thanks for reading!