- Simon Waight
I was recently at an event where I had a discussion with someone who mentioned they'd missed the news about the retirement of a feature in Azure that they were making use of in a solution. As a result, they continued to build against the feature until they were forced to make a change when the service simply stopped responding.
While Microsoft publishes retirement notifications, tracking platform changes is a new operational muscle for many teams building on platforms like Azure. Now that Azure has been running for over a decade, there are regular retirement announcements which tend to be at the service feature level, such as stopping support for a version of Node.js, rather than entire services being retired.
If you're new to how service lifecycle works have a read of the standard lifecycle FAQ that also links to the Azure Updates blog which we'll get to in a moment.
Now we have some understanding of the background, let's look at how can we use Azure's services to improve the lives of these folks? Let's dig in!
As an Azure Service User I want to receive Service Retirement Updates via email so that I am aware they are happening and can plan accordingly.
Where is the data?
The Azure Updates website is where our data resides.
The Updates website also links to an RSS feed which, thankfully, honours the same content filters as the website. In our use case we want only announcements of retirements. On the website we can set the filter and then hit Filter Results and end up on a page with this address:
I can open the RSS feed and manually add the same query string so I end up with:
So that's our data source sorted out then.
Stitching together our alerting solution
There are a few ways I can alert my operations team about retirements - via Teams, Slack or other service, but for this post I am going to send a simple HTML-formatted email.
For my orchestration code I could go low / no-code and use Azure Logic Apps, but for this post I am going to build a Java-based Azure Function that uses a Timer trigger. My choice is again driven by an interest in coding up this solution in this way!
Before we go further let's drop a quick diagram in to help visualise the overall solution.
The key components of our solution are:
- Azure Function: written using Java 11 this Function uses a Timer trigger to periodically call the Azure Updates RSS feed and parse the XML for new Retirements.
- Azure Table Storage: so we don't re-send all Retirements each time we simply track the most recent announcement sent using Azure Table Storage.
- Azure Email Communication Service: allows us to easily send the updates information to a recipient (or multiple) by creating some HTML and calling an API.
Rather than reproduce a bunch of Java code here, I'll simply direct you to the solution on GitHub. If you have access to Codespaces, or can use Dev Containers in VS Code, you can fork the repository and have a play.
I love that in just over 200 lines of Java I can create a really handy service which I can run for an extremely low cost (more on this in a minute). I'd also say it could likely be less Java, but it's been a while since I've coded much in Java so I've probably not written the most efficient code (feel free to let me know! 😉)
There are three components of value in this case.
- Azure Functions (pricing): I am running on a Linux Consumption Plan and (with my sample) am running only once per week. I will sit well withing the Azure Functions monthly free grant.
- Azure Table Storage (pricing): I have one Account to support the Azure Function (logs, etc) as well as hold my single Azure Storage Table (with one Entity). Given how little Table Storage data I have, and how infreqent I call it, I will generate neglible cost. Note that I will still incur storage changes for my Azure Functions storage (logs, etc), but that is unlikely to be a big charge either.
- Email Communication Service (pricing): the public pricing is 0.00012/MB data (USD). Given I'm only sending a single email a week, and that is is only a few kilobytes in size I'm not going to break the bank here!
I think if we'd delivered this implementation in a sprint our stakeholders would be happy. Given the relatively small implementation we could quickly add capabilities, potentially using the same Azure Function code to orchestrate sending message to multiple channels.
Hopefully you'll pick up a few techniques from this post and the associated implementation. I'm now running this service myself so I can be across retirement announcements, even if the eventual retirement is still several months or years away.
Here's a sample that lands in my inbox once a week.
Happy Days! 😎