Passed Microsoft Certified: Azure DevOps Engineer Expert (AZ-400)

Today I have finished my Azure certification path by successfully passing the AZ-400: Microsoft Azure DevOps Solutions exam. This exam measures your ability to accomplish the following technical tasks: design a DevOps strategy, implement DevOps development processes, implement continuous integration, continuous delivery, dependency management, application infrastructure, and continuous feedback.

The exam consists of 2 case studies, 12 lab tasks, 42 test questions that must be answered in 180 minutes. I had two lab tasks that couldn’t be finished because of Azure environment issues (exam’s account didn’t have required permissions on Azure resources to complete certain sub-tasks). Fortunately, I was pretty sure for overall result and, after speaking with proctor, decided to jump into the next exam’s sections.

How to prepare

  1. You must either earn the Azure Administrator Associate or Azure Developer Associate certification
  2. You must have an active Azure DevOps account. The Azure Pipelines and Azure Repos are needed at least.
  3. Check out the free Azure/DevOps training courses (AZ-400 OpenEDX that’s based on MCT training guides and AzureDevOps Labs). In addition, there are a lot of videos at Pluralsight for getting started with Azure DevOps and understand DevOps principles.
  4. The labs are all about Azure Services (IaaS/PaaS/IaC), so you must know how to prepare environments for CD, environment types and differences between them, make IaC, understand security options for each Azure resource, CI/CD. Also, I was pretty surprised to see the lab tasks to be completed on localhost file system before pushing the code to Azure.
  5. The certification will be valid only for 2 years, so keep learning and practice every day! I wish you good luck on the exam and may the force be with you.

Azure Policy: Append multiple tags

Howdy, here is an example of the custom Azure Policy that is based on Append policy action that automatically adds additional fields to the requested resource during creation or update. A common example is adding tags on resources such as costCenter or specifying allowed IPs for a storage resource. This policy appends specified tags and values on resources, so you can easily group them in order to get their consumption and costs, for example. Although the policy has default tags name and values, you can provide your own during the policy assignment.

TIP: Different versions of json files for PowerShell and deploying policy with Portal are available in my Github repo

This sample is for deploying policy with Azure Portal:

{
    "mode": "Indexed",
    "parameters": {
        "tagName1": {
            "type": "String",
            "metadata": {
                "displayName": "Tag Name1",
                "description": "Name of the tag, such as 'environment'"
            },
            "defaultValue": "environment"
        },
        "tagValue1": {
            "type": "String",
            "metadata": {
                "displayName": "Tag Name1 Value",
                "description": "Value of the tag, such as 'production'"
            },
            "defaultValue": "production"
        },
        "tagName2": {
            "type": "String",
            "metadata": {
                "displayName": "Tag Name2",
                "description": "Name of the tag, such as 'service'"
            },
            "defaultValue": "service"
        },
        "tagValue2": {
            "type": "String",
            "metadata": {
                "displayName": "TagName2 Value",
                "description": "Value of the tag, such as 'webapps'"
            },
            "defaultValue": "webapps"
        },
        "tagName3": {
            "type": "String",
            "metadata": {
                "displayName": "Tag Name3",
                "description": "Name of the tag, such as 'project'"
            },
            "defaultValue": "project"
        },
        "tagValue3": {
            "type": "String",
            "metadata": {
                "displayName": "Tag Name3 Value",
                "description": "Value of the tag, such as 'POC'"
            },
            "defaultValue": "POC"
        }
    },
    "policyRule": {
        "if": {
            "allOf": [
                {
                    "field": "[concat('tags[', parameters('tagName1'), ']')]",
                    "exists": "false"
                },
                {
                    "field": "[concat('tags[', parameters('tagName2'), ']')]",
                    "exists": "false"
                },
                {
                    "field": "[concat('tags[', parameters('tagName3'), ']')]",
                    "exists": "false"
                }
            ]
        },
        "then": {
            "effect": "append",
            "details": [
                {
                    "field": "[concat('tags[', parameters('tagName1'), ']')]",
                    "value": "[parameters('tagValue1')]"
                },
                {
                    "field": "[concat('tags[', parameters('tagName2'), ']')]",
                    "value": "[parameters('tagValue2')]"
                },
                {
                    "field": "[concat('tags[', parameters('tagName3'), ']')]",
                    "value": "[parameters('tagValue3')]"
                }
            ]
        }
    }
}

To assign the policy by using PowerShell:

# Create the Policy Definition (Subscription scope)
$policyrules = "https://raw.githubusercontent.com/rlevchenko/stuff/master/Azure/Policy/PS/appendtags-rules.json"
$policyparams = "https://raw.githubusercontent.com/rlevchenko/stuff/master/Azure/Policy/PS/appendtags-parameters.json"
$definition = New-AzPolicyDefinition -Name 'Append Multiple Tags' -Policy $policyrules  -Parameter $policyparams -Mode Indexed

# Set the scope to a resource group; may also be a resource, subscription, or management group
$scope = Get-AzResourceGroup -Name 'mvphero'

# Create the Policy Assignment
New-AzPolicyAssignment -Name 'Apply multiple tags' -DisplayName 'Apply tags and their default values' -Scope $scope.ResourceId -PolicyDefinition $definition

And this is how it looks from Azure Portal during the policy assignment:

The tags added by policy on NSG resource: