Skip to main content

Application Security Groups in Microsoft Azure

· 5 min read

Azure Application Security Groups (ASG) allow you to define what workloads (Virtual Machines) you are running in Azure has access to what resource - without being tied by managing complex IP address rules inside a Network Security Group.

Application security groups enable you to configure network security as a natural extension of an application's structure, allowing you to group virtual machines and define network security policies based on those groups. You can reuse your security policy at scale without manual maintenance of explicit IP addresses.

These Azure Application Security groups allow you to define your workloads, for example, Azure Virtual Desktop Session Hosts as a 'group' and what they may have access to in your Azure Virtual Network without opening up the service to everything inside of that VNET or creating overly complex rules that could make it hard to troubleshoot.

There are a few things to be mindful of:

  • Azure Application Security Groups are Virtual Network-specific, so they can work to allow resources across subnets, but not in separate Virtual Networks, even if they have peered.
  • As with most Azure resources, there are Subscription levellimits; you cannot have more than 3,000 Azure Application Security groups in a single subscription and region.
  • The rules that specify an application security group as the source or destination are only applied to the network interfaces that are members of the application security group; this does not affect anything not in this group, even though your Network Security Group is based on the subnet.
  • You can assign more than one Application Security group to a resource

In my example, I have a single virtual network, with 2 subnets (one subnet, has an Azure Virtual Desktop session host and the other one has a webserver running IIS), using Azure Application Security Groups, we will restrict IIS access to the webserver from the Azure Virtual Session hosts only - so IIS won't be accessible from any other machine in the Virtual Network.

High Level  - Diagram ASG

Create Application Security Group

Let's get started by creating an Application Security Group.

  1. Open the Azure Portal
  2. Click on + Create a resource
  3. Search for: Application security group and select it
  4. Click Create
  5. Select the subscription that the Application Security group will be created in
  6. Select the Resource Group (in my example, I am selecting AVD)
  7. Create an Application Security Group
  8. Click Review + create
  9. Click Create

Assign Application Security Group

Now that the Application Security group has been created it's time to assign it this our Azure Virtual Desktop session hosts.

  1. Open the Azure Portal
  2. Navigate to your Azure Virtual Desktop session host (or other workloads you are going to use)
  3. Select Networking
  4. Select Application security groups
  5. Click Configure the application security groups
  6. Select the Application Security group created earlier
  7. Assign Application Security Group
  8. Click Save

Assign Block Rule Security Group

Now it's time to assign a block rule to our web server, for port 80 as by default it is allowed through the 'AllowVnetInBound' default rule.

  1. Navigate to the Network Security Group that holds your web server (I am going to make the change on a Network Security group that is tied to the Network Interface of the web server, but the same principle applies if it was applied to a Network Security Group on the subnet - you just need to add the destination IP of the webserver)
  2. Click on Inbound security rules
  3. Click + Add
  4. Add a Deny port rule for port 80 for all source
  5. Assign Block Network Security Group Rule
  6. Click Save

After a few minutes, traffic from any workloads on the virtual network will now be blocked from accessing the web server on port 80.

Port 80 blocked

Create Allow rule using Application Security Group

Just a note around the priorities of Network Security Group rules:

Rules are processed in priority order (using a number between 100 and 4096), with lower numbers processed before higher numbers, because lower numbers have higher priority. Once traffic matches a rule, processing stops.

As a result, any rules that exist with lower priorities (higher numbers) that have the same attributes as rules with higher priorities are not processed.

  1. Navigate to the Network Security Group that holds your web server (I am going to make the change on a Network Security group that is tied to the Network Interface of the web server, but the same principle applies if it was applied to a Network Security Group on the subnet - you just need to add the destination IP of the webserver)
  2. Click on Inbound security rules
  3. Click + Add
  4. For Source, select the Application Security Group
  5. Select HTTP as the service
  6. Select Allow as the action
  7. Set the Priority to be lower than the block rule, ie 4095
  8. Click Save
  9. Create Network Security Rule Allow

After a few minutes, traffic from any workloads on the virtual network will now be allowed for any workloads from your Azure Virtual Desktop farm only (assigned to the Application Security group).

AVD - Test Port 80 Allow

