Automatically convert deprecated APIs for Kubernetes 1.16

When Kubernetes 1.16 was released, several beta APIs were deprecated in favor of their stable counterparts. This means that your deployments will fail, if you’re still using the old APIs (as hundreds of public helm charts are!)

As release manager Lachlan Evenson mentioned in his Kubernetes Podcast interview, the intention of the deprecation was to “forcefully nudge” the community towards using the stable APIs, already available for 7 versions:

LACHLAN EVENSON: Let me start by saying that this is the first release that we've had a
big API deprecation, so the proof is going to be in the pudding.

CRAIG BOX: Yes.

LACHLAN EVENSON: And we do have an API deprecation policy. So as you mentioned, Craig, 
the Apps v1 has been around since 1.9. If you go and read the API deprecation policy, 
you can see that we have a three-release announcement. So around the 1.12, 1.13 time 
frame, we actually went and announced this deprecation, and over the last few releases,
we've been reiterating that.

But really, what we want to do is get the whole community on those stable APIs because it
really starts to become a problem when we're supporting all these many now-deprecated APIs,
and people are building tooling around them and trying to build reliable tooling. So this
is the first test for us to move people, and I'm sure it will break a lot of tools that
depend on things. But I think in the long run, once we get onto those stable APIs, people 
can actually guarantee that their tools work, and it's going to become easier in the long 
run.

So we've put quite a bit of work in announcing this. There was a blog sent out about six 
months ago by Valerie Lancey in the Kubernetes community which said, hey, go use 'kubectl
convert', where you can actually say, I want to convert this resource from this API version 
to that API version, and it actually makes that really easy. But I think there'll be some 
problems in the ecosystem, but we need to do this going forward, pruning out the old APIs 
and making sure that people are on the stable ones.

So what are you to do if you want to deploy a public helm chart, which has not yet been updated for the deprecated APIs?

You could fork, update, and publish your own helm repo. It’s do-able, but that’s a lot of work!

Eventually annoyed at the process, I wrote a little script to “transmogrify” Kubernetes manifests, replacing the deprecated APIs with the stable ones.

How does it work?

You simply point the script at your manifest directory, and it if finds any of the deprecated APIs, it’ll replace them inline with the stable versions.

Here’s an example:

root@cn1:~# /tmp/transmogrify_for_k8s_1.16.sh /tmp/ansible.bbGF94temp/prometheus/templates/
Deprecated API found in [/tmp/ansible.bbGF94temp/prometheus/templates/kube-state-metrics-deployment.yaml].. Transmogrifying...
Deprecated API found in [/tmp/ansible.bbGF94temp/prometheus/templates/alertmanager-deployment.yaml].. Transmogrifying...
Deprecated API found in [/tmp/ansible.bbGF94temp/prometheus/templates/node-exporter-daemonset.yaml].. Transmogrifying...
Deprecated API found in [/tmp/ansible.bbGF94temp/prometheus/templates/server-deployment.yaml].. Transmogrifying...
root@cn1:~#

Running the script a second time will result in no output, since there are no longer any deprecated APIs:

root@cn1:~# /tmp/transmogrify_for_k8s_1.16.sh /tmp/ansible.bbGF94temp/prometheus/templates/
root@cn1:~#

Here be dragons ?

I’ve made a lot of assumptions here - for one thing, the script assumes that each Kubernetes element is in its own YAML file. Weird things might happen if you point the script at a .yaml file combining multiple elements.