I am trying to deploy an Azure Container App from scratch on my Azure Subscription using Terraform with azurerm (4.27.0). I want my container app image managed by Azure Container Registry. Here is my code:
resource "azurerm_resource_group" "rg" {
name = "<RESOURCE_GROUP_NAME>"
location = var.location
}
resource "azurerm_container_registry" "cr" {
name = "<CONTAINER_REGISTRY_NAME>"
resource_group_name = azurerm_resource_group.rg.name
location = var.location
sku = "Standard"
}
resource "azurerm_container_app_environment" "cae" {
name = "<CONTAINER_APP_ENVIRONMENT_NAME>"
location = var.location
resource_group_name = azurerm_resource_group.rg.name
log_analytics_workspace_id = var.workspace_id
logs_destination = "log-analytics"
}
resource "azurerm_user_assigned_identity" "id" {
name = "<IDENTITY_NAME>"
location = var.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_role_assignment" "role_assignment" {
scope = azurerm_container_registry.cr.id
role_definition_name = "acrpull"
principal_id = azurerm_user_assigned_identity.id.principal_id
depends_on = [azurerm_user_assigned_identity.id]
}
resource "azurerm_container_app" "ca" {
name = "<CONTAINER_APP_NAME>"
container_app_environment_id = azurerm_container_app_environment.cae.id
resource_group_name = azurerm_resource_group.rg.name
revision_mode = "Single"
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.id.id]
}
registry {
server = azurerm_container_registry.cr.login_server
identity = azurerm_user_assigned_identity.id.id
}
template {
container {
name = "<CONTAINER_NAME>"
image = "${azurerm_container_registry.cr.login_server}/<CONTAINER_IMAGE_NAME>:CONTAINER_IMAGE_TAG"
cpu = 0.5
memory = "1Gi"
}
}
depends_on = [azurerm_role_assignment.role_assignment]
}
When I run terraform apply
, I get this error:
│ Error: creating Container App (Subscription: "<SUBSCRIPTION_ID>"
│ Resource Group Name: "<RESOURCE_GROUP_NAME>"
│ Container App Name: "<CONTAINER_APP_NAME>"): polling after CreateOrUpdate: polling failed: the Azure API returned the following error:
│
│ Status: "Failed"
│ Code: "ContainerAppOperationError"
│ Message: "Failed to provision revision for container app '<CONTAINER_APP_NAME>'. Error details: The following field(s) are either invalid or missing. Field 'template.containers.<CONTAINER_APP_NAME>.image' is invalid with details: 'Invalid value: \"<CONTAINER_REGISTRY_LOGIN_SERVER>/<CONTAINER_IMAGE_NAME>:<CONTAINER_IMAGE_TAG>\": GET https:: MANIFEST_UNKNOWN: manifest tagged by \"<CONTAINER_IMAGE_TAG>\" is not found; map[Tag:<CONTAINER_IMAGE_TAG>]';.."
│ Activity Id: ""
I understand that I am trying to pull an image from my newly created container registry, even though it doesn't contain any. But I am deploying my infrastructure from scratch: at this stage, I want to create my first image, and I expect that we can do this from terraform.
Is there a way to do that? Thanks by advance.
Deploy an Azure Container App from scratch using terraform/azurerm
As suggested in the comments, Terraform natively doesn't support to push the Docker images to ACR. We can do that using CLI, however if you What everything to be provisioned using single configuration you can use null resource local exec provisioner to run the CLI commands as per the requirement.
I tried a demo configuration as per the requirement to use null resource that pass CLI command as per the requirement and able to provision the requirement successfully.
For this to work, we need a docker file in the same directory where we need are executing terraform, or we need to specify the Dockerfile path target directory.
Demo configuration:
resource "null_resource" "push_image" {
provisioner "local-exec" {
interpreter = ["pwsh", "-Command"]
command = <<EOT
az acr build --registry ${var.container_registry_name} --image ${var.container_image_name}:${var.container_image_tag} --file dockerfile .
EOT
}
}
resource "azurerm_user_assigned_identity" "identity" {
name = var.identity_name
resource_group_name = azurerm_resource_group.rg.name
location = var.location
}
resource "azurerm_role_assignment" "acr_pull" {
scope = azurerm_container_registry.acr.id
role_definition_name = "acrpull"
principal_id = azurerm_user_assigned_identity.identity.principal_id
}
resource "azurerm_container_app_environment" "env" {
name = var.container_app_env_name
location = var.location
resource_group_name = azurerm_resource_group.rg.name
log_analytics_workspace_id = var.log_analytics_workspace_id
logs_destination = "log-analytics"
}
resource "azurerm_container_app" "app" {
name = var.container_app_name
container_app_environment_id = azurerm_container_app_environment.env.id
resource_group_name = azurerm_resource_group.rg.name
revision_mode = "Single"
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.identity.id]
}
registry {
server = azurerm_container_registry.acr.login_server
identity = azurerm_user_assigned_identity.identity.id
}
template {
container {
name = var.container_name
image = "${azurerm_container_registry.acr.login_server}/${var.container_image_name}:${var.container_image_tag}"
cpu = 0.5
memory = "1Gi"
}
}
depends_on = [
null_resource.push_image,
azurerm_role_assignment.acr_pull
]
}
Deployment:
Refer:
https://www.mytechramblings.com/posts/how-to-push-a-container-image-into-acr-using-terraform/