Azure Fundamental – Azure Resource Manager and Azure Templates (Part-10)

  1. Interaction Methods:
    • Azure UI/Portal: The web-based interface provided by Azure for managing resources visually.
    • CLI (Command-Line Interface): Tools like Azure CLI allow users to manage Azure resources through command-line commands.
    • ARM Templates: JSON files that define the infrastructure and configuration of Azure resources declaratively.
    • Bicep: A domain-specific language (DSL) for deploying Azure resources declaratively, which compiles down to ARM templates.
    • SDK (Software Development Kits): Libraries provided by Azure for different programming languages to interact programmatically with Azure resources.
  2. ARM (Azure Resource Manager):
    • ARM is the deployment and management service for Azure. It provides a consistent management layer that enables you to create, update, and delete resources in your Azure subscription.
  3. Azure:
    • This represents the actual Azure cloud where resources are deployed and managed.

Detailed Explanation:

  1. User Interactions:
    • Users can use various tools and methods to interact with Azure. The choice depends on their preference, requirement, and use case.
  2. Methods:
    • Azure UI/Portal: Ideal for users who prefer a graphical interface for managing resources. It’s user-friendly and suitable for quick setups and monitoring.
    • CLI: Preferred by those who like working in a command-line environment. It is powerful for scripting and automation.
    • ARM Templates: Used for Infrastructure as Code (IaC), allowing for repeatable deployments and version control.
    • Bicep: A more readable and concise way to write IaC, which then translates into ARM templates.
    • SDK: Used by developers to interact with Azure services directly from their applications.
  3. Azure Resource Manager (ARM):
    • ARM acts as the central point that receives all the requests from the various methods. It ensures that the requests are authenticated, authorized, and then processed.
    • It handles the creation, updating, and deletion of resources in a consistent manner.
  4. Deployment to Azure:
    • Once ARM processes the requests, the corresponding resources are deployed, managed, or modified in the Azure cloud.

Example Scenario:

Suppose a user wants to deploy a virtual machine (VM) on Azure. They could:

  1. Use the Azure Portal: Navigate through the web interface to create and configure the VM.
  2. Use Azure CLI: Execute a command like az vm create with the necessary parameters.
  3. Deploy an ARM Template: Write a JSON template defining the VM and deploy it using az deployment group create.
  4. Use Bicep: Write a Bicep file that defines the VM and deploy it, which gets converted to an ARM template under the hood.
  5. Use SDK: Write a script or application in a programming language (e.g., Python) using the Azure SDK to create the VM programmatically.

To Start with Azure template

Download Visual studio –> Install ARM Resource manager (ARM) Tools

Install Azure CLI extension in Visual Studio

How to install Azure CLI in Visual Studio – https://www.cloudopsnow.in/how-to-install-azure-cli-in-visual-studio/

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "functions": [],
    "variables": {},
    "resources": [],
    "outputs": {}
}

Create a .json file –> Search for ‘arm’ ,We will get below ARM template

To create storage account – search under resource – ‘arm-storage’, change value as per your requirement

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "functions": [],
    "variables": {},
    "resources": [
        {
            "name": "jamidemo",
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2023-01-01",
            "tags": {
                "displayName": "jamidemo123"
            },
            "location": "[resourceGroup().location]",
            "kind": "StorageV2",
            "sku": {
                "name": "Premium_LRS",
                "tier": "Premium"
            }
        }
    ],
    "outputs": {}
}

Steps to deploy storage account arm template

Create resource group

az group create --name vscode --location 'Central US'