If I attempted to access the webserver from my application server, it fails:

AVD - Test Port 80 Deny

Hopefully, this helps you avoid overly complex security rules that are reliant on knowing and managing the IP of your workloads and help secure your networks.

AWESOME-Azure-Architecture List

· One min read

A very brief Blog article today, I have created an AWESOME-Azure-Architecture list, this list is hosted in Github and located here:

This list is a curated list of AWESOME blogs, videos, tutorials, code, tools & scripts, related to the design and implementation of solutions in Microsoft Azure.

This list contains anything that can help with your Microsoft Azure architecture and quickly get you up and running when designing, planning, and implementing services that empower organisations around the planet to achieve more.

Create Azure Point to Site VPN using Microsoft Entra ID authentication

· 9 min read

You may be working remotely or only have a few devices needing access to your resources in Azure; a solution that can be deployed is a point to site connection straight into your Microsoft Azure network.

This functionality allows your computer to connect privately to resources over a secure tunnel using your internet connection, using an Azure Virtual Network gateway, you can seamlessly connect to resources without the need of opening up your resources to the internet or having to whitelist your (or third party vendor) IP address, which may change daily.

You know only your specified users access your Azure resources using Microsoft Entra ID.

You can have a site to site and point to site VPN running on the same Gateway today. We will set up a Point to Site VPN using Windows 11.

Azure Point to Site

Depending on the SKU of your Virtual Network Gateway, depends on the number of concurrent connections and throughput you are allowed; because we are using Microsoft Entra ID and the OpenVPN protocol, I will be selecting Generation 1, VpnGw1, supporting a max of 250 connections (you can double the number of throughput and connections if you are running in Active/Active and have a second gateway, or select a higher SKU).

Azure AD authentication is supported for OpenVPN® protocol connections only and requires the Azure VPN client.

