0

I'm currently working on a project which uses azure function apps, we also create a data access layers for each function app which are built as nuget packages and are then published to a private nuget feed. For the function apps, we have three separate environments, QA, Staging, and Production.

I want to create separate nuget feeds for each of these environments, so that changes are pushed to the appropriate feed rather than polluting one feed with potentially broken code. I am trying to determine the best way to update the nuget.config files in the function apps to point to the appropriate feed during the CI/CD process.

I've set up similar changes to PHP projects in the past, using a "replace in files between text" task in the build pipeline, but I'm wondering if this is the best approach or if there's a different way I should go about this. I've done quite a bit of googling to try and determine what the best way to do this is but have come up empty so far.

What's the best practice in a case like this?

2
  • It sounds like a problem may be insufficient testing around the code before reaching as far as any fixed QA or Staging environments in the first place. My preferred approach would be for testing in ephemeral environments using an entirely separate Azure account away from the fixed environments; able to be deployed from a feature or integration branch for testing to happen before any code is merged into the main branch (With merging then deployment into fixed environments happening after testers are confident the code is good enough). Commented Feb 12, 2022 at 12:18
  • @BenCottrell, this is a project I inherited from another developer, so your instinct is correct, insufficient testing is at least one component of the problem. The other is that these packages had previously been packed and pushed locally by individual developers, and not all of the changes in those pushed packages were consistently committed and pushed to their corresponding git repo. What I have been endeavoring to do is to tie the deployment of the package into committing changes to the repo, essentially avoiding having gaps between released code and what exists in source control.
    – morris295
    Commented Mar 11, 2022 at 15:47

1 Answer 1

1

I would like to expand on Ben Cottrell's comment, but present you with a fork in the road when it comes to implementing the build pipelines.

My instinct makes me question the need for a NuGet package for each data access layer. NuGet packages solve two main problems: code reuse and code versioning. If the data access layer is not reused by other components, then there is no need for a NuGet package to begin with. Embed the data access layer in the Azure function app. You can still provide interfaces along with concrete classes to promote testability. I would not consider the need to "version" code enough justification to create NuGet packages, which just complicates the build process. Version control, like Git or SVN should suffice for that, especially since you can configure releases in Azure DevOps.

Assuming you have a need to reuse code, I have another fork in the road. Azure function apps enable an event-driven architecture. Only one Azure function should have direct data access. Any data retrieval should be achieved using direct service calls. Mutation of data should be achieved using events. This reduces coupling between Azure functions, eliminating the need for most code reuse. This should allow you to embed the data access code in one Azure function, eliminating the NuGet package conundrum.

Finally we arrive at the last fork in the road — a legitimate, unavoidable need to reuse code across Azure functions. Part of the build pipeline should be running automated tests against these NuGet packages before code gets deployed. This is what Ben is alluding to in his comment on your question:

My preferred approach would be for testing in ephemeral environments using an entirely separate Azure account away from the fixed environments...

Automated tests can include both unit and integration tests. This should catch most defects in these packages before a new version of an Azure function gets deployed. After deploying the Azure function, you should run yet another suite of integration tests. Failures at this point should be caused by misconfigurations or environmental issues rather than logic defects. You should be able to use the Azure release pipeline to roll back the Azure function to it's last known good state, which should prevent downstream failures in the meantime.

There will always be integration problems. You want to avoid troubleshooting environmental, configuration, and logic defects in the same environment. Catching logic defects in their own build pipeline simplifies cases where integration problems occur. That is the position you want to be in.

2
  • Everything you've said is put eloquently and is unquestionably correct. The problem is that I have inherited this project from another developer who didn't understand any of this, so for at least the work that was already completed I need to keep these nuget packages until such time as refactoring can be done. I did find a way around this which is that nuget provides the ability to specify a package feed on the restore or push step, so I was able to resolve this.
    – morris295
    Commented Mar 11, 2022 at 15:29
  • @morris295: that is a tough spot to be in. Glad you could figure it out in the short term. Commented Mar 11, 2022 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.