This week, we're exploring a wide range of topics, from .NET 10 previews and A/B testing to the latest in Azure development and AI. Plus, a selection of insightful podcast episodes to keep you informed and inspired.
Docker Model Runner ( DevOps and Docker Talk: Cloud Native Interviews and Tooling) - I tried the new model feature of Docker and had many questions. All of them were answered during this episode.
Michael Washington: The Nature Of Data - Episode 353 (Azure & DevOps Podcast) - Interesting discussion about data, and a bit more about a really cool project, Michael's Data warehouse, because sometimes we need something that runs locally.
Automating deployments is something I always enjoy. However, it's true that it often takes more time than a simple "right-click deploy." Plus, you may need to know different technologies and scripting languages.
But what if there was a tool that could help you write everything you need—Infrastructure as Code (IaC) files, scripts to copy files, and scripts to populate a database? In this post, we'll explore how the Azure Developer CLI (azd) can make deployments much easier.
What do we want to do?
Our goal: Deploy the 2D6 Dungeon App to Azure Container Apps.
This .NET Aspire solution includes:
A frontend
A data API
A database
The Problem
In a previous post, we showed how azd up can easily deploy web apps to Azure.
If we try the same command for this solution, the deployment will be successful—but incomplete:
The .NET Blazor frontend is deployed perfectly.
However, the app fails when trying to access data.
Looking at the logs, we see the database wasn't created or populated, and the API container fails to start.
Let's look more closely at these issues.
The Database
When running the solution locally, Aspire creates a MySQL container and executes SQL scripts to create and populate the tables. This is specified in the AppHost project:
var mysql = builder.AddMySql("sqlsvr2d6")
.WithLifetime(ContainerLifetime.Persistent);
var db2d6 = mysql.AddDatabase("db2d6");
mysql.WithInitBindMount(source: "../../database/scripts", isReadOnly: false);
When MySQL starts, it looks for SQL files in a specific folder and executes them. Locally, this works because the bind mount is mapped to a local folder with the files.
However, when deployed to Azure:
The mounts are created in Azure Storage Files
The files are missing!
The Data API
This project uses Data API Builder (dab). Based on a single config file, a full data API is built and hosted in a container.
Locally, Aspire creates a DAB container and reads the JSON config file to create the API. This is specified in the AppHost project:
var dab = builder.AddDataAPIBuilder("dab", ["../../database/dab-config.json"])
.WithReference(db2d6)
.WaitFor(db2d6);
But once again, when deployed to Azure, the file is missing. The DAB container starts but fails to find the config file.
The Solution
The solution is simple: the SQL scripts and DAB config file need to be uploaded into Azure Storage Files during deployment.
You can do this by adding a post-provision hook in the azure.yaml file to execute a script that uploads the files. See an example of a post-provision hook in this post.
Alternatively, you can leverage azd alpha features: azd.operations and infraSynth.
azd.operations extends the provisioning providers and will upload the files for us.
infraSynth generates the IaC files for the entire solution.
💡Note: These features are in alpha and subject to change.
Each azd alpha feature can be turned on individually. To see all features:
azd config list-alpha
To activate the features we need:
azd config set alpha.azd.operations on
azd config set alpha.infraSynth on
Let's Try It
Once the azd.operation feature is activated, any azd up will now upload the files into Azure. If you check the database, you'll see that the db2d6 database was created and populated. Yay!
However, the DAB API will still fail to start. Why? Because, currently, DAB looks for a file, not a folder, when it starts. This can be fixed by modifying the IaC files.
One Last Step: Synthesize the IaC Files
First, let's synthesize the IaC files. These Bicep files describe the required infrastructure for our solution.
With the infraSynth feature activated, run:
azd infra synth
You'll now see a new infra folder under the AppHost project, with YAML files matching the container names. Each file contains the details for creating a container.
Open the dab.tmpl.yaml file to see the DAB API configuration. Look for the volumeMounts section. To help DAB find its config file, add subPath: dab-config.json to make the binding more specific:
You can also specify the scaling minimum and maximum number of replicas if you wish.
Now that the IaC files are created, azd will use them. If you run azd up again, the execution time will be much faster—azd deployment is incremental and only does "what changed."
The Final Result
The solution is now fully deployed:
The database is there with the data
The API works as expected
You can use your application!
Bonus: Deploying with CI/CD
Want to deploy with CI/CD? First, generate the GitHub Action (or Azure DevOps) workflow with:
azd pipeline config
Then, add a step to activate the alpha feature before the provisioning step in the azure-dev.yml file generated by the previous command.
- name: Extends provisioning providers with azd operations
run: azd config set alpha.azd.operations on
With these changes, and assuming the infra files are included in the repo, the deployment will work on the first try.
Conclusion
It's exciting to see how tools like azd are shaping the future of development and deployment. Not only do they make the developer's life easier today by automating complex tasks, but they also ensure you're ready for production with all the necessary Infrastructure as Code (IaC) files in place. The journey from code to cloud has never been smoother!
If you have any questions or feedback, I'm always happy to help—just reach out on your favorite social media platform.
In this post, I will share a few things that we need our attention when deploying a .NET isolated Azure Function from GitHub to Azure using the Zip Deploy method. This method is great for fast deployment and when your artefacts are zipped in a package.
Note The complete code for this post is available on GitHub
Understanding Zip Push/Zip Deploy
Zip Push allows us to deploy a compressed package, such as a zip file, directly to Azure. It could be part of a continuous integration and continuous deployment (CI-CD) or like in this example it could replace it. This approach is particularly useful when you want to ensure your artifacts remain unchanged across different environments or when aiming for the fastest deployment experience for users.
While CI-CD is excellent for keeping your code up-to-date, zip deployment offers the advantage of speed and consistency. It eliminates the need for compilation, leading to quicker uploads and deployments.
Preparing Your Package
It’s crucial to package with all necessary dependencies the code required. There is no operation to fetch any external packages during the deployment, the zip file will be decompressed and that's it. The best way to ensure you have everything you need is to publish your code, to a folder and then go in that folder and zip all the files.
dotnet publish -c Release -o ./out
Don't zip the folder, it won't work as expected.
You need to go inside the folder and select all the files and zip them to create your deployment artefact.
The next step is to make your artefact available online. There are many ways, but for this post we are using GitHub Realease. From the GitHub repository, create a new release, upload the zipped file created earlier and publish it. Note the URL of zipped files from the release.
Preparing The ARM Template
For this one-click deployment, we need an Azure Resource Manager (ARM) template. This is a document that describes the resources that we want to deploy to Azure. To deploy the zipped file into the Azure Function there are two particularities that required our attention.
Here we define an Windows Azure Function and the WEBSITE_RUN_FROM_PACKAGE needs to be set to 1. The WEBSITE_RUN_FROM_PACKAGE is the key that tells Azure to use the zip file as the deployment artefact.
Then to specify where the zip file is located we need to add an extension to the Azure Function.
The packageUri property is the URL of the zipped file from the GitHub release. Note the dependsOn property that ensures the Azure Function is created before the extension is added. The complete ARM template is available in the GitHub repository.
One-click Deployment
When you have your artefact and the ARM template uploaded to your GitHub repository, you can create a one-click deployment button. This button will take the user to the Azure portal and pre-fill the deployment form with the information from the ARM template. Here is an example of the button for markdown.
[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FFBoucher%2FZipDeploy-AzFunc%2Fmain%2Fdeployment%2Fazuredeploy.json)
The has three parts, the first is the image that will be displayed on the button, the second is the link to the Azure portal and the third is the URL of the ARM template. The URL of the ARM template is the raw URL of the file in the GitHub repository, and it needs to be URL encoded. The URL encoding can be done using a tool like URL Encode/Decode.
Final Thoughts
Zip deployment is a powerful tool in your Azure arsenal by itself of part of a more complex CI-CD pipeline. It's a great way to make it easier for people to deploy your solution in their Azure subscription without having to clone/ fork the repository.
Video version
If you prefer, there is also have a video version of this post.
Monday! It is time to share my reading notes. It is a habit I started a long time ago where I share a list of all blog posts that catch my interest during the week.
If you think you may have interesting content, share it!
Debugging distributed systems is hard! (Dennis Frühauff) - This is a very nice post that explains clearly a situation. How many of us have been in this situation before where you try to debug a system and it's just so hard?
Healthcare and Life Sciences Blog (Kyle Raymond) - This is a cool tutorial/ example that explains what is and how to use semantic Kernel.
You hear about that new GitHub Actions. Or maybe you didn't but would like to add a continuous integration, continuous deployment (CI-CD) to your web application. In this post, I will show you how to add a CI-CD to deploy automatically to Azure using the GitHub Actions.
What are GitHub Actions
GitHub Actions are automated workflows to do things. One of these could be a CI-CD. Using a workflow you could decide to compile and execute some unit tests at every push or pull request (PR). Another workflow could be that you deploy that application.
In this article, I will deploy a .Net Core application in Azure. However, you can use any languages you would like and deploy anywhere you like... I just needed to pick one :)
Now, let's get started.
Step 1 - The Code.
We need some code in a GitHub repo. Create a GitHub repo, clone it locally. And your app in it. I created mine with dotnet new blazorserver -n cloud5minsdemo -o src. Then commit and push.
Step 2 - Define the workflow
We got the code, now it's time to define our workflow. I will be providing all the code snippets required for the scenario cover in this post, but there is tons of template ready to be used available directly from your GitHub repository! Let's have a look. From your repository click on the Action tab, and voila!
When I wrote this post, a lot of available templates assumed the Azure resources already existed and you and adding a CI-CD to the mixt to automated your deployment. It's great but in my case, I was building a brand new web site so those didn't fit my needs. This is why I created my own template. The workflow I created was inspired by Azure/webapps-deploy. And there a lot of information also available on Deploy to App Service using GitHub Actions.
Let's add our template to our solution. GitHub will look in the folder .github/workflows/ from the root of the repository. Then create a file with the extension .yml
Here the code for my dotnet.yml, as any YAML file the secret is in the indentation as it is whitespace sensitive:
on: [push,pull_request]
env:
AZURE_WEBAPP_NAME: cloud5minsdemo # set this to your application's name
AZURE_GROUP_NAME: cloud5mins2
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# checkout the repo
- uses: actions/checkout@master
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.0.101
# dotnet build and publish
- name: Build with dotnet
run: dotnet build ./src --configuration Release
- name: dotnet publish
run: |
dotnet publish ./src -c Release -o myapp
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- run: |
az group create -n ${{ env.AZURE_GROUP_NAME }} -l eastus
az group deployment create -n ghaction -g ${{ env.AZURE_GROUP_NAME }} --template-file deployment/azuredepoy.json
# deploy web app using Azure credentials
- name: 'Azure webapp deploy'
uses: azure/webapps-deploy@v1
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
package: './myapp'
# Azure logout
- name: logout
run: |
az logout
The Agent
There is a lot in there let's start by the first line. The on: is to define the trigger, in this case, the workflow will be trigger at every push or PR.
The env: is where you can declare variables. It's totally optional, but I think it will help then templates are more complex or simply to reuse them easily.
Then comes the jobs: definition. In this case, we will use the latest version of Ubuntu as our build agent. Of course, in a production environment, you should be more specify and select the OS that matches your needs. This job will have multiples steps defined in the, you guess it, steps: section/
We specify a branch to work with and set up our agent by:
And it would be a better idea to set the version as an environment variable to be able to change it quickly.
The next two instructions are really .Net Core focus as they will build and package the application into a folder myapp. Of course, in the "section" you could execute some unit test or any other validation that you may find useful.
To have our GitHub Action to be able to create resources and deploy the code it needs to have access. The azure/login@v1 will let the Action login, using a Service Principal. In other words, we will create an authentication in the Azure Active Directory, with enough permission to do what we need.
This will create a Service Principal named "c5m-Frankdemo" with the role "contributor" on the subscription specified. The role contributor can do mostly anything except granting permission.
Because no resources already existed the GitHub Action will require more permission. If you create the Resource Group outside of the CI-CD, you could limit the access only to this specific resource group. Using this command instead:
The Azure CLI command will return a JSON. We will copy-paste this JSON into a GitHub secret. GitHub secrets encrypted secrets and allow you to store sensitive information, such as access tokens, in your repository. To access them go in the Settings of the repository and select Secrets from the left menu.
Click the Add a new secret button, and type AZURE_CREDENTIALS as the name. It could be anything, as long as you use that value in the YAML file describing the workflow. Put the JSON including the curly brackets in the Value textbox and click the save button.
Provisioning the Azure Resources
Now that the workflow has access we could execute some Azure CLI commands, but let's see what missing:
- run: |
az group create -n ${{ env.AZURE_GROUP_NAME }} -l eastus
az group deployment create -n ghaction -g ${{ env.AZURE_GROUP_NAME }} --template-file deployment/azuredepoy.json --parameters myWebAppName=${{ env.AZURE_WEBAPP_NAME }}
The first command will create an Azure Resource Group, where all the resources will be created. The second one will deploy the website using an Azure Resource Manager (ARM) template. The --template-file deployment/azuredepoy.json tells us the template is a file named azuredeploy.json located in the folder deployment. Notice that the application name is passed to a parameter myWebAppName, using the environment variable.
An ARM template is simply a flat file that a lot like a JSON document. Use can use any text editor, I like doing mine with Visual Studio Code and two extensions: Azure Resource Manager Snippets, and Azure Resource Manager (ARM) Tools With those tools I can build ARM template very efficiently. For this template, we need a service plane and a web App. Here what the template looks like.
This template is simple, it only contains the two required resources: a service plan, and a web app. To learn more about the ARM Template you can read my other post or check out this excellent introduction in the documentation.
Once the template is created and saved in its folder.
The deployment
There are only two last steps to the YAML file: the deployment and logout. Let's have a quick look at the deployment.
Now that we are sure the resources exist in Azure we can deploy the code. This will be done with azure/webapps-deploy@v1 that will take the package generated by dotnet into myapp. Since we are already authenticated there is no need to specify anything at this point.
Everything is ready for the deployment. You just need to commit and push (into master) and the GitHub Action will be triggered. You can follow the deployment by going into the Actions tab.
After a few minutes, the website should be available in Azure. This post only shows a very simple build and deployment, but you can do so many things with those GitHub Actions, like executing tasks or packaging a container... I would love to know how you use them. Leave a comment or reach out on social media.
Moving your ASP.NET applications to the Microsoft Cloud (Premier Developer) - If you are thinking to migrate to the cloud, it's important to plan your migration. This post is the perfect point to get started, it contains references to deeper books and documents.
The Rise of Microsoft Visual Studio Code (Lyn Levenick) - Cool statistics about editor usage. Not sure of the real correlation with the editor used and the skill level, but it's still an interesting coincidence.
Stream Deck Tricks for Streamers… and Muggles too! (Jeff) - Fantastic post that explains so much why that little thing can save you so much pain. As THE day when I'm starting to stream get closer and closer... This is gold.
I'm about to start a new project and want to have it with a continuous integration (CI) and continuous deployment (CD). I've been using VSTS for a while now but didn't have the chance to try the new pipelines. If you didn't know VSTS as been rebranded/ redefined as Azure Devops. Before going in with the real thing I decided to give it a try with a simple project. This post is to relay those first steps.
Get Started
Let's start by creating our Azure Devops project. Navigate to Dev.Azure.com and if you don't already have an account create one it's free! Once you are logged-in, create a new project by clicking the New project blue button in the top right corner.
You will need to provide a unique name and a few simple information.
The Application
First thing first, we need an application. For this post, I will be using a simple Asp.Net Core site. For the repository, we have options. AzureDevOps (ADOps) support many repository: GitHub, Bitbucket, private Git and its own. Because the project I've created is public I decided to keep the code at the same place as everything else.
From the left menu, select Repos. From here if the code already exist just add a remote repository, or clone the empty one on your local machine, the usual. Create and add your code to that repository.
The Azure WebApp
The next step is to create a placeholder for our CD pipeline. We will create an empty shell of a web application in Azure with these three Azure CLI commands. You can execute them locally or from the Cloud Shell. (Don't forget to validate that you are in the good subscription)
az group create --name simplegroup --location eastus
az appservice plan create --name simpleplan --resource-group simplegroup --sku FREE
az webapp create --name simplefrankweb --resource-group simplegroup --plan simpleplan
The first command will create a Resource group. Then inside of this group we create a service plan, and finally we create a webapp to the mix.
Continuous Integration
The goal is to have the code to get to compile at every commit. From the left menubar, select Pipelines, and click the create new button. The first step is to identify where our code is, as you can see Azure DevOps is flexible and accept code from outside.
Select the exact repository.
This third step displays the YAML code that defines your pipeline. At this point, the file is not complete, but it's enough to build, we will come back to it later. Click the Add button to add the azure-pipelines.yml file at the root level of your repository.
The build pipeline is ready click the Run button to execute it for the first time. Now at every commit, the build will be triggered. To see the status of your build just on to into the build section from the left menubar.
Continuous Deployment
Great, our code gets to compile at every commit. It would be nice if the code could also be automatically deployed into our dev environment. To achieve that we need to create a Release Pipeline. And our pipeline will need artifacts. We will edit the azure-pipelines.yml to add two new tasks. You can do this directly in the online repository or just from your local machine; remember the file is at the root. Add these commands:
Those two tasks are to publish our application (package it), and make it available in our Artifact folder. To learn more about the type of command available and see example have a look the excellent documentation at: https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core. Once you are done, save and commit (and push if it was local).
From the left menubar, click on e the Pipeles, select Release, and clienk the New Release blue button. Select the template that matches your application. For this post Azure App Service deployment is the one we need.
The next thing to will be to rename the environment for something else than Stage 1, I named mine "to Azure" but it could be dev, prod or anything that make sense for you. Click on the Add an Artifact button.
You will now specify to the pipeline were to pick the artifacts it will deploy. In this case, we want the "output" of our latest build. And I renamed the Source alias as Drop.
To get our continuous deployment (CD) we need to enable that trigger by clicking on the little lightning bolt and enabled it.
The last step to configure the Release pipeline is to specify a destination. By clicking on the "1 job, 1 task" in the middle of the screen (with the little red exclamation point in a circle), that will open the window where we will do that.
Select the subscription you would like to use, and then click on the Authaurize button on the right. Once it's done go change the App Service Name. Click on it and wait 2-3 seconds you should see the app we created with our Azure CLI display. Select it, and voila!
Now add a ReadMe.md file by checking out the code on your local machine or directly in Azure DevOps. Grab a badge from the build and/or release and copy paste it in the ReadMe. To get the code snippet of your badge, go to your build/ release definition, and click the ellipse button. Select Status badge and copy the snippet that matches your destination file (in our case the Markdown).
Now when you go to the Overview page, you will have a nice badge that informed you. It also works on any web page just use the HTML snippet instead.
Introduction to Azure Durable Functions (Maxime Rouiller) - This is a great post that explains what are durable functions and shows a simple case to gives context.
The Five Dysfunctions of a Team: A Leadership Fable (Patrick Lencioni) - I really enjoyed this book. The fact the first the material was passed as a story adds a lot of perspective and to our comprehension. In the last chapter the author return to the theories and gives more details. I completely devour that book; I'm looking forward to reading more.
Miscellaneous
paddling.com (Wayne Horodowich) - I could not agree more.
1575 Coding on Twitch with Jeff Fritz (Carl Franklin, Richard Campbell, Jeff Fritz) - Yep developers are also on twitch and they rock. We learn how it all started in this episode.
Azure functions are great. I used to do a lot of "csx" version (C# scripted version) but more recently I switched to the compile version, and I definitely loved it! However, I was looking for a way to keep my deployment short and sweet, because sometimes I don't have time to setup a "big" CI/CD or simply because sometimes I'm not the one doing the deployment... In those cases, I need a simple script that will deploy everything! In this post, I will share with you how you can deploy everything with one easy script.
The Context
In this demo, I will deploy a simple C# (full .Net framework) Azure functions. I will create the Azure Function App and storage using an Azure Resource Manager (ARM template) and deploy with a method named Zip push or ZipDeploy. All the code, script, a template is available on my Github.
The Azure Functions Code
The Azure Function doesn't have to be special, and it can be any language supported by Azure Functions. Simply to show you everything, here the code of my function.
namespace AzFunctionZipDeploy
{
public static class Function1
{
[FunctionName("GetTopRunner")]
public static async Task Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
string top = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "top", true) == 0)
.Value;
if (top == null)
{
dynamic data = await req.Content.ReadAsAsync< object>();
top = data?.top;
}
return top == null
? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a number to get your top x runner on the query string or in the request body")
: req.CreateResponse(HttpStatusCode.OK, new { message = $"Hello, here is your Top {top} runners", runners = A.ListOf(int.Parse(top)) });
}
}
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
}
It's a really simple function that will return a list of Person generated on the fly. The list will contain as many person as the number passed in parameter. I'm using the very useful GenFu library, from my buddies: ASP.NET Monsters.
The only thing we need to do is to create our compress file (Zip or Rar) that contains everything our project required.
In this case, it's the project file (AzFunction-ZipDeploy.csproj), the function's code (Function1.cs) the host (host.json) and local settings of our function (local.settings.json).
The ARM template
For this demo, we need one Azure Function App. I will use a template that is part of the Azure Quickstart Templates. A quick look to the azuredeploy.parameters.json file and we see that the only parameter we really need to set is the name of our application.
To be able to ZipDeploy, we need to add one Application Setting to let the Kudu interface we need its help to compile our code. To do that let's open the azuredeploy.json and go to the appSettings section. We need to add a new variable named: SCM_DO_BUILD_DURING_DEPLOYMENT and set it to true. After adding the setting it should look like this (see the last one... that's our new one):
Now that all the pieces are ready it's time to put it together one script. In fact, only the two last commands are required; everything else is just stuff to make it easier to re-use it. Check out my previous post 5 Simple Steps to Get a Clean ARM Template, to learn more about the best practices related to ARM template. So let's see that script, it's pretty simple.
# script to Create an Azure Gramophone-PoC Solution
resourceGroupName=$1
resourceGroupLocation=$2
templateFilePath="./arm/azuredeploy.json"
parameterFilePath="./arm/azuredeploy.parameters.json"
dateToken=`date '+%Y%m%d%H%M'`
deploymentName="FrankDemo"$dateToken
# az login
# You can select a specific subscription if you do not want to use the default
# az account set -s SUBSCRIPTION_ID
if !( $(az group exists -g $resourceGroupName) ) then
echo "---> Creating the Resourcegroup: " $resourceGroupName
az group create -g $resourceGroupName -l $resourceGroupLocation
else
echo "---> Resourcegroup:" $resourceGroupName "already exists."
fi
az group deployment create --name $deploymentName --resource-group $resourceGroupName --template-file $templateFilePath --parameters $parameterFilePath --verbose
echo "---> Deploying Function Code"
az functionapp deployment source config-zip -g $resourceGroupName -n zipdeploydemo --src "./zip/AzFunction-ZipDeploy.zip"
echo "---> done <--- code="">--->
The only "new" thing is the last command functionapp deployment source config-zip. That where we specify to the Azure Function App to look to --src to get our source. Because I'm running it locally, the path is pointing to a local folder. However, you could execute this command also in the CloudShell, and that would become a URI... to an Azure Blob Storage by example.
Deploy and Test
If you didn't notice yet, I did my script in bash and Azure CLI. That because I want my script to be compatible with all platforms. Of course, you could have done it in PowerShell or anything else that would call the REST API.
To deploy, just execute the script passing the ResourceGroup name, and its location.
./Deploy-AZ-Gramophone.sh cloud5mins eastus
To get to Function URL, go to the Azure portal (portal.azure.com) and click on the Function App that we just deploy. Click on the function GetTopRunner in this case, and click on the </> Getfunction URL button.
Use that URL in postman and pass another parameter top to see we the deployment ws successful.
In Video Please
If you prefer, I also have a video version of this post.
Azure Application Architecture Guide (Mike Wasson) - A free book (pdf only) with all the best of the AzureCAT team? You really don't want to miss that opportunity.
Understanding Azure Event Grid ( Jason Roberts) - Nice little post that introduces event grid, differentiate it from the service bus, and quickly go over the pricing.
It's had been a while since I worked into Visual Studio Team Services (VSTS), and it was a real pleasure to get back in that area. For the solution I was working on, we need to keep the current database up and running while deploying a new version. For this purpose, we decided to append the release number to database name (ex: MyDatabase363). In our Build and Release processes, we needed to identify which databases are from the last release. In this post, I will show what I did using an inline PowerShell script to get that number and set it as an environment variable so it can be accessible by other tasks.
To get started let's add a Azure PowerShell task to our build definition. In this post, I use a build process but of course this is also valid for release process. To find the task quickly, use the search text box. I will add two of those, one to get the number, the second to validate that this value is now set as an environment variable and readable from other tasks.
Now it's time to set the first task. Fill-out all the properties and select Inline Script as the Script Type. It should look like this.
Let's examine the code.
Get last Release Number
$matchingResources = Find-AzureRmResource -ResourceNameContains "mydatabase" -ResourceType "Microsoft.Sql/servers/databases"
$lastRelease = 0
ForEach($resource in $matchingResources)
{
if ($resource.ResourceName -match '(\d)+$') {
if($lastRelease -lt $matches[0]){
$lastRelease = $matches[0]
}
}
}
Write-Output "The last release number is: $lastRelease"
Write-Output ("##vso[task.setvariable variable=lastReleaseNumber;]$lastRelease")
On the first line, I use the Azure PowerShell commandlet Find-AzureRmResource1 to get an array of all the databases currently online in my resource group that contains a specific string. In this case, it's the name of the database without the release number. Then I will loop through all returned resources and using a very simple Regex to extract the release number and keep the biggest one (the last release).
To close that script we have two outputs. The first one is to give feedback in the logs, because it's always good to have some information there. The second one look more complicated, but if you split it, it's easier to see what's happening. In fact, we are producing a VSTS (previously called Visual Studio Online this is why it's VSO) command to initialize a variable ##vso[task.setvariable variable=lastReleaseNumber;] And of course, assign to it our last release number $lastRelease
To validate that we really successfully found our last release number and assigned it to a variable, let's try to read it back but from another step. That will be easily done this code in the other step created:
Validate the last Release Number
$number = $env:lastReleaseNumber
Write-Output "Confirmation, the last Release Number is: $number "
The only thing missing before we can run our test is to create that environment variable. To to it simply go in the Variables tab and add it there.
It's all set, run the build and you should see something similar in your logs.
Announcing the Coco Framework for enterprise blockchain networks (Mark Russinovich) - You probably eared the buzz word blockchain before, but still not sure what it is exactly… Here is a good post to get started and in the meantime, you will know also an open-source framework to work with.
Managing your resources with Azure Cloud Shell (Corey Sanders) - My first thought about Cloud Shell was: cute. And then I was in a situation where … well, it really helped me. So yeah, definitely something to look at, and this post is the perfect starting point.
5 Common Myths Around Moving to Docker (Megan Rees Ahigian ) - Nice post that answers some very frequent assumptions related to container and more particularly, Docker containers.
Web Scraping In Power BI And Excel Power Query (Gil Raviv) - Just recently I've learned about Power BI web scrapping capability, then this! I didn't think it could be that great! Great post.
What’s New in Visual Basic 2017 (The Visual Basic Team) - It's been a while since I coded in VB but reading this post brought back all those souvenirs... Great work.
Securing Web Applications - Simple Talk (Vishwas Parameshwarappa) - Security should be in our priority in this time of APIs and IoT.... Excellent post to get started with multiple security breaches and how to fix them.
Tuples In C# (Mahesh Chand) - Tuples are one feature introduced in .Net 4.0 that can simplify our life a lot. Learn how in this post.