Ressourcen kannst du auf der Azure Plattform sehr einfach erstellen. Das ist grossartig, doch bietet auch ein paar gefahren. Beispielsweise kannst du nämlich Ressourcen oder ganze Umgebungen genau so einfach löschen. Was für Tests und Demos sehr hilfreich ist, kann bei Integrations- und Produktions- Umgebungen sehr gefährlich sein. Damit du dies nicht manuell zu verwalten brauchst, habe ich einen Azure Policy Code geschrieben. Dieser definiert das automatische Prüfen und Bereitstellen von Azure Resource Locks mit Azure Policies.
Falls du zuerst noch mehr über Azure Resource Lock und dessen Nutzen erfahren möchtest, empfehle ich dir das folgende Kurzvideo von mir (Ton an).
Schritt-für-Schritt – Automatisierung per Azure Policies
Da ich den Code auf meinem öffentlichen GitHub Repository bereits fertig zur Verfügung stelle, ist eine Automatisierung erdenklich einfach. Als erstes öffnest du als GitHub mit folgendem Link.
Wähle den Button «Deploy to Azure» und logge dich im Azure Portal mit dem gewünschten Account ein.
Ein Formular erscheint, in welchem du nur noch das gewünschte Abonnement aussuchen musst, auf welchem du die Policy Definition abspeichern möchtest. Die anderen Felder sind alle bereits mit einem Standardwert gespiesen. Unter anderem erstellst du auch eine neue Policy Kategorie namens «Governance», in welcher du die Definition dann platzierst. Falls du lieber einen anderen Namen oder eine bereits bestehende Kategorie verwenden willst, kannst du das einfach anpassen. Du kannst also alle Standardwerte ganz nach deinem Gusto verändern. Das Feld «Role Definition» muss allerdings mit «Owner» beibehalten werden. Klicke dann auf «Save».
Du hast die Policy erfolgreich erstellt und findest sie bei «Policy» unter «Definitions». Damit du sie schnell finden kannst, wähle bei «Type» einfach den Filter «Custom».
Klick die Policy an und wähle «Assign», um die erstellte Policy auch anzuwenden. Ein Formular erscheint wiederrum, welches du mit den Standardwerten bestehen lassen sollst. Wenn gewünscht, so kannst du allerdings eine Beschreibung hinzufügen. Wähle dann «Next», um zu den Parametern zu gelangen. Hier brauchst du eine Entscheidung zu treffen. Die Policy verhält sich nämlich so, dass sie per Standard auf allen Ressourcengruppen einen Lock erstellt. Ausgenommen sind nur Ressourcengruppen, die über einen gewissen «Tag-Value» verfügen. Du brauchst also hier zu definieren, in welchem Tag du für den Ausschluss nach welchem Wert suchen möchtest. Die Felder beinhalten bereits einen Standardwert als Vorschlag von mir, welchen du gerne übernehmen kannst.
- Ich arbeite absichtlich mit dem Ausschlussverfahren, um die Sicherheit zu erhöhen. Wäre es nämlich umgekehrt und das Setzen des Tags ginge bei einem Deployment vergessen, so wäre die Ressourcengruppe und die darin enthaltenen Ressourcen nicht geschützt.
- Stelle sicher, dass du bei den auszuschliessenden Ressourcengruppen das Tag zum Ausschluss bereits gesetzt hast, bevor du weiterfährst. Andernfalls brauchst du den Lock bei diesen wieder manuell zu entfernen.
Hast du dich für ein Tag und dessen Wert entschiede, wähle «Next», um weiterzufahren.
Jetzt gilt es einen «remediation task» zu erstellen. Dieser Task stellt sicher, dass die bestehenden Ressourcengruppen nicht nur geprüft werden, sondern auch automatisch ein Lock erstellt wird. Das ist daher mehr oder weniger der Kernpunkt des Ganzen. Für den «remediation task» erstellt Azure eine «managed identity», welche als «Owner» dann den Lock für dich jeweils automatisch erstellen kann. Setze also den Haken bei «Create a remediation task» und wähle dann die gewünschte Azure Region aus, in welcher du die «managed identity» erstellen lassen möchtest.
Wähle nun «Review + create» um die Policy basierend auf der Definition zu erstellen und zuzuweisen. Nun brauchst du etwas Geduld, bis die Policy die erste Prüfung durchgeführt und die notwendigen Locks automatisch erstellt hat. Den Status kannst du jeweils unter «Overview» der Policies abrufen.
Validieren – Automatisches Prüfen und Bereitstellen von Azure Resource Locks
Nach einer Weile sollte die erste Prüfung der Ressourcengruppen durch sein und diese durch den «remediation task» geschützt. Prüfe nun in den Eigenschaften der Ressourcengruppe, ob du den neuen Lock da wo gewünscht vorfinden kannst und die per Tag gefilterten Ressourcengruppen vom «remediation task» unberührt blieben.
Erwartetes Ergebnis der Ressourcengruppen (RGs):
- Bei bestehenden RGs OHNE Tag wurde ein Lock erstellt.
- Bestehende RGs MIT Tag wurden gefiltert und es wurde daher KEIN Lock erstellt.
- Neu erstellte RGs werden bei der Erstellung direkt von der Policy geprüft und
- …werden OHNE Tag ebenfalls mit einem Lock versehen.
- …werden MIT Tag gefiltert und es wird daher kein Lock erstellt.
Gratuliere! Du hast das Prüfen und Bereitstellen von Azure Resource Locks mit Azure Policies erfolgreich automatisiert!
Not working, im getting an error when I run the deploy to azure.
The policy effect ‹details› property could not be parsed using mode ‹All›.
Hello EFD
Thank you for your feedback, much appreciated. I just tested it myself again today, and it works perfectly fine for me on my test environment. Was it a temporary issue and it might work by now again? Have you checked?
Best,
Yannic
Thanks for this blog. I came across with a scenario where after applying this automatic policy, What if someone manually removed the resource lock. How we can ensure that even if someone is removing Azure policy should reapply again. Could you please help with that?
Hello.
Thanks for this very convenient policy.
So I got into «exclusion pitfall». Regularly I use Azure menu for exclusion AFTER applying policy.
By the way it doesn’t matter what kind of the policy I use. Here it is different behavior.
I cant exclude AFTER. Yes, I’ve read an warning, but I think I should be more elastic. Because cloud infrastructure is not static at all. Manual deletion maybe problematic. And this policy doesn’t make a force process. I mean – if someone with high permission deletes the Lock, it is gone until you MANUALLY create a Remediation Task. I’ve been searching for the automatic deployment for a long time and unsuccessfully. Maybe this strange behavior «by design» of Azure?
Good script! Don’t know why Microsoft doesn’t have this as a built-in script.
The policy works on subscription / resource group level. Is there a way to modify it so that it works on a resource level? e.g. if I want to exclude a lock being created on a disk/snapshot, but on every other resource in the resource group, I want it.
I put the exclusion tag and value (I put «True», not «true», does that make a difference?) but the policy assigned the delete lock.
Hello Randy and thank you for your comment.
You’re right, the policy is built for resource groups and will then inherit to all the resources within. In case you want to change that, you have to rewrite the policy rule part «policyRule». Instead of
«equals»: «Microsoft.Resources/subscriptions/resourceGroups»
you could also try to inlcude all resources and exclude resourceGroups instead. Or keep all included and rewrite the policy that it will only be applied to resources without the exclusion tag.
we currently deploy locks via runbooks but I’m looking at doing it via policy instead. Our standard is to call the locks we create for each RG
lck-resource group name
it looks like this in PS in the runbook
$lockcheck = Get-AzureRMResourceLock -ResourceGroupName $resourcegroup.ResourceGroupName
If ($lockcheck -eq $null)
{
New-AzureRMResourceLock -LockLevel CanNotDelete -LockName «lck-$($resourcegroup.ResourceGroupName)» -ResourceGroupName $resourcegroup.ResourceGroupName -force
how do we go about doing the same rather than just a generic Auto locked by policy, can you pass variables in to the «name» value?
«resources»: [
{
«name»: «Auto locked by policy»,
«type»: «Microsoft.Authorization/locks»,
«apiVersion»: «2017-04-01»,
«properties»: {
«level»: «CanNotDelete»,
«notes»: «This lock was deployed automatically by Azure Policy to prevent the resource group and its containing resources from accidental deletion.»
Hello Kerry
Thank you for your message. Yes, you can achieve that also with Azure Policy, if you use «Concat» for example.
In your example it would be something like….
"name": "[concat('lck-', parameters('resourceGroupName'))]",
Hope this does help you.
Thank you sir…
You are more than welcome!