I’m currently working with Terraform Cloud to create an Azure Container App using Terraform as part of my Infrastructure as Code (IaC) efforts. I’m using a null_resource with the local-exec provisioner to execute a script that builds a Docker image and pushes it to Azure Container Registry (ACR). However, I've run into a limitation where the script doesn’t execute as intended because Terraform Cloud runs in a remote environment.
Here’s a snippet of my configuration (sample):
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "East US"
}
resource "azurerm_container_registry" "acr" {
name = "myUniqueACRName"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
sku = "Basic"
admin_enabled = true
}
resource "null_resource" "deploy_image_acr" {
triggers = {
deploy_time = timestamp()
}
provisioner "local-exec" {
command = "./deploy_to_acr.sh ${var.client_id} ${var.client_secret} ${var.tenant_id} ${var.subscription_id} ${azurerm_container_registry.acr.name} ${var.image_name}"
}
depends_on = [azurerm_container_registry.acr]
}
Bash Script:
#!/bin/bash
# Login to Azure with the Service Principal
az login --service-principal -u "$1" -p="$2" --tenant "$3"
# Set the desired subscription
az account set --subscription "$4"
# Remove all existing images
for repo in $(az acr repository list --name "$5" --output tsv); do
az acr repository delete --name "$5" --repository "$repo" --yes
done
# Build and push the new image
docker build -t <image_name> ..
az acr login --name $5
docker tag <image_name> $5.azurecr.io/<image_name>
docker push $5.azurecr.io/<image_name>
The Problem: When I try to apply this configuration in Terraform Cloud, the local-exec provisioner does not execute the script because it's designed to run on the local machine where Terraform is executed.
Questions:
To execute scripts defined in a null_resource
or any other resource on my local machine while using Terraform Cloud:
Solution: Ensure that your execution mode is set to local in your workspace. This will store the state file inside Terraform while all infrastructure provisioning occurs on your local machine.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "4.2.0"
}
}
cloud {
organization = "org-name"
workspaces {
name = "wk-space"
}
}
}
Navigate to Workspace Settings > Execution Mode.
Documentation: Terraform Cloud Execution Mode