Azure / azure-functions-on-container-apps

Docs , samples and issues for Azure Functions on Azure Container Apps
MIT License
74 stars 18 forks source link

Setting up continuous deployment on a container app through the portal fails due to deny assignment #65

Open peter-mskeng opened 4 months ago

peter-mskeng commented 4 months ago

Which language are you using?

Typescript/Node

Provide resource details

  1. Function app name: msk-functions-node
  2. Resource id: /subscriptions/e0f035e9-2d23-4fa1-bc02-b4367ea174f1/resourceGroups/MskContainerappEnvironment_FunctionApps_88542ce8-3b01-4d55-9ced-410277f17b64/providers/Microsoft.App/containerapps/msk-functions-node

Expected behavior

Setting up continuous deployment on the container app through the portal would be successful.

Actual behavior

Set up fails due to a deny assignment on the system-generated resource group.

To Reproduce

Steps to reproduce the behavior:

  1. Follow tutorial here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-deploy-container-apps?tabs=acr%2Cbash&pivots=programming-language-typescript
  2. Navigate to the newly created container app in the Azure portal.
  3. Note the system-generated resource group, which does not follow the expected resource group from the tutorial.
  4. Under "Get Started", click "Set up deployment", configure settings, and then click "Start continuous deployment".
  5. "Start continuous deployment" fails with deny assignment error.

Additional context

The container app resource group appears to be a system-generated resource group, and the deny assignment appears to be intended to prevent modifications that may result in an incorrect state.

Given these constraints, what is the correct way to set up continuous deployment?

raorugan commented 4 months ago

Hi @peter-mskeng , enabling deployment center from portal is currently work in progress. Deployment from system resource group will not work. In the meanwhile it is recommended to use Github Actions or Azure pipelines . Here are the samples github action - https://github.com/Azure/azure-functions-on-container-apps/tree/main/samples/GitHubActions, Azure pipelines - https://github.com/Azure/azure-functions-on-container-apps/tree/main/samples/AzurePipelineTasks.

@peter-mskeng - would like to meet with you and discuss your scenario , requirements . this will help shape the roadmap. Please drop a note to ramya.oruganti@microsoft.com. Look forward to talking to you!

peter-mskeng commented 4 months ago

Ok thanks, I will try the Github Action with Azure Service Principle for RBAC. I had previously gone down this route following the learn more link from the portal, but then got stuck on deployment credentials. So thank you providing for this sample repository with instructions.

Yes, I would be happy to meet to discuss our scenario, will email you. Briefly, we have been building out a static web app with a managed API backend, then we had the opportunity to integrate a key data source via ODBC, but this required a custom driver, so after some research I determined we could build a docker image off the base azure functions image, install the driver there, and then deploy to a container.

This works successfully so far, so now I am trying to configure continuous deployment on the container app. We're using Github Actions for the static web app and it works very well, so we hope to use the same pattern for the container app too.

peter-mskeng commented 4 months ago

I got this to work after some trial and error, using https://github.com/Azure/azure-functions-on-container-apps/tree/main/samples/GitHubActions as suggested.

Specifically, in the build step I had to use "docker.io" for both LOGIN_SERVER and REGISTRY, but then in the deploy step I had to use "registry.hub.docker.com" instead of "docker.io".

These other combinations failed:

Like so:

name: Deploy container to Azure Functions App

on:
  # Automatically trigger it when detected changes in repo
  push:
    branches: [ main ]

permissions:
  contents: read

env:
  AZURE_FUNCTION_APP_NAME: 'msk-functions-node'   # set this to your function app name on Azure
  LOGIN_SERVER: 'docker.io'                       # set this to login server for your private container registry (e.g. 'contoso.azurecr.io', 'docker.io' )
  REGISTRY: 'docker.io'                           # set this to proper value for REGISTRY
  NAMESPACE: '******'                             # set this to proper value for NAMESPACE
  IMAGE: '**************'                         # set this to proper value for IMAGE
  TAG: ${{ github.sha }}                          # set this to proper value for TAG
  REGISTRY2: 'registry.hub.docker.com'

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout to the branch
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Log in to container registry
        uses: docker/login-action@v1
        with:
          registry: ${{ env.LOGIN_SERVER }}
          username: ${{ secrets.REGISTRY_USERNAME }}
          password: ${{ secrets.REGISTRY_PASSWORD }}

      - name: Build and push container image to registry
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }}
          file: ./Dockerfile
          context: ./

  deploy:
    runs-on: ubuntu-latest
    needs: build

    steps:
      - name: Azure Login
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_RBAC_CREDENTIALS }}

      - name: 'Run Azure Functions Container Action'
        uses: Azure/functions-container-action@v1
        id: fa
        with:
          app-name: ${{ env.AZURE_FUNCTION_APP_NAME }}
          image: ${{ env.REGISTRY2 }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }}

      # If you want to display or use the functionapp url, then uncomment the task below
      #- name: 'Published functionapp url'
      #  run: |
      #    echo "${{ steps.fa.outputs.app-url }}"

      - name: Azure logout
        run: |
          az logout
mtycholaz commented 4 months ago

Just ran into this same issue in the portal. I can't create a new revision to update my app because of the deny assignment! My only current workaround is to push two docker images with different tags to my registry, and then manually change the image my function app is configured for. Not ideal, but it works for now. I'll eventually end up with a github actions workflow, but not ready for that yet.

raorugan commented 4 months ago

Hi Matt, per design the user is expected to interact with functions resource and not the underlying azure container apps resource or the revisions. Azure Functions is handles revisions and the latest revision is always picked by Azure Functions resource. If you are trying to update the resource with new image , check out the guidance here - https://github.com/Azure/azure-functions-on-container-apps/tree/main/samples/VSCode%20Sample#update-code-or-container-image or github actions would pick up the updates from your code , build it and deploy to Azure Functions resource. Btw what is your scenario?

mtycholaz commented 4 months ago

Hi Matt, per design the user is expected to interact with functions resource and not the underlying azure container apps resource or the revisions. Azure Functions is handles revisions and the latest revision is always picked by Azure Functions resource. If you are trying to update the resource with new image , check out the guidance here - https://github.com/Azure/azure-functions-on-container-apps/tree/main/samples/VSCode%20Sample#update-code-or-container-image or github actions would pick up the updates from your code , build it and deploy to Azure Functions resource. Btw what is your scenario?

It was my assumption that when I push an image (with the same tag, in my case 'latest') to the Azure Container Repo, that either the function resource or function container app would detect this, spin down the old revision, and create a new revision based on the updated image.

Currently, I have to manually update the version by going to the function resource itself and selecting a new tag. Even if I could restart the container app, and it would pick up the new image that would help. But I even get denied access to restart the container app.

My scenario is that I'm a single dev pushing from my local box, with no cicd (yet).

raorugan commented 3 months ago

hi @mtycholaz - container restart has to happen to pull the image - this happens only if functions in stop/start or if you update the function app or new revision conditions happen like -A new revision is created when a container app is updated with revision-scope changes. The changes are limited to the revision in which they're deployed, and don't affect other revisions.

A revision-scope change is any change to the parameters in the properties.template section of the container app resource template.

These parameters include:

Revision suffix Container configuration and images - Updates to images or configs of functions Scale rules for the container application - Not supported for functions on ACA

Functions start/stop will be out soon so you can trigger this. Hope this helps!