I have a image registry in Azure Subscription A and I want to deploy an azure Container App in a Azure Subscription B using the image from the Azure Subscription A registry repository. I'm trying to do this using service principles as authentication. Is that possible with terraform? I can do it with scripts where I use the Azure Cli to login to Subscription A, pull the image and then login to Azure Subscription B and deploy it or even with Visual Studio's Publish (when I create the Publish profile I can chose the account for the Container App and for the Registry I can use another account) but I can't seem to manage this in terraform. This is my main.tf (I'm using variables to hide sensitive data) :
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.63.0"
}
}
required_version = ">= 1.1.0"
}
provider "azurerm" {
subscription_id = var.subsriptionA_sub_id
tenant_id = var.subsriptionA_tenant_id
client_id = var.subsriptionA_client_id
client_secret = var.subsriptionA_client_secret
features {}
}
provider "azurerm" {
alias = "test"
subscription_id = var.subscriptionB_sub_id
tenant_id = var.subscriptionB_tenant_id
client_id = var.subscriptionB_client_id
client_secret = var.subscriptionB_client_secret
features {}
}
resource "azurerm_resource_group" "example" {
provider = azurerm.test
name = var.resource_group_name
location = var.location
}
data "azurerm_container_registry" "acr" {
provider = azurerm
name = "registryName"
resource_group_name = var.subscriptionA_resource_group_name
}
resource "azurerm_log_analytics_workspace" "example" {
provider = azurerm.test
name = "acctest-01"
location = var.location
resource_group_name = var.resource_group_name
sku = "PerGB2018"
retention_in_days = 30
}
resource "azurerm_container_app_environment" "example" {
provider = azurerm.test
name = "Example-Environment"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
log_analytics_workspace_id = azurerm_log_analytics_workspace.example.id
}
resource "azurerm_container_app" "example" {
provider = azurerm.test
name = "example-app"
container_app_environment_id = azurerm_container_app_environment.example.id
resource_group_name = var.resource_group_name
revision_mode = "Single"
template {
container {
name = "examplecontainerapp"
image = "${data.azurerm_container_registry.acr.login_server}/repositoryA:latest"
cpu = 0.25
memory = "0.5Gi"
}
}
}
edit : This is the error I'm getting with this setup :
Error: creating Container App (Subscription: SubscriptionB
│ Resource Group Name: var.resource_group_name
│ Container App Name: "example-app"): performing CreateOrUpdate: containerapps.ContainerAppsClient#CreateOrUpdate: Failure sending request: StatusCode=0 -- Original Error: Code="InvalidParameterValueInContainerTemplate" Message="The following field(s) are either invalid or missing. Field 'template.containers.examplecontainerapp.image' is invalid with details: 'Invalid value: \"${data.azurerm_container_registry.acr.login_server}/repositoryA:latest\": GET https:?scope=repositoryFromSusbscriptionA UNAUTHORIZED: authentication required, visit https://aka.ms/acr/authorization for more information.';."
edit2 : I found my solution, I needed to add these blocks, registry alone wasn't enough I needed a secret to get the password:
secret {
name = "secretname"
value = var.subsriptionA_client_secret
}
registry {
server = "server"
username = var.subsriptionA_client_id
password_secret_name = "secretname"
}
Thank you in advance!
I've found the solution for anyone wondering, there needs to be a registry block that takes the credential and the password needs to be from a secret (you can also use azure key vault for this from what I researched though I haven't tried that) :
resource "azurerm_container_app" "example" {
provider = azurerm.test
name = "example-app"
container_app_environment_id = azurerm_container_app_environment.example.id
resource_group_name = var.resource_group_name
revision_mode = "Single"
secret {
name = "secretname"
value = var.subsriptionA_client_secret
}
registry {
server = "server"
username = var.subsriptionA_client_id
password_secret_name = "secretname"
}
template {
container {
name = "examplecontainerapp"
image = "${data.azurerm_container_registry.acr.login_server}/repositoryA:latest"
cpu = 0.25
memory = "0.5Gi"
}
}
}