Practical:
PS C:\Users\gufra\Desktop\ARM> az group create --name vscode --location 'Central US'
{
  "id": "/subscriptions/157c38cd-a49f-496e-91c2-0dad1860b1de/resourceGroups/vscode",
  "location": "centralus",
  "managedBy": null,
  "name": "vscode",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"

Create the storage account

Switch to the folder where you have the 01-storage-account.json or similar file

az deployment group create --resource-group vscode --template-file 01-storage-account.json

Practical:
S C:\Users\gufra\Desktop\ARM> az deployment group create --resource-group vscode --template-file Storage_account.json   
{
  "id": "/subscriptions/157c38cd-a49f-496e-91c2-0dad1860b1de/resourceGroups/vscode/providers/Microsoft.Resources/deployments/Storage_account",
  "location": null,
  "name": "Storage_account",
  "properties": {
    "correlationId": "2bf46100-658a-41ba-a5ff-1227afa50832",
    "debugSetting": null,
    "dependencies": [],
    "duration": "PT22.4832539S",
    "error": null,
    "mode": "Incremental",
    "onErrorDeployment": null,
    "outputResources": [
      {
        "id": "/subscriptions/157c38cd-a49f-496e-91c2-0dad1860b1de/resourceGroups/vscode/providers/Microsoft.Storage/storageAccounts/jamidemo",
        "resourceGroup": "vscode"
      }
    ],
    "outputs": {},
    "parameters": {},
    "parametersLink": null,
    "providers": [
      {
        "id": null,
        "namespace": "Microsoft.Storage",
        "providerAuthorizationConsentState": null,
        "registrationPolicy": null,
        "registrationState": null,
        "resourceTypes": [
          {
            "aliases": null,
            "apiProfiles": null,
            "apiVersions": null,
            "capabilities": null,
            "defaultApiVersion": null,
            "locationMappings": null,
            "locations": [
              "centralus"
            ],
            "properties": null,
            "resourceType": "storageAccounts",
            "zoneMappings": null
          }
        ]
      }
    ],
    "provisioningState": "Succeeded",
    "templateHash": "15869348054422500026",
    "templateLink": null,
    "timestamp": "2024-05-28T00:45:39.297838+00:00",
    "validatedResources": null
  },
  "resourceGroup": "vscode",
  "tags": null,
  "type": "Microsoft.Resources/deployments"
}

Delete the resource

az group delete --name vscode --no-wait

To under more about templates go through official document – https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/overview

Deep Drive Explanation of Azure Template

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "functions": [],
    "variables": {},
    "resources": [],
    "outputs": {}
}

1. $schema

  • Purpose: This line specifies the schema that defines the structure and version of the template.
  • Value: "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"
  • Explanation: The URL points to the JSON schema that helps with validating the template structure according to the Azure standards as of April 2019. This ensures that the template adheres to the correct format and syntax.

Example:

"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"

2. contentVersion

  • Purpose: Indicates the version of the template content.
  • Value: "1.0.0.0"
  • Explanation: This is a user-defined version number for the template. It helps track changes and updates to the template. This version number does not affect the deployment but can be useful for documentation and version control.
"contentVersion": "1.0.0.0"

3. parameters

  • Purpose: Defines the input parameters for the template. Parameters allow you to customize the deployment by providing different values without changing the template itself.
  • Value: {} (empty in the provided example)
  • Explanation: In a more complex template, this section would include parameters that can be set during deployment. Parameters can have types such as string, int, bool, etc., and can have default values, allowed values, and descriptions.

Example:

"parameters": {
    "storageAccountType": {
        "type": "string",
        "defaultValue": "Standard_LRS",
        "allowedValues": [
            "Standard_LRS",
            "Standard_GRS",
            "Standard_ZRS"
        ],
        "metadata": {
            "description": "Type of the storage account"
        }
    }
}

In this example, the parameter storageAccountType allows the user to specify the type of storage account to create.

4. functions

  • Purpose: Defines custom functions that can be used within the template.
  • Value: give below
  • Explanation: This custom function uniqueStorageAccountName takes a prefix and appends a unique string derived from the resource group’s ID, ensuring the storage account name is unique.

Example:

"functions": [
    {
        "namespace": "udf",
        "members": {
            "uniqueStorageAccountName": {
                "parameters": [
                    {
                        "name": "prefix",
                        "type": "string"
                    }
                ],
                "output": {
                    "type": "string",
                    "value": "[concat(parameters('prefix'), uniqueString(resourceGroup().id))]"
                }
            }
        }
    }
]

5. variables

  • Purpose: Defines variables that store values to be reused throughout the template. Variables can help simplify the template by avoiding repetition.
  • Value: {} (empty in the provided example)
  • Explanation: Variables can hold values derived from parameters, constants, or expressions, making the template more readable and maintainable.

Example:

"variables": {
    "storageAccountName": "[concat('storage', uniqueString(resourceGroup().id))]"
}

