In the previous post, we have configured an app registration to give us the means to identify the Let’s Encrypt app during automatic jobs. Now we will give access to the app so that it can manage the resources inside the web application for us.

Go to the resource group that contains the web app where the SSL certificate will be installed. Click on the Access control (IAM) menu:

Resource group access control

On the right-hand side of the page, you should be able to see the role assignment widget. Click on the Add button inside it:

Add role assignment button

And in the role assignment window, add the Let’s Encrypt app registration as a contributor to the resource group as shown below. To find the correct app registration, use the search functionality inside the Select field. When searching for the app name, the search results will be shown below the Select field. Once clicked in the result, the app registration will then also be shown in the Selected members list.

Add role assignment window

Click the save button to finalise granting the rights to the application. Now technically, the Let’s Encrypt app has the necessary rights to modify our resources inside the selected group.

Finding the subscription id

Before we conclude this step, since we are already inside the Resource group page, take note of the subscription ID as indicated above. We will also need this later, together with the client secret and client ID which we had copied during the first step. Then in the next step, we will set up a storage account.

As reported in Microsoft’s Identity Platform Blog, the user experience for Azure App Registrations has changed, and the choice to use the legacy editor will not be available after March 1st. The end result is that some things in Azure Active Directory(AAD) have been moved around. So I decided that it’s time to do another series of blog posts to describe how to configure your Azure Web App with a free Let’s Encrypt certificate because AAD is an essential part of the process.

In this first post, I will go through the process of creating an App Registration inside Azure Active Directory. By the end of the series, we will have a Let’s Encrypt extension running beside our web app. Since the generated certificates will expire every three months, this extension will renew SSL certificates automatically for us.

We need a way to give the Let's Encrypt extension access to our Azure resource group so that it can manage the resources automatically for us. An Azure App Registration will enable us to create an authentication account that the extension will use to log into our Azure Active Directory.

So without further ado, let’s start our journey to make our site secure. From the Azure Portal dashboard, click on Azure Active Directory:

Azure Active Directory Icon

Then further down look for the App registrations menu, and click the + New registration button:

New app registration menu

