Files
code-snippets/docs/azure/aca-with-terraform.md
Liam Pietralla 07d9dd6657
All checks were successful
Build, Test & Publish / Build (push) Successful in 55s
Build, Test & Publish / Build and Publish Container Image (push) Successful in 34s
Build, Test & Publish / Deploy to Infrastructure (push) Successful in 31s
terraform azure
2026-03-25 08:33:50 +11:00

3.4 KiB

ACA with Terraform

Azure Container Apps (ACA) is a serverless container hosting service that allows you to run your containerized applications without managing the underlying infrastructure. Terraform is an Infrastructure as Code (IaC) tool that enables you to define and provision infrastructure using a declarative configuration language.

data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "my_rg" {
  name     = "my_rg"
  location = "Australia East"
  tags = {
    environment = "production",
    project     = "my-project",
    managed_by  = "terraform"
  }
}

resource "azurerm_container_registry" "acr" {
  name                = "myacr${random_id.acr_suffix.hex}"
  resource_group_name = azurerm_resource_group.my_rg.name
  location            = azurerm_resource_group.my_rg.location
  sku                 = "Basic"

  tags = {
    environment = "production",
    project     = "my-project",
    managed_by  = "terraform"
  }
}

resource "azurerm_container_app_environment" "aca_env" {
  name                = "aca-env"
  resource_group_name = azurerm_resource_group.my_rg.name
  location            = azurerm_resource_group.my_rg.location

  tags = {
    environment = "production",
    project     = "my-project",
    managed_by  = "terraform"
  }
}

resource "azuread_application" "acr_push_app" {
  display_name = "my-project-acr-push"
}

resource "azuread_service_principal" "acr_push_sp" {
  client_id = azuread_application.acr_push_app.client_id
}

resource "azuread_service_principal_password" "acr_push_secret" {
  service_principal_id = azuread_service_principal.acr_push_sp.id
}

resource "azurerm_role_assignment" "acr_push_role" {
  scope                = azurerm_container_registry.acr.id
  role_definition_name = "AcrPush"
  principal_id         = azuread_service_principal.acr_push_sp.object_id
}

resource "azurerm_user_assigned_identity" "aca_identity" {
  name                = "aca-identity"
  resource_group_name = azurerm_resource_group.my_rg.name
  location            = azurerm_resource_group.my_rg.location
}

resource "azurerm_role_assignment" "acr_pull_role" {
  scope                = azurerm_container_registry.acr.id
  role_definition_name = "AcrPull"
  principal_id         = azurerm_user_assigned_identity.aca_identity.principal_id
}

resource "azurerm_container_app" "app" {
  name                         = "app"
  container_app_environment_id = azurerm_container_app_environment.aca_env.id
  resource_group_name          = azurerm_resource_group.my_rg.name
  revision_mode                = "Single"

  identity {
    type = "UserAssigned"
    identity_ids = [azurerm_user_assigned_identity.aca_identity.id]
  }

  registry {
    server = azurerm_container_registry.acr.login_server
    identity = azurerm_user_assigned_identity.aca_identity.id
  }

  ingress {
    allow_insecure_connections = false
    external_enabled = true
    target_port = 3000
    transport = "auto"

    traffic_weight {
      latest_revision = true
      percentage = 100
    }
  }

  template {
    container {
      name   = "app"
      image  = "${azurerm_container_registry.acr.login_server}/my-project:latest"
      cpu    = "0.25"
      memory = "0.5Gi"

      env {
        name = "NEXT_PUBLIC_APP_ENV"
        value = "production"
      }

      readiness_probe {
        transport = "HTTP"
        port      = 3000
      }

      liveness_probe {
        transport = "HTTP"
        port      = 3000
        path      = "/api/health"
      }
    }
  }
}