Never forget an EF Core migration anymore, rely on webapp HealthChecks

Guillaume Guerra
Jun 19 · 5 min read
Image for post
Image for post
Always listen to the cat

Sounds familiar ?

It’s Friday afternoon, you’ve accepted to handle your team’s weekly delivery. It has to be up by Monday and no one else is available.

Although you know you shouldn’t deliver on a Friday, you’re confident, you have released this app a million times, piece of cake :

  • Package delivered in Azure DevOps ✔️
  • Swagger is up, webapp has started ✔️
  • Yummy cookie eaten ✔️

Few hours later, production goes crazy, 500 errors everywhere, datacenter is on 🔥 🔥 🔥.

Too bad, you were having drinks with your friends, you’re running back home.

Ultimately, CSI (or AppInsights logs, it depends) will unveil the awful truth, you forgot to run an EntityFramework migration 💔

You hate yourself, you broke production, and most of all, you wasted a great Belgian 🍺.

Wait, can’t EF run required migrations on its own ?

Absolutely, EF can lookup for missing migrations and run them on the fly, during application startup.

However, MSDN advises you not to use this feature on production Database. Sometimes, a good old human supervised manual operation is better.

Oops, did I say manual operation ?

Quick words about webapps health checking

Image for post
Image for post

As part of .NET Core SDK, Microsoft has delivered an amazing healthcheck runtime.

Once it’s setup in your Startup class, your app will host a set of health check endpoints that you can query to assert its health.

Out of the box, it can help you ensure that all your usual dependencies are up and running, thanks to its extensible design and the hyper active .NET Core dev community :

It even comes with a very convenient self hosted website, HealthChecks.UI, to display the health check results :

Image for post
Image for post
You can even configure the top left icon, damn they’re good …

Leverage on this SDK to check EntityFramework migrations

We published on NuGet a custom health check that will ensure all migrations were executed, for a given Entity Framework Core DbContext.

It will work for any storage backend (AzureSQL, Oracle, CosmosDB SQL API, SQLite, etc), thanks to EF Core abstractions.

1- Follow this tutorial to setup the HealthCheck runtime in your webapp

2- Make sure you add Younited.HealthCheck.EntityFrameworkMigrations nuget to your project :

Image for post
Image for post

3- Register the EntityFrameworkMigrationsHealthCheck into the pipeline, using the extension method shown below. You will have to provide your custom DbContext :

That’s all folks ! 🎁 🎁 🎁

Now, querying the detailed health endpoint of your api will provide you with the list of migrations that could not be found on the DB, if any

HealthCheck.UI will also report the failure, obviously :

Image for post
Image for post

❗️ ❗️ ❗️ Note that this check is designed to stop searching for missing migrations once it confirmed they were all there. It’s meant to avoid paying for the lookup every time the health check is invoked. We assume that if all migrations were there at some point, they won’t be rolled back. Of course, after the next process startup, lookup will happen again until it confirms no migrations are missing. ❗️ ❗️ ❗️

However, in case you need to alter this behavior, feel free to publish a PR on our repo 😉

For a complete sample app, you can have a look at the project repo.

How to include healthchecks in your CD process

You surely don’t want to add a manual step in your delivery process, to query the health endpoint.

Instead, you can ask your delivery pipeline to query the detailed health endpoint right after the deployment, and make sure it returns a 200 status code.

All delivery systems have scripting tasks (python, powershell, etc.) that you can leverage on to perform this api call.

Combined with the warmup slot mechanism of Azure, you can define a production delivery workflow as follow :

  • Deliver on the production warmup slot
  • Query the health check endpoint, assert that it returns 200
  • Switch slots to finalize the deployment only if the healthcheck was a success

This way, in case the health check identifies a missing migration, or any other concern, you will have caught it before the actual delivery ✔️

Curious on how to write such custom health check ?

All code, including the sample app, is located on GitHub

First, you’ll have to create a class that implements IHealthCheck interface, from Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions nuget. As you can see, the interface is as simple as it can be :

In our case, the core of the implementation is how to look for the missing migrations. Lucky for us 🙏, there is a built-in method for this within EntityFramework Core packages, GetPendingMigrationsAsync :

Then, all we have to do is to call this lookup method only when the last check found missing migrations.

It’s not as straightforward as it could be, since the healthcheck instance is stateless. We have to register another service into the DI framework, as a singleton, to provide the healthcheck with persistent state capabilities.

Ultimately, the healthcheck implementation looks like this :

Thanks !

May the migrations be with you

YounitedTech

Le blog Tech de Younited, où l’on parle de développement…

Thanks to Arnaud TAMAILLON

Guillaume Guerra

Written by

YounitedTech

Le blog Tech de Younited, où l’on parle de développement, d’architecture, de microservices, de cloud, de data… Et de comment on s’organise pour faire tout ça. Ah, et on recrute aussi, on vous a dit ?

Guillaume Guerra

Written by

YounitedTech

Le blog Tech de Younited, où l’on parle de développement, d’architecture, de microservices, de cloud, de data… Et de comment on s’organise pour faire tout ça. Ah, et on recrute aussi, on vous a dit ?

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store