How to setup Service Chaining in Azure?

In this blog post, we will learn about VNet Peering, Hub and spoke Architecture and Service chaining in Azure.

What is VNet Peering?

Virtual network peering enables you to connect two Azure virtual networks. Once peered, the virtual networks appear as one, for connectivity purposes. There are two types of VNet peering.

  • Regional VNet peering connects Azure virtual networks in the same region.
  • Global VNet peering connects Azure virtual networks in different regions.
Global and Regional Vnet Peering

Issues with VNet Peering

VNet Peering is NONTRANSITIVE. This means that if you establish VNet Peering between VNet1 and VNet2 and between VNet2 and VNet3, VNet Peering capabilities do not apply between VNet1 and VNet3.This is shown in the below diagram:

How to overcome the limitations of Vnet Peering?

You can deploy hub-and-spoke networks, where the hub virtual network can host infrastructure components such as a network virtual appliance or VPN gateway. All the spoke virtual networks can then peer with the hub virtual network. Traffic can flow through network virtual appliances or VPN gateways in the hub virtual network. This way all the networks can communicate with each other without any restrictions.

Hub and Spoke Architecture

What is service chaining?

  • Virtual network peering enables the next hop in a user-defined route to be the IP address of a virtual machine in the peered virtual network or a VPN gateway.
  • Service chaining enables you to direct traffic from one virtual network to a virtual appliance, or virtual network gateway, in a peered virtual network, through user-defined routes
Service Chaining Example

Service Chaining Demo

We will understand service chaining with the help of a Demo. We will implement the diagram shown below in a demo. The demo is recorded and posted on my youtube channel and the link is provided below.

Service Chaining Demo

Here is the code used in the Demo.

#This is the code for the sc_azuredeploy.parameters.json
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "adminUsername": {
            "value": "useradmin"
        },
        "adminPassword": {
            "value": "Pa55w.rd1234"
        }
    }
}

