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
410 stars 198 forks source link

[Issue] Cannot run `azd down` when using conditional deployment #553

Open KSchlobohm opened 2 years ago

KSchlobohm commented 2 years ago

Output from azd version

azd version 0.1.0-beta.5 (commit 7bd25dd6f1b1899abf63b5f6f36d268a465183e4)

Output from az version

{
  "azure-cli": "2.38.0",
  "azure-cli-core": "2.38.0",
  "azure-cli-telemetry": "1.0.6",
  "extensions": {
    "containerapp": "0.3.5",
    "log-analytics": "0.2.2",
    "rdbms-connect": "1.0.2"
  }
}

Describe the bug Cannot run azd down because AZD reads resourceGroup names from deployment groups and finds a group name that has not been deployed.

Error: listing resource group rg-azd-conditional2: failed running az resource list: exit code: 3, stdout: , stderr: ERROR: (ResourceGroupNotFound) Resource group 'rg-azd-conditional2' could not be found.
Code: ResourceGroupNotFound
Message: Resource group 'rg-azd-conditional2' could not be found.
: exit status 3

To Reproduce

  1. azd init
  2. Choose a template (I chose todo-csharp-cosmos-sql)
  3. Open main.bicep and add the following

resource resourceGroup2 'Microsoft.Resources/resourceGroups@2021-04-01' = if (false) {
  name: '${abbrs.resourcesResourceGroups}${name}2'
  location: location
  tags: tags
}

module secondaryResources 'resources.bicep' = if (false) {
  name: 'resources2'
  scope: resourceGroup2
  params: {
    location: location
    principalId: principalId
    resourceToken: resourceToken
    tags: tags
  }
}
  1. Run azd provision
  2. Observe - Verify the 2nd resource group was not deployed
  3. Run azd down --no-prompt --force
  4. Observe - The command will fail with error message shown above
  5. Run az deployment sub show -n {name}
  6. Observe - The 2nd resource group was not deployed because the conditional is false but the deployment included it in the description. This causes the azd command to fail because it thinks 2 resource groups were deployed.

Expected behavior Expected azd down to delete resources

Environment Information on your environment:

ellismg commented 2 years ago

This is a very interesting issue, and something I hadn't considered before. The implementation of azd down works by fetching the most recently deployment and collecting all resource groups from it, which it then deletes. This is logic that is 100% implemented by azd (since Azure has no related concept).

We should look at what the deployment object looks like in this case and see if there's a better way for us to gather this information.

One thing to ponder (I'm not sure what the answer is here): Imagine that secondaryResources was conditional on some parameter, which you configured via the environment value DEPLOY_SECONDARY_RESOURCES. Then you do something like this:

azd env set DEPLOY_SECONDARY_RESOURCES true
azd provision # this creates the secondary resources
azd env set DEPLOY_SECONDARY_RESOURCES false
azd provision # this doesn't create the secondary resources (but they don't get deleted, since ARM doesn't work that way)
azd down --no-prompt --force  # does this delete the secondary resource group?

In the above, the most recently deployment won't show anything about the second resource group, and so when we fix this issue azd down would not delete it. Is that behavior going to be surprising? @KSchlobohm what would you expect here?

Note that the story here would be different for Terraform and Pulumi, in both cases the down operation translates to destory and these tools use the state file to ensure they only destroy tracked resources.

KSchlobohm commented 2 years ago

@ellismg we're using an environment parameter of SECONDARY_AZURE_LOCATION to trigger this behavior. We expect that parameter to be an empty string for non-prod environments and it should be the name of an azure region when we deploy the multiregional production scenario.

In the non-prod scenario, when the condition is false, I still get this error but I'd like azd to delete the 1 resource group. In the prod scenario, when the condition is true I'd like it to delete both resource groups (and it does).

The challenge with deploying code in the prod scenario is explored in #328 where having the same code deployed twice (conditionally) requires me to use the azd env set AZURE_RESOURCE_GROUP {myname} to tell azd which resource group to target. It's not currently a requirement to use 2 resource groups to target two regions, that's just how I discovered it.