如何配置 Azure 应用服务以使用 terraform 从 ACR 中提取图像? [英] How to configure an Azure app service to pull images from an ACR with terraform?

查看:12
本文介绍了如何配置 Azure 应用服务以使用 terraform 从 ACR 中提取图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下 terraform 模块来在同一计划下设置应用服务:

I have the following terraform module to setup app services under the same plan:

provider "azurerm" {
}

variable "env" {
    type = string
    description = "The SDLC environment (qa, dev, prod, etc...)"
}

variable "appsvc_names" {
    type = list(string)
    description = "The names of the app services to create under the same app service plan"
}

locals {
    location = "eastus2"
    resource_group_name = "app505-dfpg-${var.env}-web-${local.location}"
    acr_name = "app505dfpgnedeploycr88836"
}

resource "azurerm_app_service_plan" "asp" {
    name                = "${local.resource_group_name}-asp"
    location            = local.location
    resource_group_name = local.resource_group_name
    kind                = "Linux"
    reserved            = true

    sku {
        tier = "Basic"
        size = "B1"
    }
}

resource "azurerm_app_service" "appsvc" {
    for_each            = toset(var.appsvc_names)

    name                = "${local.resource_group_name}-${each.value}-appsvc"
    location            = local.location
    resource_group_name = local.resource_group_name
    app_service_plan_id = azurerm_app_service_plan.asp.id

    site_config {
        linux_fx_version = "DOCKER|${local.acr_name}/${each.value}:latest"
    }

    app_settings = {
        DOCKER_REGISTRY_SERVER_URL = "https://${local.acr_name}.azurecr.io"
    } 
}

output "hostnames" {
  value = {
    for appsvc in azurerm_app_service.appsvc: appsvc.name => appsvc.default_site_hostname
  }
}

我通过如下配置调用它:

I am invoking it through the following configuration:

terraform {
    backend "azurerm" {
    }
}

locals {
    appsvc_names = ["gateway"]
}

module "web" {
    source = "../../modules/web"
    env = "qa"
    appsvc_names = local.appsvc_names
}

output "hostnames" {
    description = "The hostnames of the created app services"
    value       = module.web.hostnames
}

容器注册表有我需要的图像:

The container registry has the images I need:

C:> az acr login --name app505dfpgnedeploycr88836
Login Succeeded
C:> az acr repository list  --name app505dfpgnedeploycr88836
[
  "gateway"
]
C:> az acr repository show-tags --name app505dfpgnedeploycr88836 --repository gateway
[
  "latest"
]
C:>

当我应用 terraform 配置时,一切都创建得很好,但是在 Azure 门户中检查创建的应用服务资源会发现它的容器设置显示没有 docker 图像:

When I apply the terraform configuration everything is created fine, but inspecting the created app service resource in Azure Portal reveals that its Container Settings show no docker image:

现在,我可以手动切换到另一个 ACR,然后再切换回我只想得到这个的那个:

Now, I can manually switch to another ACR and then back to the one I want only to get this:

Cannot perform credential operations for /subscriptions/0f1c414a-a389-47df-aab8-a351876ecd47/resourceGroups/app505-dfpg-ne-deploy-eastus2/providers/Microsoft.ContainerRegistry/registries/app505dfpgnedeploycr88836 as admin user is disabled. Kindly enable admin user as per docs: https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication#admin-account

这让我很困惑.根据 https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication#admin-account 不应使用管理员用户,因此我的 ACR 没有.另一方面,我知道我需要以某种方式配置应用服务以通过 ACR 进行身份验证.

This is confusing me. According to https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication#admin-account the admin user should not be used and so my ACR does not have one. On the other hand, I understand that I need somehow configure the app service to authenticate with the ACR.

那么正确的做法是什么?

What is the right way to do it then?

推荐答案

所以这现在是可能的,因为 v2.71 版本的 Azure RM 提供程序.有几件事必须发生......

So this is now possible since the v2.71 version of the Azure RM provider. A couple of things have to happen...

  1. 为应用分配托管标识(也可以使用用户分配,但需要做更多工作)
  2. site_config.acr_use_managed_identity_credentials 属性设置为 true
  3. 在容器上授予应用程序的身份 ACRPull 权限.
  1. Assign a Managed Identity to the application (can also use User Assigned but a bit more work)
  2. Set the site_config.acr_use_managed_identity_credentials property to true
  3. Grant the application's identity ACRPull rights on the container.

下面是上面代码的修改版,没测试过但应该没问题

Below is a modified version of the code above, not tested but should be ok

provider "azurerm" {
}

variable "env" {
    type = string
    description = "The SDLC environment (qa, dev, prod, etc...)"
}

variable "appsvc_names" {
    type = list(string)
    description = "The names of the app services to create under the same app service plan"
}

locals {
    location = "eastus2"
    resource_group_name = "app505-dfpg-${var.env}-web-${local.location}"
    acr_name = "app505dfpgnedeploycr88836"
}

resource "azurerm_app_service_plan" "asp" {
    name                = "${local.resource_group_name}-asp"
    location            = local.location
    resource_group_name = local.resource_group_name
    kind                = "Linux"
    reserved            = true

    sku {
        tier = "Basic"
        size = "B1"
    }
}

resource "azurerm_app_service" "appsvc" {
    for_each            = toset(var.appsvc_names)

    name                = "${local.resource_group_name}-${each.value}-appsvc"
    location            = local.location
    resource_group_name = local.resource_group_name
    app_service_plan_id = azurerm_app_service_plan.asp.id

    site_config {
        linux_fx_version = "DOCKER|${local.acr_name}/${each.value}:latest"
        acr_use_managed_identity_credentials = true
    }

    app_settings = {
        DOCKER_REGISTRY_SERVER_URL = "https://${local.acr_name}.azurecr.io"
    }

    identity {
        type = "SystemAssigned"
    }   
}

data "azurerm_container_registry" "this" {
  name                = local.acr_name
  resource_group_name = local.resource_group_name
}

resource "azurerm_role_assignment" "acr" {
  for_each             = azurerm_app_service.appsvc
  
  role_definition_name = "AcrPull"
  scope                = azurerm_container_registry.this.id
  principal_id         = each.value.identity[0].principal_id
}

output "hostnames" {
  value = {
    for appsvc in azurerm_app_service.appsvc: appsvc.name => appsvc.default_site_hostname
  }
}

2021 年 12 月 21 日编辑关于由 Azure 重置的值的 MS 文档问题现已解决,并且您还可以通过门户控制托管身份.

EDITED 21 Dec 2021 The MS documentation issue regarding the value being reset by Azure has now been resolved and you can also control Managed Identity via the portal.

这篇关于如何配置 Azure 应用服务以使用 terraform 从 ACR 中提取图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