This will open a new window to register the app. Here we need to provide any name which we will use to identify the application (I opted to name it Let's Encrypt). The supported account type should be ‘Accounts in this organizational directory only (Default Directory only - Single tenant)’ and the redirect URI filled in with the web app’s URL.

Register an application window

Click the Register button and wait for the app registration to be created.

Now we need to create the actual login. Once back to the app registrations page, click on Certificates & secrets, and then + New client secret:

Certificates and secrets menu

Give it a descriptive name and the desired expiry time.

Add a client secret window

After the secret store is created, its value will be displayed. Make sure to copy the value by hovering on the field and clicking on the copy icon as shown below. For security reasons, this value will be hidden when you try to view it in a future session (otherwise it wouldn't be a secret anymore). We will then use this secret once when configuring the Let’s Encrypt extension during the last step and dispose of the information immediately after.

Copy the client secret

Back inside the app registration window, we also need to make a note of the application id for later.

Copy the application id

In the second step, we will give the Let's Encrypt account that we just created access to our Azure resources.

In this tutorial, we will see how to create a YAML build pipeline from an existing pipeline built with the classic editor. Creating a YAML build pipeline from scratch may be intimidating for novice users, but if you have an existing one in the classic editor, switching over is easier. You don’t need to be a YAML guru.

Once logged in Azure DevOps, head over to your existing pipeline. This can be accessed from the build pipelines section as shown below.

Opening the original pipeline

In my case, I have a pipeline to build this website’s code. Click on the job name, then we will have the option to view it in YAML form.

View it as YAML

This will open a popup window showing the existing job in the YAML format. Click the ‘Copy to clipboard’ button. We will need to paste this code into a new file soon.

Copy YAML to clipboard

We now need to copy the code and store it inside a text file in our repository. This can be done directly from the Azure DevOps portal. From your repository, create a new branch and then a new file right afterwards. Put this new file in the Pipeline folder, so that it will not be stored directly beside your code.

Create new YAML file

Paste the copied YAML into the new file.

The YAML editor

Before you commit, it is important to check if you need to specify the image name of the build agent. When you run your build on an Azure-hosted agent, you need to add the vmImage parameter, as I did with windows-2019 below. If you have a private agent instead, just the name of the agent is enough.

Setting the YAML build agent

Now we can go back to the build pipelines page and click on the button to create a new pipeline.

Start build with Azure Repos Git

On the next step, click on the repository name.

Selecting the repository

And on the Configure step, we will select an ‘Existing Azure Pipelines YAML file’.

Connect pipeline to existing YAML file

Then choose the filename that we just saved a few steps back.

Selecting the YAML file

On the final review step, we can now add the required variables. The generated YAML file contains comments about the variables that the build expects so that it can run successfully.

Need to declare some variables

Click on the Variables button so that we can add them and then just add each one individually. We can look the existing classic pipeline if we need to verify the values of the variables.

Adding a variable for YAML pipeline

We can now click the Run button to test the pipeline.

The build is queued

Once the job finishes, we can check the outcome.

The build run outcome

So now we now that the build has run successfully, we can set it to be triggered automatically whenever any code is committed into the master branch. Go back to edit the YAML file and add the trigger as shown here.

Adding a master branch trigger to the YAML file

And there’s no better way to test it than creating a pull request on the YAML file so that it can be integrated into master and automatically trigger the build. Create a new pull request and choose to merge the new branch into master.

The change is ready to be added to a pull request

If this triggers the build, then we have confirmed that we have really managed to set up everything successfully.

The pull request has triggered the build

Last time we left off by triggering the NuKeeper build pipeline that we had just created. Today, we will edit the pipeline configuration with a schedule to run regularly and so we can get on with the rest our work safe in the knowledge that automation is taking care of the updates.

To start, click on the pipelines icon and choose Edit from the context menu of the existing pipeline.

Menu to edit the build pipeline

Choose the triggers tab and then click on the Add button to create the schedule. Enter the day of the week and the time when you wish the build to run. Make sure to uncheck the option to ‘Only schedule builds if the source or pipeline has changed’ because otherwise, NuKeeper will only check for updates whenever you also change the source code.

Adding a scheduled trigger

Once happy with the setup, save your changes.

Save the build pipeline

And enter a comment which describes the modification.

Describing what was done in this change

You’re all set now. NuKeeper will check for nuget package updates depending on the schedule. However, we can go one step further. Let’s modify the branch policy so that reviewers are added automatically when NuKeeper creates a pull request. Click on the icons as shown below:

Edit the branch policies

And add the code reviewers as required. You can include individual users or groups of users. In the latter case, any group member will be able to approve the update. When a pull request is created, all the reviewers listed here will receive a notification. We can also specify a file path, since we know that NuKeeper will only modify the csproj files.

Include the reviewers automatically

Lastly, we can also talk about configuration. The full details of the configuration options are described on the NuKeeper site, but let’s pick up a few of the most popular. These configuration options can be added to your pipeline as arguments in the NuKeeper task.

Azure DevOps NuKeeper configuration

By default, the only argument is -m 3, which means that the task will update up to three packages at any one time. We can also set the age of the packages that we want to update (with the -a argument), which will be seven days if not specified. In this way, we will wait for the package to be tried and tested in the wild for any problems before we automatically attempt to add it into our solution. However, this value can also be specified in hours or disabled completely so any new package will be picked up immediately.

Another popular argument is the c argument (which stands for change). Here we can specify the level of the version changes we want NuKeeper to include; patch, minor, or major. Some major changes can potentially include breaking changes and some teams may choose to apply these updates manually, or otherwise plan for them.

If indeed we know that there are packages with breaking changes, we can then use the exclude argument (e) so that NuKeeper will leave them alone. The consolidate argument (n) will combine all the updates into a single pull request, otherwise by default, the task will create a pull request for each package. The useprerelease argument (no shortcut for this one) will specify if we want to include alpha or beta package releases or not, and the nice thing is that by default it is set to update to a newer pre-release version only if you are already using a pre-release version of a package. I will let you explore the rest of the options, but by using the above you will already gain a big advantage with a lot of flexibility.

NuKeeper is a tool that automatically updates any third-party Nuget packages inside your solution to the latest version. Today we will create a pipeline which will be set up to specifically run this tool. NuKeeper will then scan the solution, and if there are updates it will go ahead and create a new feature branch, apply the changes, and present them as a pull-request for you to approve. Isn’t that a handy buddy?

So we will start by clicking the New Pipeline button within the Pipelines section of Azure DevOps. At the moment, the Azure DevOps YAML editor does not provide us with the full experience to install and choose a new task yet (which we need for NuKeeper), so we will use the classic editor instead.

Given the choice, we will go for the classic build pipeline editor

Select Azure Repos Git as the source control type, and find the relevant repository where the source code is stored. Obviously, if your source code is using a different source control type, it has to be configured accordingly.

Choosing the location of our solution

Next, I’m offered to create a pipeline from a template, but I will start with an empty job instead. This will create a simple job with no tasks which is fine since we only need to add one specific task. Make sure to change the name to indicate that this pipeline will be used for updating third-party libraries inside the solution. As for the agent that the pipeline will run on, I’m happy enough to use the windows-2019 hosted agent to run this job for me.

An empty build pipeline is created

In the case of NuKeeper, the job is very easy to configure. It just needs one task, which is started by clicking on the + button:

Adding a task to the build pipeline

The Add tasks section will show up. Here we can search directly for ‘nukeeper’ to get the result we want from the marketplace. The first time that a task from the marketplace is used within your organisation, it has to be approved by an administrator. Click on the ‘Get it free’ button to do that. If we want to use the nukeeper task again in any future pipelines we create, it will be already approved and the Add button will be shown directly.

Find the NuKeeper task

Clicking the button will open the NuKeeper page within the Visual Studio Marketplace site, where we need to click the ‘Get it free’ button once again.

NuKeeper on the Visual Studio Marketplace

And one more button click to install the extension.

Marketplace extension needs to be approved by the organisation the first time it is used

One thing to note is that if you are not the administrator of your organisation, you can still click the ‘Get it free’ button. At that point, an email request will be sent to the administrator who will then need to accept and do the installation step.

After a few seconds, you should see that the installation was completed successfully.

NuKeeper extension added to organisation

When I got back to my build pipeline, I still needed to refresh the page so that I can actually select the NuKeeper task that I just installed. To do this, save the pipeline first so we can keep the existing configuration and then reload the whole page.

Saving the build pipeline

You will be asked to choose the folder where the pipeline will be saved. The default will do for now, but if you have a project with multiple build pipelines, organising them into specific folders becomes important.

Choosing the destination folder for the build pipeline save

Now we can see that it is possible to add the task to the job, so go ahead and click the Add button.

Add NuKeeper task to pipeline

Once added, the NuKeeper task will be shown inside the job. NuKeeper has some configuration options, but we will stay with the default setting for now. By default, NuKeeper will update up to three packages at a time. We will use that, and I will explain the configuration options in a future post.

NuKeeper task added

So now it’s time to Save & queue the job we just configured. A new window will be shown, where we will Save and run. Note the comment in the screenshot below, which explains the changes that are being saved.

Save and run the build pipeline

Once the build is run, you can click on the job name to follow the progress of the build pipeline.

Progress of the build run

Around a minute later we get a summary of the build run.

Summary shows that everything is fine

Everything looks ok at first glance, all those green checkmarks must surely indicate that it is so. However, digging in deeper we can see that there is a problem:

Details view shows that there are problems

NuKeeper has identified that there are packages to update, but the updates failed. Apparently something with LibGit2SharpException : request failed with status code: 403. This is due to some permissions that we need to assign to the build service. In this case, we need to go to the Project settings menu, then repositories, and then choose the relevant repository that we need to allow NuKeeper to modify.

Navigating to the repository settings from the project settings

The NuKeeper task through the project collection build service needs to be able to create a new branch and contribute code changes to it. Note the required permissions marked with a green checkmark below.

Changing repository settings

Let’s run the build pipeline again. Now we can see that the updates are successful!

Running the build pipeline again

And there are also pull requests for us to approve!

Pull requests from NuKeeper are available

In the screenshot below, we can see a detailed report of the changes included in the pull request. We can also see that the pull request has triggered a build which we had set up in a previous post about setting up pull requests in Azure DevOps. This build will confirm whether the changes that NuKeeper has done will compile the code and the unit tests will all pass. With this peace of mind we can then go ahead and approve the pull request.

NuKeeper pull request details

Next time we will see the different configuration options that NuKeeper provides. We will also schedule the task to run regularly and so keep our solution always up to date with minimal effort.

Buy me a coffee Buy me a coffee