#Code for sc1_azuredeploy.json

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vmSize": {
            "type": "string",
            "defaultValue": "Standard_DS1_v2",
            "metadata": {
                "description": "VM size"
            }
        },
        "vm1Name": {
            "type": "string",
            "defaultValue": "vm1",
            "metadata": {
                "description": "VM1 name"
            }
        },
        "vm2Name": {
            "type": "string",
            "defaultValue": "vm2",
            "metadata": {
                "description": "VM2 name"
            }
        },
        "adminUsername": {
            "type": "string",
            "metadata": {
                "description": "Admin username"
            }
        },
        "adminPassword": {
            "type": "securestring",
            "metadata": {
                "description": "Admin password"
            }
        },
        "virtualNetworkName": {
            "type": "string",
            "defaultValue": "vnet1",
            "metadata": {
                "description": "Virtual network name"
            }
        }
    },
    "variables": {
        "vm1Name": "[parameters('vm1Name')]",
        "vm2Name": "[parameters('vm2Name')]",
        "nic1": "nic1",
        "nic2": "nic2",
        "virtualNetworkName": "[parameters('virtualNetworkName')]",
        "subnet0Name": "subnet0",
        "subnet1Name": "subnet1",
        "publicIPAddress0Name": "pip1",
        "publicIPAddress1Name": "pip2",
        "subnet0Ref": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnet0Name'))]",
        "subnet1Ref": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnet1Name'))]",
        "networkSecurityGroup0Name": "nsg1",
        "networkSecurityGroup1Name": "nsg2"
    },
    "resources": [
        {
            "name": "[variables('vm1Name')]",
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2018-06-01",
            "location": "[resourceGroup().location]",
            "comments": "The first VM",
            "dependsOn": [
                "[variables('nic1')]"
            ],
            "properties": {
                "osProfile": {
                    "computerName": "[variables('vm1Name')]",
                    "adminUsername": "[parameters('adminUsername')]",
                    "adminPassword": "[parameters('adminPassword')]",
                    "windowsConfiguration": {
                        "provisionVmAgent": "true"
                    }
                },
                "hardwareProfile": {
                    "vmSize": "[parameters('vmSize')]"
                },
                "storageProfile": {
                    "imageReference": {
                        "publisher": "MicrosoftWindowsServer",
                        "offer": "WindowsServer",
                        "sku": "2016-Datacenter",
                        "version": "latest"
                    },
                    "osDisk": {
                        "createOption": "fromImage"
                    },
                    "dataDisks": []
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "properties": {
                                "primary": true
                            },
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nic1'))]"
                        }
                    ]
                }
            }
        },
        {
            "name": "[variables('vm2Name')]",
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2018-06-01",
            "location": "[resourceGroup().location]",
            "comments": "The second VM",
            "dependsOn": [
                "[variables('nic2')]"
            ],
            "properties": {
                "osProfile": {
                    "computerName": "[variables('vm2Name')]",
                    "adminUsername": "[parameters('adminUsername')]",
                    "adminPassword": "[parameters('adminPassword')]",
                    "windowsConfiguration": {
                        "provisionVmAgent": "true"
                    }
                },
                "hardwareProfile": {
                    "vmSize": "[parameters('vmSize')]"
                },
                "storageProfile": {
                    "imageReference": {
                        "publisher": "MicrosoftWindowsServer",
                        "offer": "WindowsServer",
                        "sku": "2016-Datacenter",
                        "version": "latest"
                    },
                    "osDisk": {
                        "createOption": "fromImage"
                    },
                    "dataDisks": []
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "properties": {
                                "primary": true
                            },
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nic2'))]"
                        }
                    ]
                }
            }
        },
        {
            "type": "Microsoft.Network/virtualNetworks",
            "name": "[variables('virtualNetworkName')]",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "Virtual Network",
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "10.104.0.0/16"
                    ]
                },
                "subnets": [
                    {
                        "name": "[variables('subnet0Name')]",
                        "properties": {
                            "addressPrefix": "10.104.0.0/24"
                        }
                    },
                    {
                        "name": "[variables('subnet1Name')]",
                        "properties": {
                            "addressPrefix": "10.104.1.0/24"
                        }
                    }
                ]
            }
        },
        {
            "name": "[variables('nic1')]",
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "NIC of the first VM",
            "dependsOn": [
                "[variables('publicIPAddress0Name')]",
                "[variables('networkSecurityGroup0Name')]",
                "[variables('virtualNetworkName')]"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig1",
                        "properties": {
                            "subnet": {
                                "id": "[variables('subnet0Ref')]"
                            },
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIpAddress": {
                                "id": "[resourceId('Microsoft.Network/publicIpAddresses', variables('publicIPAddress0Name'))]"
                            }
                        }
                    }
                ],
                "networkSecurityGroup": {
                    "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroup0Name'))]"
                }
            }
        },
        {
            "name": "[variables('nic2')]",
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "NIC of the second VM",
            "dependsOn": [
                "[variables('publicIPAddress1Name')]",
                "[variables('networkSecurityGroup1Name')]",
                "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig1",
                        "properties": {
                            "subnet": {
                                "id": "[variables('subnet1Ref')]"
                            },
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIpAddress": {
                                "id": "[resourceId('Microsoft.Network/publicIpAddresses', variables('publicIPAddress1Name'))]"
                            }				
                        }
                    }
                ],
                "networkSecurityGroup": {
                    "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroup1Name'))]"
                }
            }
        },
        {
            "name": "[variables('publicIPAddress0Name')]",
            "type": "Microsoft.Network/publicIpAddresses",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "Public IP for NIC of the first VM",
            "properties": {
                "publicIpAllocationMethod": "Dynamic"
            }
        },
        {
            "name": "[variables('publicIPAddress1Name')]",
            "type": "Microsoft.Network/publicIpAddresses",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "Public IP for NIC of the second VM",
            "properties": {
                "publicIpAllocationMethod": "Dynamic"
            }
        },
        {
            "name": "[variables('networkSecurityGroup0Name')]",
            "type": "Microsoft.Network/networkSecurityGroups",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "NSG for NIC of the first VM",
            "properties": {
                "securityRules": [
                    {
                        "name": "default-allow-rdp",
                        "properties": {
                            "priority": 1000,
                            "sourceAddressPrefix": "*",
                            "protocol": "Tcp",
                            "destinationPortRange": "3389",
                            "access": "Allow",
                            "direction": "Inbound",
                            "sourcePortRange": "*",
                            "destinationAddressPrefix": "*"
                        }
                    }
                ]
            }
        },
        {
            "name": "[variables('networkSecurityGroup1Name')]",
            "type": "Microsoft.Network/networkSecurityGroups",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "NSG for NIC of the second VM",
            "properties": {
                "securityRules": [
                    {
                        "name": "default-allow-rdp",
                        "properties": {
                            "priority": 1000,
                            "sourceAddressPrefix": "*",
                            "protocol": "Tcp",
                            "destinationPortRange": "3389",
                            "access": "Allow",
                            "direction": "Inbound",
                            "sourcePortRange": "*",
                            "destinationAddressPrefix": "*"
                        }
                    }
                ]
            }
        }
    ],
    "outputs": {}
}

#sc2_azuredeploy.json

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vmSize": {
            "type": "string",
            "defaultValue": "Standard_DS1_v2",
            "metadata": {
                "description": "VM size"
            }
        },
        "vmName": {
           "type": "string",
            "defaultValue": "vm3",
            "metadata": {
                "description": "VM name"
            }
        },
        "adminUsername": {
            "type": "string",
            "metadata": {
                "description": "Admin username"
            }
        },
        "adminPassword": {
            "type": "securestring",
            "metadata": {
                "description": "Admin password"
            }
        },
        "virtualNetworkName": {
            "type": "string",
            "defaultValue": "vnet2",
            "metadata": {
                "description": "Virtual network name"
            }
        }
    },
    "variables": {
        "vmName": "[parameters('vmName')]",
        "nic3": "nic3",
        "virtualNetworkName": "[parameters('virtualNetworkName')]",
        "subnet0Name": "subnet0",
        "publicIPAddressName": "pip3",
        "subnet0Ref": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnet0Name'))]",
        "networkSecurityGroupName": "nsg3"
    },
    "resources": [
        {
            "name": "[variables('vmName')]",
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2018-06-01",
            "location": "[resourceGroup().location]",
            "comments": "The third VM",
            "dependsOn": [
                "[variables('nic3')]"
            ],
            "properties": {
                "osProfile": {
                    "computerName": "[variables('vmName')]",
                    "adminUsername": "[parameters('adminUsername')]",
                    "adminPassword": "[parameters('adminPassword')]",
                    "windowsConfiguration": {
                        "provisionVmAgent": "true"
                    }
                },
                "hardwareProfile": {
                    "vmSize": "[parameters('vmSize')]"
                },
                "storageProfile": {
                    "imageReference": {
                        "publisher": "MicrosoftWindowsServer",
                        "offer": "WindowsServer",
                        "sku": "2016-Datacenter",
                        "version": "latest"
                    },
                    "osDisk": {
                        "createOption": "fromImage"
                    },
                    "dataDisks": []
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "properties": {
                                "primary": true
                            },
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nic3'))]"
                        }
                    ]
                }
            }
        },
        {
            "type": "Microsoft.Network/virtualNetworks",
            "name": "[variables('virtualNetworkName')]",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "Virtual Network",
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "10.204.0.0/16"
                    ]
                },
                "subnets": [
                    {
                        "name": "[variables('subnet0Name')]",
                        "properties": {
                            "addressPrefix": "10.204.0.0/24"
                        }
                    }
                ]
            }
        },
        {
            "name": "[variables('nic3')]",
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "NIC of the third VM",
            "dependsOn": [
                "[variables('publicIpAddressName')]",
                "[variables('networkSecurityGroupName')]",
                "[variables('virtualNetworkName')]"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig1",
                        "properties": {
                            "subnet": {
                                "id": "[variables('subnet0Ref')]"
                            },
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIpAddress": {
                                "id": "[resourceId('Microsoft.Network/publicIpAddresses', variables('publicIpAddressName'))]"
                            }
                        }
                    }
                ],
                "networkSecurityGroup": {
                    "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
                }
            }
        },
        {
            "name": "[variables('publicIpAddressName')]",
            "type": "Microsoft.Network/publicIpAddresses",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "Public IP for NIC of the third VM",
            "properties": {
                "publicIpAllocationMethod": "Dynamic"
            }
        },
        {
            "name": "[variables('networkSecurityGroupName')]",
            "type": "Microsoft.Network/networkSecurityGroups",
            "apiVersion": "2018-08-01",
            "location": "[resourceGroup().location]",
            "comments": "NSG for NIC of the third VM",
            "properties": {
                "securityRules": [
                    {
                        "name": "default-allow-rdp",
                        "properties": {
                            "priority": 1000,
                            "sourceAddressPrefix": "*",
                            "protocol": "Tcp",
                            "destinationPortRange": "3389",
                            "access": "Allow",
                            "direction": "Inbound",
                            "sourcePortRange": "*",
                            "destinationAddressPrefix": "*"
                        }
                    }
                ]
            }
        }
    ],
    "outputs": {}
}

I hope you liked this post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.