Release Azure Functions and file transformations - azure

I have a lot of Azure Functions projects to deploy on Azure. I set build and pipeline for them. For example, this is one Release for an Azure Function.
Under Variables I defined all variables for the environments (one for dev, one for stage and one for production).
There is only one step for deploying the Azure Functions on Azure. I want to add/replace in the local.settings.json the right settings for an environment. I'm not be able to find how to configure that.
In other project, if I use Azure App Service Deploy, there is a section File Transforms & Variable Substitution Options.
How can I do the same in the release of an Azure Functions? What is the correct strategy or best practice?
Update and Solution
I thought it was much straightforward. I think this is the solution. In the App settings under Application and Configuration Settings, I have to specified each variable and its value using the ... in that line.
I can type or copy in this field. The syntax is
-variableName "$(variablename)"
I'm using quotes because if in the value there is any space (for example in the connection string you have Initial Catalog) DevOps raises an error. For array, I'm still using :.

Another way is to use File Transform task to substitute the variables in local.settings.json file with pipeline variables. See here for more information.
With File Transform task, you donot have to specify each variable and its value in App settings of deploy Azure Functions task.
You can add a File Transform task before the deploy Azure Functions task. Then define the variables(eg. KeyVaultSettings.ClientId) in your pipeline variables.
Then set the Package or folder, file format and Target files in File Transform task. See below:

This is what I've done in my Azure Functions pipeline (it's yaml, but you'll get the idea).
Create one stage per environment in your pipeline
Create your pipelines variables and asign a different value based on scope (stage)
Create a configuration entry (see picture) in your pipeline and asign the variable value.
Consume the configuration entry in your Azure Function (in my case I use Environmental Variables for that)
Use pipeline environment in your azure function configuration

Related

Terraform Destroy does not work with Azure Devops Variables in terraform.tfvars