A note about Gateway SKUs (apart from Basic) you can resize in the same generation (i.e. Generation 1 VpnGw1 to VpnGw3, but you can't go from Generation 1 VpnGw1 to Generation 2 VpnGw5, in order to upgrade, you have to delete and recreate the Gateway, just keep this in mind when deciding on the SKU of your resources).

You can read more about the Virtual Network Gateways and VPN SKUs at the official Microsoft documentation here; your Gateway SKU may differ depending on your requirements.

Create Azure Point to Site VPN using Microsoft Entra ID authentication

Prerequisites

  • An Azure subscription (that you have at least contributor rights to and the ability to create Users and Groups)
  • An endpoint device running Windows 10 or 11 that you can install the Azure VPN client onto

Create Virtual Network

First things first, let's create a Virtual Network.

  1. Log in to the Azure Portal
  2. Click on + Create a resource
  3. Search for: Virtual Network and click on it
  4. Click Create
  5. Select or create your Resource Group that you want your network resource to sit in (I recommend Virtual Network and the gateway resources sit in its own Resource Group away from other resources so that they can be protected by resource locks, RBAC and they are usually classified as a shared resource).
  6. Azure Virtual Network
  7. Click Next: IP Addresses
  8. Now we need to define the Address space and subnets; I will leave the Address space as 10.0.0.0/16 but remove the Default subnet (select the checkbox next to the Subnet and select Delete)
  9. Click +Add Subnet, and add a new subnet with the name of GatewaySubnet with an IP range of: 10.0.1.0/27 (this Subnet will be used by our Virtual Network Gateway, and the name needs to be exactly GatewaySubnet).
  10. Now I will add a subnet named: app servers, for the Virtual Machines I will need to connect to will be placed.
  11. Azure Virtual Network
  12. Click Next: Security
  13. Leave everything (BastionHost, DDoS Protection Standard, Firewall) as Disabled.
  14. Click Next: Tags
  15. Enter in any tags and click Review + Create
  16. Review your configuration and click Create

Create Virtual Network Gateway

Now that we have the foundation of our setup - an Azure Virtual Network, it is time to provision the Gateway itself; just a note before we continue, the Gateway can take 30-60 minutes to provision.

  1. Log in to the Azure Portal
  2. Click on + Create a resource
  3. Type in and search for: Virtual Network Gateway
  4. Click Create
  5. Type in the name of your Azure Virtual Network Gateway
  6. Select the region (it must be the same region as your virtual network)
  7. Select the Gateway Type: VPN
  8. The VPN type is: Route-based
  9. Select the SKU, in this example - I will be going with VpnGw1
  10. Select the Generation of the Virtual Network Gateway; I am going with: Generation 1
  11. Select the Virtual Network that you created earlier, and it will automatically find and assign the Gateway to the Subnet named: GatewaySubnet
  12. Select Standard public IP address SKU
  13. Select Public IP address and select: Create new
  14. Type in your public IP name
  15. Leave 'Enable active-active mode' and 'Configure BGP' as Disabled.
  16. Click Review + Create
  17. Azure Virtual Network Gateway
  18. Verify configuration is correct and clicks Create
  19. It can take up to 30-60 minutes for the Virtual Network Gateway to be created.

Setup Microsoft Entra ID authentication on the Virtual Network Gateway

Now that the Virtual Network has been created, we can now set up Microsoft Entra ID authentication.

Collect Microsoft Entra ID Tenant ID

First, we need to collect the Azure AD Tenancy ID

  1. Log in to the Azure Portal
  2. Click on Microsoft Entra ID
  3. In the Overview pane, copy the Tenant ID and save this for the next step.
Grant Azure VPN Client permisisons

Now we need to grant the Azure VPN application permissions.

  1. Log in to the Azure Portal

  2. Open a new window and type in and press Enter:

    https://login.microsoftonline.com/common/oauth2/authorize?client_id=41b23e61-6c1e-4545-b367-cd054e0ed4b4&response_type=code&redirect_uri=https://portal.azure.com&nonce=1234&prompt=admin_consent
  3. If you get an error about external identity, then replace /common/ with your tenant ID.

  4. Azure VPN Permissions

  5. Click Accept

  6. Navigate back to Microsoft Entra ID

  7. Select Enterprise Applications

  8. Select Azure VPN

  9. Copy the Application ID of the Azure VPN enterprise application (you will need both Application ID and tenant ID for the next steps)

  10. Azure VPN

Configure Point to Site Connection

Now its time to configure the Virtual Network Gateway

  1. Log in to the Azure Portal
  2. Navigate to the Virtual Network Gateway you created earlier
  3. Click on Point-to-site configuration
  4. Click Configure now
  5. Enter in your address pool (this is the address pool of the VPN clients, make sure this doesn't overlap with any other IP range you use, I will go with: 172.0.0.0/16)
  6. Make sure the Tunnel type is: OpenVPN (SSL)
  7. Select Microsoft Entra ID for the Authentication type
  8. For Tenant, ID enter in: https://login.microsoftonline.com/**TENANTID**/ and enter in your own Tenant ID.
  9. For the Audience (this is the users and groups that are assigned to the Enterprise Azure VPN application), put in the Application ID of the Azure VPN.
  10. For the Issuer, enter in: https://sts.windows.net/**TENANTID**/
  11. Azure Virtual Network Gateway
  12. Click Save
  13. It may take 1-5 minutes to save the configuration
Install and connect using the Azure VPN client

Now that the Point to Site VPN has been configured it's time to connect!

  1. Click on Download VPN client (if it is greyed out, then navigate to the Overview pane, then back to the Point-to-site configuration).
  2. Extract the zip file, you will need these files
  3. Download the Azure VPN Client to your computer.
  4. Azure VPN Client
  5. Once, downloaded click Open.
  6. Click the + sign (lower left)
  7. Click Import
  8. Navigate to the: azurevpnconfig.xml file that you downloaded earlier and click Open
  9. You can change the Connection Name to something more user friendly (you can also edit the file directly for when you look at pushing out this to multiple users, but make sure you have a backup of the file)
  10. Click Save
  11. Azure VPN Connection
  12. Click Connect
  13. Enter in your Microsoft Entra ID credentials (you may be prompted for MFA, depending on the rules - you can use Azure VPN application under conditional access)
  14. Azure VPN Connection
  15. You should now be connected to the Azure network through a point to site VPN!
  16. If I run 'ipconfig /all' on my device, I can see a PPP adapter that is connected and on the VPN address range created earlier: 172.0.0.2
  17. Azure Point to Site Connections
  18. If I navigate back to the Point-to-site connection in the Azure Portal, I can see, my connection has been allocated:
  19. Azure Point to Site Connections
  20. I can now use Remote Desktop to connect to a Virtual Machine, running in my AppServers Subnet, which I am running without the need of a Public IP or bastion/jump host:
  21. Azure Point to Site VPN

Note: I don't have a DNS service running in Azure, but the Azure VPN agent will take DNS from the Virtual Network if you have this configured to point towards a DNS server (Active Directory, or other DNS forwarder (pointing towards Azure DNS IP: 168.63.129.16) such as Azure Firewall DNS proxy; you can set Custom DNS servers by modifying your DNS configuration, or add entries into the host file of the computers.

You can set your Custom DNS settings (remember to add the DNS suffix if needed) and configure the VPN to automatically connect by following the details on the OpenVPN Azure AD Client page.

Using Intune, you can also push this configuration to your Windows 10 and 11 clients

My Website Setup

· 2 min read

Pretty simple article today regarding 'My website setup'.

I've had a few people ask what CMS (Content Management System) my website runs on - and no it's not running on an Azure App Service!

I am using:

  • Github Pages (running Jekyll and Ruby on Rails)
  • Cloudflare as my DNS CDN (which also allows me to set HTTPS) and cache the website across the planet

Because the pages are in a git repository, I have version control across my pages, can roll back or make any changes easily and allow others to submit pull requests for changes, or issues natively.

The pages are created using Markdown, I usually have a OneNote page with an idea or blurb, then Forestry to do the initial post, and then manually edit the files and verify the syntax is correct, add tables into the page and fix any issues that may have been caused (Forestry doesn't support markdown tables and can make some content look a bit weird and unstructured, but its usually an easy fix editing the markdown manually).

Having it on Github pages, helped me learn a lot more about using git and source control, versioning methodologies.

Then for comments, I use Disqus and for analytics, Google Analytics and Bing Webmaster Tools.

All in all - I just have to pay for the domain, everything else is free and because it's stateless, caching content is a lot easier and I don't have to worry about keeping a CMS up to date/patched or a database tuned!

If you're wondering why it's not running on an Azure App Service? I wanted something cheap, could further challenge and learn from, at the end of the day I wanted a stateless website (static websites in Storage account, wasn't available when I set this up) and I wanted to reserve my limited Azure credits to be able to actually learn and play more. I have no regrets in putting it in Github Pages and depending on your requirements - recommend you try it out!

Azure Public DNS as Code

· 13 min read

The Microsoft Azure ecosystem offers a lot of capabilities that empower individuals and businesses; one of those capabilities that are often overlooked is DNS(Domain Name System).

Azure DNS allows you to host your DNS domain in Azure, so you can manage your DNS records using the same credentials, billing, and support contract as your other Azure services. Zones can be either public or private, where Private DNS Zones (in Managed Preview) are only visible to VMs that are in your virtual network.

You can configure Azure DNS to resolve hostnames in your public domain. For example, if you purchased the contoso.xyz domain name from a domain name registrar, you can configure Azure DNS to host the contoso.xyz domain and resolve www.contoso.xyz to the IP address of your web server or web app.

In this article, we are going to focus on Azure Public DNS.

I had my external DNS under source control using Terraform and the Cloudflare provider a few years ago. I wanted to see if I use source control and continuous integration to do the same thing using Azure DNS and Azure Bicep.

My theory was I could make a change to a file and then commit it and have the Azure DNS records created or modified automatically, allowing changes to DNS to be gated, approved, scheduled and audited, allowing changes and rollback a lot easier – without having to give people access to be able to create DNS records with no auditability, turns out you can!

Using an Azure DevOps pipeline and repository and Azure Bicep, we will deploy an Azure Public DNS zone to a resource group automatically on a successful commit and any records.

Azure Bicep - Pipeline High Level

Create Azure Public DNS as Code

Prerequisites

  • An Azure DevOps account and permissions to create a service endpoint
  • An Azure subscription that you have at least contributor rights to
  • A git repository (I am going to use the repository in Azure DevOps, but you could use a nested repository from GitHub)
  • The latest Azure PowerShell modules and Azure Bicep/Azure CLI for local editing
  • A domain name and rights to change the nameservers to point towards Azure DNS

In this article, I will be using an Azure subscription. I have access to an Azure DevOps (free) subscription and a custom domain I joined named 'badasscloud.com'.

I will assume that you have nothing set up but feel free to skip the sections that aren't relevant.

That that we have the prerequisites sorted let's set it up...

Create Azure DevOps Repository

  1. Sign in to Azure DevOps

  2. Select + New Project

  3. Give your project a name (i.e., I am going with: DNSAsCode)

  4. Azure DevOps - Create New Project

  5. Click Create (your project will now be created)

  6. Click on Repos

  7. Click on Files

  8. Find the 'Initialize Main branch with a README or gitignore' section and click Initialize.

  9. Azure DevOps - Create New Project

  10. You should now have an empty git repository!

    Create Azure DevOps Service Connection

    For Azure DevOps to connect to Microsoft Azure, we need to set up a service principal; you can create the service connection in Azure DevOps. However, it usually generates a service principal with a name that could be unrecognizable in the future in Azure, and I prefer to develop them according to naming convention and something that I can look at and instantly recognize its use-case. To do that, we will create it using Azure CLI.

    1. Open PowerShell

    2. Run the following commands to connect to Azure and create your Service Principal with Contributor access to Azure:

      #Connects to Microsoft Azure
      az.cmd login
      #Set SPN name
      $AppRegName = 'SPN.AzureSubscription.Contributor'
      #Creates SPN and sets SPN as Contributor to the subscription
      $spn = az.cmd ad sp create-for-rbac --name $AppRegName --role 'contributor'
      #Exports Password, Tenant & App ID for better readability - required for Azure DevOps setup
      $spn | ConvertFrom-Json | Select-Object -Property password, tenant, appId
      az.cmd account show --query id --output tsv
      az.cmd account show --query name --output tsv
    3. Make sure you record the password, application ID and the subscription ID/name; you will need this for the next step - you won't be able to view it anywhere else; if you lose it, you can rerun the sp create command to generate a new password. Now that we have the SPN, we need to add the details into Azure DevOps.

    4. Sign in to Azure DevOps

    5. Navigate to the DNS As Code project you created earlier

    6. Click on Project Settings (bottom right-hand side of the window)

    7. Click on Service connections

    8. Click on: Create a service connection

    9. Select Azure Resource Manager

    10. Click Next

    11. Click on: Service Principal (Manual) and click Next

    12. Enter in the following details that we exported earlier from the creation of the service principal:

      • Subscription ID
      • Subscription Name
      • Service Principal ID (the appId)
      • Service principal key (password)
      • Tenant ID
    13. Click Verify to verify that Azure DevOps can connect to Azure; you should hopefully see a Verification succeeded.

    14. Give the Service connection a name (this is the display name that is visual in Azure DevOps)

    15. Add a description (i.e. created by, created on, created for)

    16. Click on Verify and save

    17. You now have a new Service connection!

    18. Azure DevOps - Service Connection

Note: The password for the service principal is valid for one year, so when they expire, you can come into the Azure DevOps service connection and update it here.

Add Azure Bicep to Repository

Now that Azure DevOps has the delegated rights to create resources in Microsoft Azure, we need to add the Azure Bicep for Azure DNS Zone.

I have created the below Azure Bicep file named: Deploy-PublicDNS.bicep

Don't edit the file yet. You can add your DNS records later - after we add some variables into the Azure Pipeline.

This file will:

  • Create a new public Azure DNS zone, if it doesn't exist
  • Add/Remove and modify any records

I have added CNAME, A Record and TXT Records as a base.

Deploy-PublicDNS.bicep
///Variables - Edit, these variables can be set in the script or implemented as part of Azure DevOps variables.
//Set the Domain Name Zone:
param PrimaryDNSZone string = ''
//Deploys to the location of your resource group, that is specified during the deployment.
var location = 'Global'
//Variable array for your A records. Add, remove and amend as needed, any new record needs to be included in {}.
var arecords = [
{
name: '@'
ipv4Address: '8.8.8.8'
}
{
name: 'webmail'
ipv4Address: '8.8.8.8'
}
]
//Variable array for your CNAME records. Add, remove and amend as needed, any new record needs to be included in {}.
var cnamerecords = [
{
name: 'blog'
value: 'luke.geek.nz'
}
]

//

var txtrecords = [
{
name: '@'
value: 'v=spf1 include:spf.protection.outlook.com -all'
}

]

///Deploys your infrastructure below.

//Deploys your DNS Zone.

resource DNSZone 'Microsoft.Network/dnsZones@2018-05-01' = {
name: toLower(PrimaryDNSZone)
location: location
properties: {
zoneType: 'Public'
}
}

//Deploys your A records that are listed in the arecord variable table above.

resource DNSARecords 'Microsoft.Network/dnsZones/A@2018-05-01' = [for arecord in arecords: {
name: toLower(arecord.name)
parent: DNSZone
properties: {
TTL: 3600
ARecords: [
{
ipv4Address: arecord.ipv4Address
}

]
targetResource: {}
}
}]

//Deploys your CNAME records that are listed in the cnamerecord variable table above.

resource CNAMErecords 'Microsoft.Network/dnsZones/CNAME@2018-05-01' = [for cnamerecord in cnamerecords: {
name: toLower(cnamerecord.name)
parent: DNSZone

properties: {
'TTL': 3600
CNAMERecord: {

cname: cnamerecord.value

}
targetResource: {}
}
}]

resource TXTrecords 'Microsoft.Network/dnsZones/TXT@2018-05-01' = [for txtrecord in txtrecords: {
name: toLower(txtrecord.name)
parent: DNSZone

properties: {
'TTL': 3600
TXTRecords: [
{
value: [
txtrecord.value
]
}

]
}


}]


output cnamerecords string = CNAMErecords[0].properties.CNAMERecord.cname
output arecords string = arecords[0].ipv4Address

To add the Azure Bicep file into Azure DevOps, you can commit it into the git repository; see a previous post on 'Git using Github Desktop on Windows for SysAdmins' to help get started. However, at this stage, I will create it manually in the portal.

  1. Sign in to Azure DevOps
  2. Navigate to the DNS As Code project you created earlier
  3. Click on Repos
  4. Click on Files
  5. Click on the Ellipsis on the right-hand side
  6. Click New
  7. Click File
  8. Azure DevOps - New File
  9. Type in the name of your file (including the bicep extension), i.e. Deploy-PublicDNS.bicep
  10. Click Create
  11. Copy the contents of the Azure Bicep file supplied above and paste them into the Contents of Deploy-PublicDNS.bicep in Azure DevOps
  12. Azure DevOps - Azure Bicep
  13. Click Commit
  14. Click Commit again
  15. While we are here, let's delete the README.md file (as it will cause issues with the pipeline later on), click on the README.md file.
  16. Click on the Ellipsis on the right-hand side
  17. Click Delete
  18. Click Commit
  19. You should now only have your: Deploy-PublicDNS.bicep in the repository.

Create Azure DevOps Pipeline

Now that we have the initial Azure Bicep file, it's time to create our pipeline that will do the heavy lifting. I have created the base pipeline that you can download, and we will import it into Azure DevOps.

azure-pipelines.yml
# Variable 'location' was defined in the Variables tab
# Variable 'PrimaryDNSZone' was defined in the Variables tab
# Variable 'ResourceGroupName' was defined in the Variables tab
# Variable 'SPN' is defined in the Variables tab
trigger:
branches:
include:
- refs/heads/main
jobs:
- job: Job_1
displayName: Agent job 1
pool:
vmImage: ubuntu-latest
steps:
- checkout: self
- task: AzureCLI@2
displayName: 'Azure CLI '
inputs:
connectedServiceNameARM: $(SPN)
scriptType: pscore
scriptLocation: inlineScript
inlineScript: >2-
az group create --name $(ResourceGroupName) --location $(location)
az deployment group create `
--template-file $(Build.SourcesDirectory)\Deploy-PublicDNS.bicep `
--resource-group $(ResourceGroupName) `
--parameters PrimaryDNSZone=$(PrimaryDNSZone)
powerShellErrorActionPreference: continue

This pipeline will run through the following steps:

  • Spin up an Azure-hosted agent running Ubuntu (it already has the Azure CLI and PowerShell setup)
  • Create the Azure resource group to place your DNS zone into (if it doesn't already exist)
  • Finally, do the actual Azure Bicep deployment and create your Primary DNS zone resource, and, if necessary, modify any resources.

Copy the contents of the YAML pipeline above, and let's import it to Azure DevOps.

  1. Sign in to Azure DevOps
  2. Navigate to the DNS As Code project you created earlier
  3. Click on Pipelines
  4. Click on the Create Pipeline
  5. Select Azure Repos Git (YAML)
  6. Select your DNSAsCode repository
  7. Select Starter pipeline
  8. Overwrite the contents of the starter pipeline with the YAML file supplied
  9. Azure DevOps - YAML
  10. Click on the arrow next to Save and Run and select Save
  11. Select Commit directly to the main branch
  12. Click Save
  13. You may get an error about the trigger. You can ignore it - we will need to set the variables and trigger now.
  14. Click on Pipelines, select your newly created pipeline
  15. Select Edit
  16. Click Variables
  17. Click on New Variable
  18. We need to add four variables. To make the deployment more environment-specific, add the following variables into Azure DevOps (these variables will be accessible by this pipeline only).
VariableNote
locationLocation where you want to deploy the Resource into – i.e. ‘Australia East’
PrimaryDNSZoneThe name of your domain you want the public zone to be, i.e. badasscloud.com
ResourceGroupNameThe name of the Resource Group that the DNS Zone resource will be deployed into, i.e. DNS-PRD-RG
SPNThe name of the Service Connection, that we created earlier to connect Azure DevOps to Azure, i.e., SPN.AzureDNSCode
  1. Azure DevOps Variables

  2. Click Save

    Test & final approval of Azure DevOps Pipeline

    Now that the Azure Pipeline has been created and variables set, it's time to test, warning this will run an actual deployment to your Azure subscription!

    We will deploy a once-off to grant the pipeline access to the service principal created earlier and verify that it works.

  3. Sign in to Azure DevOps

  4. Navigate to the DNS As Code project you created earlier

  5. Click on Pipelines

  6. Click on your Pipeline

  7. Select Run pipeline

  8. Click Run

  9. Click on Agent job 1

  10. You will see a message: This pipeline needs permission to access a resource before this run can continue

  11. Click View

  12. Azure DevOps - badasscloud.com DNS deployment

  13. Click Permit

  14. Click Permit again, to authorise your SPN access to your pipeline for all future runs

  15. Your pipeline will be added to the queue and once an agent becomes available will start to run.

As seen below, there were no resources before my deployment and the Azure Pipeline agent kicked off and created the resources in the Azure portal.

Note: You can expand the Agent Job to see the steps of the job, I hid it as it revealed subscription ID information etc during the deployment.

Azure DevOps - badasscloud.com DNS deployment

Remember to update your nameserver records for your domain to point towards the nameserver entries in the Azure DNS zone resource, to use Azure DNS!

Edit the Bicep file

Now that you have successfully deployed your Azure Bicep file, you can go into the Azure Bicep and update the A, CNAME records to match your own environment - any new change to this repository will automatically trigger Continous Integration and deployment, you can override this behaviour by editing the Pipeline, clicking Edit Trigger and unselect 'Enable; continuous integration

Each variable (var object) (cnames, arecords) is enclosed in brackets, this array allows you to add multiple records, for example, if I wanted to add another name record, it would look like this:

//Variable array for your CNAME records. Add, remove and amend as needed, any new record needs to be included in {}.
var cnamerecords = [
{
name: 'blog'
value: 'luke.geek.nz'
}
{
name: 'fancierblog'
value: 'azure.com'
}
]

Simply add another object under the first, as long as it is included in the brackets, then upon deployment Azure Bicep will parse the variable array and for each record, create/modify the DNS records, you only ever need to edit the content in the variable without touching the actual resource deployment.

As records are added and removed over time, you will develop a commit history and with the power of Azure DevOps, can implement scheduling changes at certain times and approval!

Hopefully, this article helps you achieve Infrastructure as Code for your Azure DNS resource, the same concept can be applied for other resources using Azure Bicep as well.