Posted on Leave a comment

Inherit tags on Azure resources

Tags are metadata elements that you apply to your Azure resources. They’re key-value pairs that help you identify resources based on settings that are relevant to your organization. For example, If you want to track the deployment environment for your resources, add a key named Environment.

Tag names are case-insensitive for operations. A tag with a tag name, regardless of the casing, is updated or retrieved.

Although tags are very useful for categorization and help quickly identify the resource existence, many forget to use them and resources remain untagged. For this reason one can apply an inherit policy for resources so that tags automatically filled. For example you can append a tag on your subscription and create a policy to inherit this tag on resource groups if it is not added during the creation. Additionally you can create a policy to inherit tags on resources from resource groups. The second scenario will be examined below.

First you should need to create a new policy under Azure policy

You can press on an existing policy and create a duplication definition

Then you should select the Definition location that will be your subscription and then you should edit the Policy Rule. You can leave the policy as it is and change only the displayName of the tag. This policy will inherit the Team tag from the resource group on resources.

{
  "mode": "Indexed",
  "policyRule": {
    "if": {
      "allOf": [
        {
          "field": "[concat('tags[', parameters('tagName'), ']')]",
          "notEquals": "[resourceGroup().tags[parameters('tagName')]]"
        },
        {
          "value": "[resourceGroup().tags[parameters('tagName')]]",
          "notEquals": ""
        }
      ]
    },
    "then": {
      "effect": "modify",
      "details": {
        "roleDefinitionIds": [
          "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
        ],
        "operations": [
          {
            "operation": "addOrReplace",
            "field": "[concat('tags[', parameters('tagName'), ']')]",
            "value": "[resourceGroup().tags[parameters('tagName')]]"
          }
        ]
      }
    }
  },
  "parameters": {
    "tagName": {
      "type": "String",
      "metadata": {
        "displayName": "Team",
        "description": "example: DevOps"
      }
    }
  }
}

You can read more about Azure policies in the below documentation link.

https://learn.microsoft.com/en-us/azure/governance/policy/samples/

Then you should save the policy and go on assignments to assign it on a particular resource.

In the policy assignment you can exclude components that will override the policy. Additionally you can specify a resource group instead of the whole subscription.

The important part would be to provide the Tag Name. This would be the parameter on which you will perform the actions. As we specified that we want the Team tag to be inherited then we will give this as an input.

When you apply tags on resources, you add some metadata on them as a result you will need to have contributor role. When we specify this action automatically, we will need a service principal that will do the job. We can select one automatically using managed identity from the remediation tab of the policy creation.

Finally we can create our assignment and try what we created. I have a test resource group with the tag Team inside my subscription.

When I need to create a new resource under the resource group, this should automatically inherit the tag Team. In order to test I will create a Log Analytics workspace without Tags on the resource group.

we can notice that after the creation this resource will have the tag Team automatically filled.

Posted on Leave a comment

Automatic rollback procedure for Azure DevOps

Azure devops pipelines provide a variety of tools for automated procedures. One mechanism that administrators can build using the YAML structure is an automated rollback mechanism during a deployment.

This means that after a deployment you can revert the previous state using your YAML tasks without having to redeploy. Another case would be a broken deployment which can be identified by monitoring tools and then a validation could approve or not the final release. This is exactly depicted in the below image. After releasing a version we have a validation step that requires manual approval from an administrator. If the validation is approved the release will proceed else the rollback will be triggered.

This mechanism is described below with YAML. Release stage includes release, validation and rollback jobs. Release job performs the actual release. Validation will depend on release job and will continue only if is approved. The rollback job will run only if validation failed which means that an administrator canceled the approval.

trigger: none
pr: none

stages:

- stage: releaseStage
  jobs:

  - deployment: release
    displayName: Release
    environment:
      name: dev
      resourceType: VirtualMachine
    strategy:
      runOnce:
        deploy:
          steps:
            - task: PowerShell@2
              displayName: hostname
              inputs:
                targetType: 'inline'
                script: |
                    deployment script here...
  
  - job: validation
    dependsOn: release
    pool: server
    steps:
    - task: ManualValidation@0
      inputs:
        notifyUsers: 'admin@domain.com'
        instructions: 'continue?'
        onTimeout: reject

  - deployment: rollback
    displayName: rollback
    dependsOn: validation
    condition: failed()
    environment:
      name: dev
      resourceType: VirtualMachine
    strategy:
      runOnce:
        deploy:
          steps:
            - task: PowerShell@2
              displayName: rolling back
              inputs:
                targetType: 'inline'
                script: |
                    rollback script here..
                    Write-Host "rollback"

When the release can be verified from the administrator the rollback will be skipped. This is the case when the validation is approved from the user.

Validation task will ask the user for a review.

On the other hand if validation is rejected the rollback stage will run.

Posted on 2 Comments

Run jobs with containers on Azure batch service

Azure Batch can be a great tool for instant batch processing as it creates and manages a pool of compute nodes (virtual machines), installs the applications you want to run, and schedules jobs to run on the nodes. Sometimes however a container could be a more appropriate solution for simplicity and scaling than a virtual machine. In this guide I will explain how you could use containers for batch service in order to run jobs and tasks.

Use the Azure Compute Gallery to create a custom image pool – Azure Batch | Microsoft Learn

First things first, you will need to have a azure container registry or another public or private registry to store your container image. I have already created mine and pushed my batchcontainer image inside which is a .NET micro service that returns a hello world message as an output.

using System;

namespace samplebatch
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"Hello {args[0]}");
        }
    }
}

https://github.com/geralexgr/samplebatch

The next step would be to create your batch service account. The part on which you set your container as the workload is when you create a pool. Pools consist of the compute node that will execute your jobs and there you will add a new pool which will host containers from the image that you pushed earlier.

On the node selection you will have to select Marketplace on the Image type and specifically microsoft-azure-batch and ubuntu-server-container of 20-04-lts version. Then you will need to select Custom on the container configuration and add your container registry by pressing the hyperlink.

selection of custom container image on the batch service

Then you will need to input the username and password for the container registry as well as the registry URL.

When you have your pool ready you can go and create your job. You can leave the default settings on the job creation but you should specify the pool where the job will run.

Then you can create a task or multiple tasks for your job and provide the commands or inputs for them. In my case I created a task named kati with the command of my name. This will be provided as input in my container which is a .NET microservice that prints a hello world message based on the input.

The important thing to do is to fill the image name from your repository. You can also provide container run options that you want for this node to have like mount of directories etc.

Example: repo.azurecr.io/batchservice:latest

As a result the output would be Hello gerasimos

The output of the run can be found on the stdout.txt file which is located on the task pane. You can also find a stderr.txt file which will log errors/failures that could appear during the execution.

Lastly, you can locate your job execution by navigating in the nodes where you can find a history of your tasks. As you can see I have two successful task executions and non failed.

YouTube video: