Build your own Azure retirements email alerts service using Java, Azure Functions and Communication Services

Published on
Reading time

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!

User Story

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?

If you took a look at the lifecycle FAQ (linked above) you will find it links to the Modern Lifecycle Policy which includes a link to the Azure Updates website.

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.

My reasons for this simply boil down to wanting to try the new Email Communication Service feature of Azure Communication Services. At time of writing this service was still in preview.

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.

Architecture diagram that shows all the components making up this 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! 😉)

Cost analysis

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.00025/emailand0.00025/email and 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!

Showcase outcome

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.

Screenshot of Outlook on iphone displaying the retirements email alert.

Happy Days! 😎