This post was most recently updated on July 26th, 2024.
3 min read.Have you ever wondered how you could roll back the latest layered Azure IoT Edge deployment? I have – it’s actually pretty useful. But what for?
Well, perhaps it’s useful as the last step or whatever interesting Azure DevOps pipelines you have to deploy changes to an Edge device, run tests, and then remove the deployment. You could possibly have it as an optional parameter in case you want to do a dry run for the deployment – see if everything works well but not actually leave your stuff on the device. Or, perchance, it could be used as a separate pipeline that you can run when you notice that your malformed, and completely broken, manifest was deployed to an environment that then proceeded to not function quite as expected. And to be fair, the same Azure CLI commands that I’ve added into the AzureCLI task in my YAML below can simply be run in your terminal of choice to remove the deployment without involving Azure DevOps at all!
So many options! So much YAML!
Solution
Let’s get to it, then!
We built a simple template for rolling back the latest deployment for any single module. We especially wanted to figure out the latest deployment by creation time from all deployments deployed to a target environment (a JMESPATH query) and remove it from the IoT Hub.
So, long story short here’s the code, and a bit below you can find the solution as to what it is and how it works!
YAML for a rollback step template:
parameters:
- name: sub
type: string
displayName: Name of the subscription to use
- name: connection
type: string
displayName: Azure Subscription Service Connection to use
- name: iothub
type: string
displayName: Name of the IoT Hub to use for the deployment
- name: imageName
type: string
displayName: Image Name of the container that the module-to-be-deployed uses - this string is used to query for old deployments (to tell deployments for different modules apart from one another)
- name: target
type: string
displayName: Target Condition for your deployment
steps:
- task: AzureCLI@2
displayName: ${{ parameters.targetLocation }} (${{ parameters.targetEnvironment }}) - Roll back the latest Edge deployment using az CLI
inputs:
azureSubscription: ${{ parameters.connection }}
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az config set extension.use_dynamic_install=yes_without_prompt
az account set --subscription "${{ parameters.sub }}"
$latestDeploymentId = az iot edge deployment list -n ${{ parameters.iothub }} --query "reverse(sort_by([? targetCondition!=null && your-JMESPATH-Query-using-${{parameters.target }})], &createdTimeUtc))|[*]|[0]|[id][0]"
az iot edge deployment delete -n ${{ parameters.iothub }} -d $latestDeploymentId
addSpnToEnvironment: true
useGlobalConfig: true
And then you can use this template from your pipeline shown below:
- ${{ if eq(parameters.rollback, true) }}:
- stage: Rollback
dependsOn:
displayName: Roll back
jobs:
- job: RollbackDeployment
displayName: Roll back
pool:
vmImage: $(Your.Pool)
steps:
- template: ci/Tasks/Rollback.yml
parameters:
sub: $(Your.SubscriptionName)
connection: $(Your.ServiceConnectionId)
iothub: $(Your.IoTHubName)
imageName: $(Your.ImageName)
target: $(Your.TargetCondition)
But what kind of configuration do we need to make use of this template? Let’s see…
How to roll back your Azure IoT Edge deployments using an Azure DevOps YAML pipeline?
Time needed: 20 minutes
1. Create your pipeline
Creating the pipeline is your first step. It doesn’t really matter how and where you do that, but this guide presumes you’ll create the YAML file for the pipeline to the root of the project’
2. (OPTIONAL) Define a pipeline parameter for your rollback
You will now need a pipeline parameter for rollback – because we’ll want it to be optional (not every build needs to be a rollback after all!)
Add this at the top of your pipeline YAML:parameters:
- name: rollback
displayName: Roll back?
type: boolean
default: false
If you want to roll back after each deployment (after running tests, for example), simply ignore this step.
3. Add your rollback template file
We’ll be adding a new file for the rollback template (see the YAML above).
In my example, we have the pipeline YAML files in the root of the repository and all YAML templates in a folder structure like ci/{templatetype}/{templatename}.yml
So let’s add a new file to path ci/Tasks/Rollback.yml, and paste the content from the YAML above to it.
4. Add your rollback step
When you have the files (1 for your pipeline, one for your rollback template), you can add the step to your pipeline. If you want to have the step as optional (something you can select for each run of your pipeline), you can wrap it in:- ${{ if eq(parameters.rollback, true) }}:
Otherwise, it’ll just be something like this:- template: ci/Tasks/Rollback.yml
parameters:
sub: $(Your.SubscriptionName)
connection: $(Your.ServiceConnectionId)
iothub: $(Your.IoTHubName)
imageName: $(Your.ImageName)
target: $(Your.TargetCondition)
Et voilà ! Hopefully, it’s clear and helpful enough. Let me know in any case!
References
- How to fix Bitlocker failing to activate? - August 13, 2024
- Why You (unfortunately) need a Local Administrator account on Windows 🙃 - August 6, 2024
- 5 Years an MVP – a Humble Reflection - July 30, 2024