I have very simple pipeline, classic pipeline with Terraform Init, Plan and Apply, how ever deployment failed in middle, so I wanted to destroy all resources…
(backend is remote sitting on Azure blob container
so I enabled only Init and Destroy Task in pipeline, In Init parameters I have provided remote backend details, but when I run pipeline with destroy command it says " variable not allowed"
Actually in terraform.tfvars file I have used azure variable group variable substitution like below
and I have destory task like below
error i get is:
"It isn’t possible to define anything other than static values in a .tfvars file.", see Reference environment variables in .tfvars file.
Alternativly, you can rename the environment variables to start with TF_VAR_ prefix, e.g. TF_VAR_resource_group or you can try to pass the values via -var parameter.
I normally recommend against this type of solutions as it's non-canonical; e.g. there are ways to solve the problem, as #sschmeck has posted, so adding a third-party tool can just create more of a headache.
That said, this article details the use a "Replace Tokens" task in Azure DevOps.
Simply put, you can tell this task to scan for *.tfvars files, and have it replace some tokens with a pattern such as __example__, so in your example:
resource_group = __resource_group__
And set the resource_group variable in a Azure DevOps variable group; it will then search for your specified pattern and replace it.
Again, I would say use TF_VARs as it's canonical, but this may also work for you.

Create variable in Azure pipeline to use in a different pipeline

We have separate pipelines for our infrastructure and our application deployments. For our infrastructure, we are using terraform and i know that you can use terraform outputs as variables in later tasks within the same pipeline but is it possible to save the output as a variable in azure so that it can be used in a different pipeline.
We are looking to use this for S3 bucket names to use in the application code and for VPC subnet and SG ids in serverless.
Is this possible to save variables in the pipeline?
There is a variable group in Azure DevOps to share static values across pipelines.
In your case, if you want to save the terraform output as a variable in the variable group, you need to do something e.g. call the REST API dynamically to set the variable in the variable group, then you can use it in another pipeline.
You could also refer to this similar issue.

Azure Task Group deployment through release - How to get Azure Function App deployment output url 'AppServiceApplicationUrl' for later smoke test task

I've created a task group which deploys an Azure Function App which normally in a normal release pipeline (not a task group), it gives you the option of naming this variable on the panel which opens on the right hand side:
output variable
But when an azure function app task is contained within a task group, it gives you no option to create an output variable.
I was wondering if theres a way I can capture that output variable so I can later use it as a variable in a later task within the same task group?
You will find your variable but under slightly different name.
Assuming you have one FunctionApp in yout ask group you will get it via this variable
AZUREFUNCTIONAPP_APPSERVICEAPPLICATIONURL
To be sure please display all env variables. For Ubuntu you can add bash script with this command
env | sort
For more information please check this GitHub issue.

In azure devops: how can I inject my pipeline variables as appsettings when deploying a docker container to azure?

I'm having trouble setting my appsettings in a deployed docker container on azure.
My setup:
I have a .NET core app
My build pipeline builds a docker image and pushes it to my container registry on azure.
My release pipeline pulls the image based on a tag and deploys it to an azure web app.
I need to deploy the image to multiple environments. Every environment has different appsettings. I defined the variables in my pipeline "variables tab":
And I need to send these to my azure so they can be used.
When I manually add them it works, but i want to extract them from my variables, so I only have to add them once. (see screenshot 1)
Edit: The screenshot above works. But this is not what I'm looking for. As I'd have to edit the appsettings pipeline each time I add or remove a new appsetting. Also I believe that removing an appsetting here will just leave it on the deployed environment.
I'm deploying an existing docker image, so i'm unable to edit the appsetting.json file. I also won't make different docker files for each environment.
Is there a way to achieve this? How can I extract / list the variables defined in my pipeline as docker variables or appsettings?
You can define pipeline variables in your pipeline and have them attached to a specific scope (read stage) or the release scope (applied to all stages).
E.g. I have a variable defined as EnvironmentConnectionString which is defined in two scopes:
Scope Test: "EnvironmentConnectionString = server=test-db; ...."
Scope QA: "EnvironmentConnectionString = server=qa-db;..."
Score Release: "logging_flag=enabled"
Then you can set this up in your "Application and Configuration Settings" like
- ConnectionString $(EnvironmentConnectionString)
- Logging $(logging_flag)
Note the $(variable name) syntax for using these variables
When the different stages of the pipeline run, they automatically pick up the values specific to the stage and apply to azure app settings.
You can have different variable groups for different stages. These Variable Groups should have same variables defined with different values.
For example: The Dev Variable Group and Release group both have variables Port, RequestTimeout... The Port in Dev is 4999 while the Port in Release could be 5000. We can link these groups to specific Stage scope, Dev variable group for Dev stage and Release group for Release stage.
[![enter image description here][1]][1]
Make sure all your stages have same settings like this, and then the variables with be replaced with correspondings values for different scopes.
Update:
Each stage in the pipeline is independent, they represent different environments. So we have to define the settings of stage or settings of the tasks within the stages one by one. We have to define the appsettings input one by one.
[1]: https://i.stack.imgur.com/ukbjs.png

Azure Application Settings not overriding my appsettings.json file values

I have tried adding DefaultConnection from my appsettings.json file to Azure's Application Settings but Azure will not override the connection string.
Any article or blog I can find states that all I should need to do is add the connection string name as it states in the appsettings.json file and Azure should do the rest (e.g. https://tehremo.wordpress.com/2016/10/07/override-connection-strings-app-settings-in-asp-net-core-and-azure-app-service/) however when the application is published it is using my local connection string.
My Startup.cs file looks like the following:
NOTE: I am publishing using VSTS continuous delivery with "Deploy Azure App Service" release task.
I just had a similar problem (the problem was with PostgreSQL connection string type, I had to change it to custom) and now it works for me, so these are the pieces:
This is my appsettings.json file. I have a value for 'Psql' set in my appsettings.Development.json, but in the appsettings.json it is left empty.
These are the settings which are set in the Azure portal. Please note, that there are two ways to override the connection string.
This is the part of my Startup.cs file. Pay attention to the order of how the settings are applied in the Startup constructor and the way I get the connection string in the ConfigureServices method (GetConnectionString is a standard extension method).
Additional info from my comments below:
Azure GUI (Connection strings, Application settings) uses environment variables internally, so the appsettings.json will stay the same.
If there is a need for an appsettings.json's value to be overwritten during VSTS release activity (before it will be published to Azure), Colin's ALM Corner Build & Release Tools can be used. Here are the links to Colin's ALM Corner Build & Release Tools and tutorial.
Thanks #pasul, your help was much appreciated and helped me find an alternative solution. In order to deploy using VSTS task and replace application settings, you will need to add variables to the release task and pass into the task the json file in question for variable substitution.
When in "Deploy Azure App Service" release task you should see a "File Transforms and Variable Substitution" section. In here you will supply the path to the json file you want to swap variable values.
Then you will need to click on the options button on the release environment. You will see an option to configure variables in the pop out menu.
From here you can add the json property you want to modify as a variable. In my case the connection string. Which will look like the following:
"ConnectionStrings.DefaultConnection"
Then just put in your connection string value. VSTS will then swap out these values for you when deploying.

Resources