{"id":95,"date":"2026-01-26T12:00:00","date_gmt":"2026-01-26T12:00:00","guid":{"rendered":"https:\/\/rezachegini.com\/?p=95"},"modified":"2026-10-30T07:01:09","modified_gmt":"2026-10-30T07:01:09","slug":"my-first-azure-arm-templates-deploying-web-apps","status":"publish","type":"post","link":"https:\/\/rezachegini.com\/?p=95","title":{"rendered":"My First Azure ARM Templates: Deploying Web Apps"},"content":{"rendered":"<h3 class=\"wp-block-heading\">Why I Started Learning ARM Templates<\/h3><p class=\"wp-block-paragraph\">Hello everyone! I&#8217;m Reza, a junior DevOps engineer. Today I want to share my first experience with Azure ARM templates. When I started my home lab, I was creating Azure resources manually through the portal. It was slow and I made mistakes. Then I learned about Infrastructure as Code (IaC) and decided to try ARM templates.<\/p><h3 class=\"wp-block-heading\">What is ARM Template?<\/h3><p class=\"wp-block-paragraph\">ARM means Azure Resource Manager. ARM templates are JSON files that define what resources you want to create in Azure. Instead of clicking in the portal, you write code and Azure creates everything for you.<\/p><p class=\"wp-block-paragraph\">Think about it like a recipe. You write down all ingredients and steps, then Azure follows your recipe and makes the infrastructure.<\/p><h3 class=\"wp-block-heading\">My First ARM Template &#8211; Creating a Web App<\/h3><p class=\"wp-block-paragraph\">Let me show you my first ARM template. This is the actual code from my GitHub repository:<\/p><pre class=\"wp-block-code\"><code>{\n  \"$schema\": \"https:\/\/schema.management.azure.com\/schemas\/2019-04-01\/deploymentTemplate.json#\",\n  \"contentVersion\": \"1.0.0.0\",\n  \"parameters\": {},\n  \"functions\": [],\n  \"variables\": {},\n  \"resources\": [\n    {\n        \"type\": \"Microsoft.Web\/serverfarms\",\n        \"apiVersion\": \"2022-03-01\",\n        \"name\": \"reza787878\",\n        \"location\": \"[resourceGroup().location]\",\n        \"sku\": {\n                \"name\":\"F1\",\n                \"capacity\":1\n            },\n            \"properties\":{\n                \"name\":\"reza787878\"\n            }\n    },\n    {\n            \"type\": \"Microsoft.Web\/sites\",\n            \"apiVersion\": \"2022-03-01\",\n            \"name\": \"rezawebapp994848\",\n            \"location\": \"[resourceGroup().location]\",\n            \"properties\":{\n                \"name\":\"rezawebapp994848\",\n                \"serverFarmId\":\"[resourceId('Microsoft.Web\/serverfarms','reza787878')]\"\n            },\n            \"dependsOn\":[\n                \"[resourceId('Microsoft.Web\/serverfarms','reza787878')]\"\n            ]\n        }\n  ],\n  \"outputs\": {}\n}<\/code><\/pre><h3 class=\"wp-block-heading\">Understanding the Structure<\/h3><p class=\"wp-block-paragraph\">Let me explain each part:<\/p><h3 class=\"wp-block-heading\">1. Schema and Version<\/h3><pre class=\"wp-block-code\"><code>\"$schema\": \"https:\/\/schema.management.azure.com\/schemas\/2019-04-01\/deploymentTemplate.json#\",\n\"contentVersion\": \"1.0.0.0\"<\/code><\/pre><p class=\"wp-block-paragraph\">This tells Azure what type of template this is. Every ARM template needs this at the top.<\/p><h3 class=\"wp-block-heading\">2. App Service Plan (Server Farm)<\/h3><pre class=\"wp-block-code\"><code>{\n    \"type\": \"Microsoft.Web\/serverfarms\",\n    \"apiVersion\": \"2022-03-01\",\n    \"name\": \"reza787878\",\n    \"location\": \"[resourceGroup().location]\",\n    \"sku\": {\n        \"name\":\"F1\",\n        \"capacity\":1\n    }\n}<\/code><\/pre><p class=\"wp-block-paragraph\">This creates the App Service Plan. Think of it like a server that will host your web app.<\/p><p class=\"wp-block-paragraph\">Important details:<\/p><ul class=\"wp-block-list\"><li>type: Microsoft.Web\/serverfarms &#8211; this is the resource type for App Service Plan<\/li><li>apiVersion: 2022-03-01 &#8211; Azure API version (very important!)<\/li><li>name: reza787878 &#8211; my App Service Plan name<\/li><li>location: [resourceGroup().location] &#8211; this is ARM function! It takes location from your resource group automatically<\/li><li>sku: F1 &#8211; this is FREE tier! Perfect for learning and testing<\/li><\/ul><h3 class=\"wp-block-heading\">3. Web App<\/h3><pre class=\"wp-block-code\"><code>{\n    \"type\": \"Microsoft.Web\/sites\",\n    \"apiVersion\": \"2022-03-01\",\n    \"name\": \"rezawebapp994848\",\n    \"location\": \"[resourceGroup().location]\",\n    \"properties\":{\n        \"name\":\"rezawebapp994848\",\n        \"serverFarmId\":\"[resourceId('Microsoft.Web\/serverfarms','reza787878')]\"\n    },\n    \"dependsOn\":[\n        \"[resourceId('Microsoft.Web\/serverfarms','reza787878')]\"\n    ]\n}<\/code><\/pre><p class=\"wp-block-paragraph\">This creates the actual Web App.<\/p><p class=\"wp-block-paragraph\">Key points:<\/p><ul class=\"wp-block-list\"><li>type: Microsoft.Web\/sites &#8211; this is Web App resource type<\/li><li>serverFarmId: This connects the Web App to the App Service Plan. I use resourceId() function to get the ID<\/li><li>dependsOn: This is VERY important! It tells Azure: &#8220;Create the App Service Plan FIRST, then create the Web App&#8221;<\/li><\/ul><h3 class=\"wp-block-heading\">The Magic of dependsOn<\/h3><p class=\"wp-block-paragraph\">When I first wrote this template, I forgot to add dependsOn. Azure tried to create the Web App before the App Service Plan existed. The deployment failed!<\/p><pre class=\"wp-block-code\"><code>\"dependsOn\":[\n    \"[resourceId('Microsoft.Web\/serverfarms','reza787878')]\"\n]<\/code><\/pre><p class=\"wp-block-paragraph\">This line saved me. It creates the correct order:<\/p><ol class=\"wp-block-list\"><li>First: App Service Plan<\/li><li>Second: Web App<\/li><\/ol><h3 class=\"wp-block-heading\">How I Deployed This Template<\/h3><p class=\"wp-block-paragraph\">I used Azure CLI in my terminal:<\/p><pre class=\"wp-block-code\"><code># Create resource group first\naz group create --name template-grp --location \"North Europe\"\n\n# Deploy the template\naz deployment group create \\\n  --resource-group template-grp \\\n  --template-file 01-AzureWebApp.json<\/code><\/pre><p class=\"wp-block-paragraph\">After 2-3 minutes, everything was ready! I checked the Azure portal and saw my Web App running.<\/p><h3 class=\"wp-block-heading\">What I Learned<\/h3><ol class=\"wp-block-list\"><li>ARM templates save time: I can deploy the same infrastructure again in 2 minutes<\/li><li>Location function is smart: Using [resourceGroup().location] means I don&#8217;t need to write location twice<\/li><li>Dependencies matter: Always use dependsOn when one resource needs another<\/li><li>F1 tier is free: Great for learning without spending money<\/li><li>resourceId() function: This connects resources together<\/li><\/ol><h3 class=\"wp-block-heading\">My Mistakes and How I Fixed Them<\/h3><p class=\"wp-block-paragraph\">Mistake 1: I used wrong API version first (2020-12-01) Fix: I checked Azure documentation and updated to 2022-03-01<\/p><p class=\"wp-block-paragraph\">Mistake 2: Name conflicts &#8211; Azure said &#8220;name already exists&#8221; Fix: I added numbers to make unique names like rezawebapp994848<\/p>","protected":false},"excerpt":{"rendered":"<p>Why I Started Learning ARM Templates Hello everyone! I&#8217;m Reza, a junior DevOps engineer. Today I want to share my first experience&hellip;<\/p>\n","protected":false},"author":2,"featured_media":97,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_rezaops_part":"1","_rezaops_linkedin_url":"https:\/\/www.linkedin.com\/pulse\/my-first-azure-arm-templates-deploying-web-apps-reza-chegini-jtjrc\/","footnotes":""},"categories":[50,10],"tags":[53,52,54,8,55],"series":[51],"class_list":["post-95","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-devops","tag-arm-templates","tag-azure","tag-azure-web-apps","tag-devops","tag-iac","series-azure-arm-templates"],"jetpack_featured_media_url":"https:\/\/rezachegini.com\/wp-content\/uploads\/2026\/10\/my-first-azure-arm-templates-cover.png","_links":{"self":[{"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/posts\/95","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=95"}],"version-history":[{"count":1,"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/posts\/95\/revisions"}],"predecessor-version":[{"id":96,"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/posts\/95\/revisions\/96"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/media\/97"}],"wp:attachment":[{"href":"https:\/\/rezachegini.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=95"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=95"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=95"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=95"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}