In this example, the storageAccountName variable generates a unique storage account name based on the resource group’s ID.

6. resources

  • Purpose: Specifies the resources to be deployed or updated in Azure.
  • Value: [] (empty in the provided example)
  • Explanation: This is the core part of the template where you define Azure resources such as virtual machines, storage accounts, databases, etc. Each resource includes details like type, API version, name, location, and properties.

Example

"resources": [
    {
        "type": "Microsoft.Storage/storageAccounts",
        "apiVersion": "2019-06-01",
        "name": "[variables('storageAccountName')]",
        "location": "[resourceGroup().location]",
        "sku": {
            "name": "[parameters('storageAccountType')]"
        },
        "kind": "StorageV2",
        "properties": {}
    }
]

In this example, a storage account resource is defined with its type, API version, name, location, SKU, and kind.

7. outputs

  • Purpose: Defines values that are returned after the deployment is completed.
  • Value: {} (empty in the provided example)
  • Explanation: Outputs can be used to return information about the deployed resources, such as their names, IDs, or other properties. This is useful for chaining deployments or for users to know specific details about the deployment.

Example:

"outputs": {
    "storageAccountName": {
        "type": "string",
        "value": "[variables('storageAccountName')]"
    }
}

In this example, the output returns the name of the storage account that was created during the deployment.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccountType": {
            "type": "string",
            "defaultValue": "Standard_LRS",
            "allowedValues": [
                "Standard_LRS",
                "Standard_GRS",
                "Standard_ZRS"
            ],
            "metadata": {
                "description": "Type of the storage account"
            }
        }
    },
    "functions": [
        {
            "namespace": "udf",
            "members": {
                "uniqueStorageAccountName": {
                    "parameters": [
                        {
                            "name": "prefix",
                            "type": "string"
                        }
                    ],
                    "output": {
                        "type": "string",
                        "value": "[concat(parameters('prefix'), uniqueString(resourceGroup().id))]"
                    }
                }
            }
        }
    ],
    "variables": {
        "storageAccountName": "[udf.uniqueStorageAccountName('storage')]"
    },
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2019-06-01",
            "name": "[variables('storageAccountName')]",
            "location": "[resourceGroup().location]",
            "sku": {
                "name": "[parameters('storageAccountType')]"
            },
            "kind": "StorageV2",
            "properties": {}
        }
    ],
    "outputs": {
        "storageAccountName": {
            "type": "string",
            "value": "[variables('storageAccountName')]"
        }
    }
}

Example

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "functions": [],
    "variables": {},
    "resources": [
        {
            "name": "[toLower('ubuntuVM1storageabhi')]",
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2023-01-01",
            "location": "[resourceGroup().location]",
            "tags": {
                "displayName": "ubuntuVM1 Storage Account"
            },
            "sku": {
                "name": "Standard_LRS"
            },
            "kind": "Storage"
        },
        {
            "name": "ubuntuVM1-PublicIP",
            "type": "Microsoft.Network/publicIPAddresses",
            "apiVersion": "2023-04-01",
            "location": "[resourceGroup().location]",
            "tags": {
                "displayName": "PublicIPAddress"
            },
            "properties": {
                "publicIPAllocationMethod": "Dynamic",
                "dnsSettings": {
                    "domainNameLabel": "[toLower('ubuntuVM1')]"
                }
            }
        },
        {
            "name": "ubuntuVM1-nsg",
            "type": "Microsoft.Network/networkSecurityGroups",
            "apiVersion": "2023-04-01",
            "location": "[resourceGroup().location]",
            "properties": {
                "securityRules": [
                    {
                        "name": "nsgRule1",
                        "properties": {
                            "description": "description",
                            "protocol": "Tcp",
                            "sourcePortRange": "*",
                            "destinationPortRange": "22",
                            "sourceAddressPrefix": "*",
                            "destinationAddressPrefix": "*",
                            "access": "Allow",
                            "priority": 100,
                            "direction": "Inbound"
                        }
                    }
                ]
            }
        },
        {
            "name": "ubuntuVM1-VirtualNetwork",
            "type": "Microsoft.Network/virtualNetworks",
            "apiVersion": "2023-04-01",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/networkSecurityGroups', 'ubuntuVM1-nsg')]"
            ],
            "tags": {
                "displayName": "ubuntuVM1-VirtualNetwork"
            },
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "10.0.0.0/16"
                    ]
                },
                "subnets": [
                    {
                        "name": "ubuntuVM1-VirtualNetwork-Subnet",
                        "properties": {
                            "addressPrefix": "10.0.0.0/24",
                            "networkSecurityGroup": {
                                "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'ubuntuVM1-nsg')]"
                            }
                        }
                    }
                ]
            }
        },
        {
            "name": "ubuntuVM1-NetworkInterface",
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2023-04-01",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/publicIPAddresses', 'ubuntuVM1-PublicIP')]",
                "[resourceId('Microsoft.Network/virtualNetworks', 'ubuntuVM1-VirtualNetwork')]"
            ],
            "tags": {
                "displayName": "ubuntuVM1-NetworkInterface"
            },
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipConfig1",
                        "properties": {
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIPAddress": {
                                "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'ubuntuVM1-PublicIP')]"
                            },
                            "subnet": {
                                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'ubuntuVM1-VirtualNetwork', 'ubuntuVM1-VirtualNetwork-Subnet')]"
                            }
                        }
                    }
                ]
            }
        },
        {
            "name": "ubuntuVM1",
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2023-03-01",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/networkInterfaces', 'ubuntuVM1-NetworkInterface')]"
            ],
            "tags": {
                "displayName": "ubuntuVM1"
            },
            "properties": {
                "hardwareProfile": {
                    "vmSize": "Standard_A2_v2"
                },
                "osProfile": {
                    "computerName": "ubuntuVM1",
                    "adminUsername": "azureuser",
                    "adminPassword": "azureuser@123"
                },
                "storageProfile": {
                    "imageReference": {
                        "publisher": "Canonical",
                        "offer": "UbuntuServer",
                        "sku": "16.04-LTS",
                        "version": "latest"
                    },
                    "osDisk": {
                        "name": "ubuntuVM1-OSDisk",
                        "caching": "ReadWrite",
                        "createOption": "FromImage"
                    }
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', 'ubuntuVM1-NetworkInterface')]"
                        }
                    ]
                },
                "diagnosticsProfile": {
                    "bootDiagnostics": {
                        "enabled": true,
                        "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', toLower('ubuntuVM1storageabhi'))).primaryEndpoints.blob]"
                    }
                }
            }
        }
    ],
    "outputs": {}
}

Deploy Azure VM using Arm templates

Create resource group if it does not exist

az group create --name vscode --location 'Central US'

Create virtual machine

Switch to the folder where you have the 01-create-vm.json file available.

az deployment group create --resource-group vscode --template-file 01-create-vm.json

Related Posts

Secure supply chain: SBOM, SLSA, signing, provenance (plain English)

If you ship software today, you don’t just ship your code. You ship: That whole chain is your software supply chain. And attackers love it, because instead…

Read More

CI/CD for Cloud Apps: Build → Scan → Deploy → Rollback (a practical reference pipeline)

CI/CD sounds simple until you’re responsible for a production system and realize: This guide gives you a reference CI/CD pipeline you can adopt for most cloud apps…

Read More

Policy as Code: OPA/Rego basics + how it prevents bad infra

You know that feeling when an incident starts with a sentence like: Most “bad infra” isn’t malicious. It’s normal engineering drift:new hires, rushed PRs, copy-paste manifests, unclear…

Read More

Reusable IaC Module Design: naming, inputs/outputs, versioning (the engineer’s playbook)

Reusable IaC modules are like internal libraries: if the “API” is clean, teams move fast. If it’s messy, everyone forks it, patches it, and you end up…

Read More

GitOps explained: Argo CD vs Flux, patterns, and anti-patterns

GitOps is one of those ideas that sounds like buzzwords… until you run it for 30 days and suddenly you can’t imagine operating Kubernetes without it. Because…

Read More

Terraform vs CloudFormation vs Pulumi: which fits which team (the practical, engineer-first guide)

You’re not really choosing a tool. You’re choosing how your team will think about infrastructure for the next 2–5 years: This guide helps you decide fast, without…

Read More
guest
0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x
()
x