Azure / azure-dev

A developer CLI that reduces the time it takes for you to get started on Azure. The Azure Developer CLI (azd) provides a set of developer-friendly commands that map to key stages in your workflow - code, build, deploy, monitor, repeat.
https://aka.ms/azd
MIT License
397 stars 191 forks source link

Conditional package/deploy a service #3397

Open azureholic opened 7 months ago

azureholic commented 7 months ago

I have a project with a demo client application, that could be deployed. All the services of the solution are deployed in any case, just this demo app is optional.

I'm now using a postdeploy hook to run azd publish demoapp and azd deploy demoapp when the environment var DEPLOY_DEMO_APP is true (this is one of the bicep variables, that deploys the infra for the app conditionally).

Output from azd version azd version 1.6.1 (commit eba2c978b5443fdb002c95add4011d9e63c2e76f)

Describe the bug the postdeploy hook runs my script and the app gets deployed, but the execution never finishes (azd does not continue and finish to a command prompt). The demoapp is a nodejs application. This is the postdeploy hook script (pwsh)

#get the environment variables 
$azdenv = azd env get-values --output json | ConvertFrom-Json
if ($azdenv.DEPLOY_DEMO_APP) {
    azd package demoapp
    azd deploy demoapp
}

in my azure.yaml i define a custom workflow that will deploy the service that always needs to be provisioned like this

workflows:
  up: # Deploy the application to Azure / Proxy only
      # post-deploy hook will deploy demoapp if parameter 
      # DEPLOY_DEMO_APP is set to true
    - azd: provision
    - azd: package proxy
    - azd: deploy proxy

Expected behavior the postprovision hook script should terminate after the script has run.

Environment Information on your environment:

Additional context I now have 1 service that gets deployed always and 1 service that can be deployed conditional. It would be great if azure.yaml schema could be extended to make conditional deployment possible

 proxy:
    project: ./src/dotnet/YARPProxy
    host: containerapp
    language: dotnet
    condition: <some condition script that returns true of false or an environment variable>
    docker:
      path: ./Dockerfile
      context: ../
wbreza commented 7 months ago

@azureholic

Regarding this script block:

#get the environment variables 
$azdenv = azd env get-values --output json | ConvertFrom-Json
if ($azdenv.DEPLOY_DEMO_APP) {
    azd package demoapp
    azd deploy demoapp
}

You should not need to load environment variables into the script. They are already available on the current process when the script executes. You can access it directly like $DEPLOY_DEMO_APP

azd does not currently support a conditional block today but it is on our backlog. Could you provide more information of your postprovision hook that you are referring to?

As long as the postprovision hook completes without error it should return back to your prompt.

azureholic commented 6 months ago

@wbreza sorry, my bad, it's a post deploy hook (so being triggered after the default service has been deployed). The script will check the env variable to see if the optional service needs to be deployed also (as shown in the powershell script)

hooks:
  postdeploy:
    shell: pwsh
    run: ./scripts/deploy-demoapp.ps1

but I see what the issue is. The post deploy hooks get triggered by deploying this service as part of the script and that will cause an infinite loop.

great to see a conditional deployment out-of-the-box in the future. It would also be great to have conditions on hooks as well.

wbreza commented 6 months ago

@azureholic Another option that you would have now to get around the circular dependency is to set the postdeploy hook on your individual service instead of the project root if you have not done so already. This will allow you to control the lifecycle of your orchestration more easily.

Example

name: my-app
workflows:
  up: # Deploy the application to Azure / Proxy only
      # post-deploy hook will deploy demoapp if parameter 
      # DEPLOY_DEMO_APP is set to true
    - azd: provision
    - azd: package proxy
    - azd: deploy proxy
services:
  demoapp:
    host: containerapp
    language: dotnet
    project: path/to/project
  proxy:
     project: ./src/dotnet/YARPProxy
     host: containerapp
     language: dotnet
     condition: <some condition script that returns true of false or an environment variable>
     docker:
       path: ./Dockerfile
       context: ../
    hooks:
      postdeploy: # Will only ever run after 'proxy' is successfully deployed
        shell: pwsh
        run: ./scripts/deploy-demoapp.ps1
azureholic commented 6 months ago

great point, didn't think of that. Thanks!