Can docker on Azure Linux App Service authenticate with the ACR without us specifying the password in the app settings?

Viewed 1341

We deploy a Linux App Service to Azure using terraform. The relevant configuration code is:

resource "azurerm_app_service" "webapp" {
  app_settings = {
    DOCKER_REGISTRY_SERVER_URL              = "https://${local.ctx.AcrName}.azurecr.io"
    DOCKER_REGISTRY_SERVER_USERNAME         = data.azurerm_key_vault_secret.acr_admin_user.value
    DOCKER_REGISTRY_SERVER_PASSWORD         = data.azurerm_key_vault_secret.acr_admin_password.value
    ...
  }
  ...
}

The problem is that terraform does not consider app_settings a secret and so it outputs in the clear the DOCKER_REGISTRY_SERVER_PASSWORD value in the Azure DevOps output (I obfuscated the actual values): enter image description here

So, I am wondering - can docker running on an Azure Linux App Service host authenticate with the respective ACR without us having to pass the password in a way that makes it so obvious to every one who can inspect the pipeline output?

The following article seems relevant in general - https://docs.docker.com/engine/reference/commandline/login, but it is unclear how we can apply it in my context, if at all.

Also, according to https://feedback.azure.com/forums/169385-web-apps/suggestions/36145444-web-app-for-containers-acr-access-requires-admin#%7Btoggle_previous_statuses%7D Microsoft has started working on something relevant, but looks like this is still a work in progress (almost 5 months).

2 Answers

I'm afraid you must set the environment variables about DOCKER_REGISTRY_* to pull the images from the ACR, it's the only way to do that designed by Azure. But for the sensitive info about the password, it also provides a way to hide it. You can use the Key Vault to store the password in secret, and then get the password from the secret. Take a look at the document Use Key Vault references for App Service. So you can change the app_setting for the password like this:

DOCKER_REGISTRY_SERVER_PASSWORD = "@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)"

Or

DOCKER_REGISTRY_SERVER_PASSWORD = "@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret;SecretVersion=ec96f02080254f109c51a1f14cdb1931)"

Then it just shows the reference of the Key Vault, not the exact password.

Unfortunately Azure Web Apps do not support interacting with ACR using a managed identity, you must pass those Environment Variables to the App Service.

Terraform does not currently support applying a "sensitive" flag to arbitrary values. You can define outputs as sensitive, but it will not help with values you want to hide during the plan phase.

I would suggest checking out https://github.com/cloudposse/tfmask, using the TFMASK_RESOURCES_REGEX configuration to block the output you want to hide during your pipeline. If you're averse to adding dependencies, similar effect could be achieved by piping terraform apply through grep --invert-match "DOCKER_REGISTRY" instead.

@charles-xu has a good answer as well if you want to set up mappings between keyvault and your web app then push your tokens into kv secrets.

Related