Deploy Container App and pull image from Azure Container Registry using Terraform and AzAPI : Thomas Thornton
by: Thomas Thornton
blow post content copied from Thomas Thornton
click here to view original post
In this blog I am going to show how to deploy Container App and pull an image from Azure Container Registry using user assigned managed identity for authentication. I will be achieving this using Terraform and AzAPI.
Image below shows a diagram of what I will be deploying; it shows container app accessing a container registry using a user created identity.
![](https://tamops.files.wordpress.com/2022/12/image-8.png?w=539)
Terraform
The terraform will create:
- Resource Group
- Log Analytics Workspace
- Container App Environment
- Container App
- User created identity
- Assign IAM permissions to an already created container registry for the user created identity
- Assign user created identity to the container App
- Successfully deploy container app with image stored in container registry
Resource Group
resource "azurerm_resource_group" "rg" {
name = "${var.aca_name}-rg"
location = var.location
}
Log Analytics Workspace
resource "azurerm_log_analytics_workspace" "loganalytics" {
name = "${var.aca_name}-la"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
sku = "PerGB2018"
retention_in_days = 30
}
Data resources associated with already created Container Registry
data "azurerm_resource_group" "acr" {
name = "tamops-acr-github"
}
data "azurerm_container_registry" "acr" {
name = "tamopsactionacr"
resource_group_name = data.azurerm_resource_group.acr.name
}
Container App Environment deployed using AzAPI and Log Analytics workspace associated to send logs
esource "azapi_resource" "containerapp_environment" {
type = "Microsoft.App/managedEnvironments@2022-03-01"
name = "${var.aca_name}env"
parent_id = azurerm_resource_group.rg.id
location = azurerm_resource_group.rg.location
body = jsonencode({
properties = {
appLogsConfiguration = {
destination = "log-analytics"
logAnalyticsConfiguration = {
customerId = azurerm_log_analytics_workspace.loganalytics.workspace_id
sharedKey = azurerm_log_analytics_workspace.loganalytics.primary_shared_key
}
}
}
})
}
Create user assigned identity and associated IAM role assignment
resource "azurerm_user_assigned_identity" "containerapp" {
location = azurerm_resource_group.rg.location
name = "containerappmi"
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_role_assignment" "containerapp" {
scope = data.azurerm_resource_group.acr.id
role_definition_name = "acrpull"
principal_id = azurerm_user_assigned_identity.containerapp.principal_id
depends_on = [
azurerm_user_assigned_identity.containerapp
]
}
Create Azure Container App using AzAPI, notice:
- Highlighted lines 8-11: Showing assignment of user assigned identity created above
- Highlighted lines 21-26: Showing registry being assigned to the container registry
- Highlighted line 31: Showing image assigned from container registry
resource "azapi_resource" "containerapp" {
type = "Microsoft.App/containerapps@2022-03-01"
name = var.aca_name
parent_id = azurerm_resource_group.rg.id
location = azurerm_resource_group.rg.location
identity {
type = "SystemAssigned, UserAssigned"
identity_ids = [azurerm_user_assigned_identity.containerapp.id]
}
body = jsonencode({
properties = {
managedEnvironmentId = azapi_resource.containerapp_environment.id
configuration = {
ingress = {
external : true,
targetPort : 80
},
"registries" : [
{
"server" : data.azurerm_container_registry.acr.login_server,
"identity" : azurerm_user_assigned_identity.containerapp.id
}
]
}
template = {
containers = [
{
image = "${data.azurerm_container_registry.acr.login_server}/aspcoresample:76ef8d9511d310649729a28563fdf6d133338e30",
name = "firstcontainerappacracr"
resources = {
cpu = 0.25
memory = "0.5Gi"
},
"probes" : [
{
"type" : "Liveness",
"httpGet" : {
"path" : "/",
"port" : 80,
"scheme" : "HTTP"
},
"periodSeconds" : 10
},
{
"type" : "Readiness",
"httpGet" : {
"path" : "/",
"port" : 80,
"scheme" : "HTTP"
},
"periodSeconds" : 10
},
{
"type" : "Startup",
"httpGet" : {
"path" : "/",
"port" : 80,
"scheme" : "HTTP"
},
"periodSeconds" : 10
}
]
}
]
scale = {
minReplicas = 0,
maxReplicas = 2
}
}
}
})
ignore_missing_property = true
depends_on = [
azapi_resource.containerapp_environment
]
}
The terraform files here – have been setup to run locally, with running a successful plan
terraform init
terraform plan
Terraform Plan output:
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azapi_resource.containerapp will be created
+ resource "azapi_resource" "containerapp" {
+ body = (known after apply)
+ id = (known after apply)
+ ignore_casing = false
+ ignore_missing_property = true
+ location = "uksouth"
+ name = "tamopsacablog"
+ output = (known after apply)
+ parent_id = (known after apply)
+ schema_validation_enabled = true
+ tags = (known after apply)
+ type = "Microsoft.App/containerapps@2022-03-01"
+ identity {
+ identity_ids = (known after apply)
+ principal_id = (known after apply)
+ tenant_id = (known after apply)
+ type = "SystemAssigned, UserAssigned"
}
}
# azapi_resource.containerapp_environment will be created
+ resource "azapi_resource" "containerapp_environment" {
+ body = (sensitive)
+ id = (known after apply)
+ ignore_casing = false
+ ignore_missing_property = true
+ location = "uksouth"
+ name = "tamopsacablogenv"
+ output = (known after apply)
+ parent_id = (known after apply)
+ schema_validation_enabled = true
+ tags = (known after apply)
+ type = "Microsoft.App/managedEnvironments@2022-03-01"
+ identity {
+ identity_ids = (known after apply)
+ principal_id = (known after apply)
+ tenant_id = (known after apply)
+ type = (known after apply)
}
}
# azurerm_log_analytics_workspace.loganalytics will be created
+ resource "azurerm_log_analytics_workspace" "loganalytics" {
+ daily_quota_gb = -1
+ id = (known after apply)
+ internet_ingestion_enabled = true
+ internet_query_enabled = true
+ location = "uksouth"
+ name = "tamopsacablog-la"
+ primary_shared_key = (sensitive value)
+ reservation_capacity_in_gb_per_day = (known after apply)
+ resource_group_name = "tamopsacablog-rg"
+ retention_in_days = 30
+ secondary_shared_key = (sensitive value)
+ sku = "PerGB2018"
+ workspace_id = (known after apply)
}
# azurerm_resource_group.rg will be created
+ resource "azurerm_resource_group" "rg" {
+ id = (known after apply)
+ location = "uksouth"
+ name = "tamopsacablog-rg"
}
# azurerm_role_assignment.containerapp will be created
+ resource "azurerm_role_assignment" "containerapp" {
+ id = (known after apply)
+ name = (known after apply)
+ principal_id = (known after apply)
+ principal_type = (known after apply)
+ role_definition_id = (known after apply)
+ role_definition_name = "acrpull"
+ scope = "/subscriptions/04109105-f3ca-44ac-a3a7-66b4936112c3/resourceGroups/tamops-acr-github"
+ skip_service_principal_aad_check = (known after apply)
}
# azurerm_user_assigned_identity.containerapp will be created
+ resource "azurerm_user_assigned_identity" "containerapp" {
+ client_id = (known after apply)
+ id = (known after apply)
+ location = "uksouth"
+ name = "containerappmi"
+ principal_id = (known after apply)
+ resource_group_name = "tamopsacablog-rg"
+ tenant_id = (known after apply)
}
Plan: 6 to add, 0 to change, 0 to destroy.
Running terraform apply, we can review the deployed resources in Azure
terraform apply
![](https://tamops.files.wordpress.com/2022/12/image-9.png?w=991)
Reviewing container app identities, we can see the user assigned identity successfully
![](https://tamops.files.wordpress.com/2022/12/image-10.png?w=944)
Reviewing the container app URL, we can see the container image has been deployed successfully!
![](https://tamops.files.wordpress.com/2022/12/image-11.png?w=1024)
Awesome! Successfully deployed Container App and pulled an image from Azure Container Registry using user assigned managed identity for authentication.
GitHub repository containing example terraform
December 15, 2022 at 03:03PM
Click here for more details...
=============================
The original post is available in Thomas Thornton by Thomas Thornton
this post has been published as it is through automation. Automation script brings all the top bloggers post under a single umbrella.
The purpose of this blog, Follow the top Salesforce bloggers and collect all blogs in a single place through automation.
============================
![Salesforce Salesforce](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFmyaIQdurN6leEPGsGRFLEqL1-DDldAIWOFE8VIMwgIMQzXJseN-Y6ZMrEGv7OSkyRl2X4lYBFVEMigP7eUnfuOd8_gOyr64mYHvyMHBDOEvXJgTYUOoSaNkCJZ_O-1riJmcjw2-MrpJ-QhPwrl1-BoG8yP-iKz9wk1av65OXlMTHJJLQcSIaxwBCdA/s1516/image1.png)
Post a Comment