{"id":106,"date":"2026-01-30T12:00:00","date_gmt":"2026-01-30T12:00:00","guid":{"rendered":"https:\/\/rezachegini.com\/?p=106"},"modified":"2026-10-30T07:03:45","modified_gmt":"2026-10-30T07:03:45","slug":"dynamic-resource-creation-in-arm-templates-making-unique-names-automatically","status":"publish","type":"post","link":"https:\/\/rezachegini.com\/?p=106","title":{"rendered":"Dynamic Resource Creation in ARM Templates: Making Unique Names Automatically"},"content":{"rendered":"<p class=\"wp-block-paragraph\">Hello everyone! Today I want to share something that saved me a lot of time &#8211; dynamic resource creation in ARM templates.<\/p><p class=\"wp-block-paragraph\">Before, I had a problem. Every time I deployed my template, Azure said &#8220;name already exists&#8221;. I had to manually change names in my template every time. This was annoying!<\/p><p class=\"wp-block-paragraph\">Then I learned about ARM template functions like uniqueString() and concat(). Now Azure creates unique names automatically. Let me show you!<\/p><h3 class=\"wp-block-heading\">My Problem with Hardcoded Names<\/h3><p class=\"wp-block-paragraph\">Look at my old Web App template:<\/p><pre class=\"wp-block-code\"><code>{\n    \"type\": \"Microsoft.Web\/sites\",\n    \"name\": \"rezawebapp994848\",\n    \"properties\": {\n        \"name\": \"rezawebapp994848\"\n    }\n}<\/code><\/pre><p class=\"wp-block-paragraph\">The problem: rezawebapp994848 is hardcoded!<\/p><p class=\"wp-block-paragraph\">What happened when I deployed again?<\/p><p class=\"wp-block-paragraph\">Error: &#8220;The website name &#8216;rezawebapp994848&#8217; already exists&#8221;<\/p><p class=\"wp-block-paragraph\">What happened when my friend tried to use my template?<\/p><p class=\"wp-block-paragraph\">Error: &#8220;The website name &#8216;rezawebapp994848&#8217; already exists&#8221;<\/p><p class=\"wp-block-paragraph\">I needed unique names every time!<\/p><h3 class=\"wp-block-heading\">Solution: Use Variables and Functions<\/h3><p class=\"wp-block-paragraph\">Here&#8217;s my new template with dynamic names:<\/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        \"web-app-name\":\"[concat('webapp',uniqueString(resourceGroup().id))]\"\n    },\n    \"resources\": [\n        {\n            \"type\": \"Microsoft.Web\/serverfarms\",\n            \"apiVersion\": \"2022-03-01\",\n            \"name\": \"plan787878\",\n            \"location\": \"[resourceGroup().location]\",\n            \"sku\": {\n                \"name\":\"F1\",\n                \"capacity\":1\n            },\n            \"properties\":{\n                \"name\":\"plan787878\"\n            }\n        },\n        {\n            \"type\": \"Microsoft.Web\/sites\",\n            \"apiVersion\": \"2022-03-01\",\n            \"name\": \"[variables('web-app-name')]\",\n            \"location\": \"[resourceGroup().location]\",\n            \"properties\":{\n                \"name\":\"[variables('web-app-name')]\",\n                \"serverFarmId\":\"[resourceId('Microsoft.Web\/serverfarms','plan787878')]\"\n            },\n            \"dependsOn\":[\n                \"[resourceId('Microsoft.Web\/serverfarms','plan787878')]\"\n            ]\n        }\n    ],\n    \"outputs\": {}\n}<\/code><\/pre><p class=\"wp-block-paragraph\">Now look at the variables section:<\/p><pre class=\"wp-block-code\"><code>\"variables\": {\n    \"web-app-name\":\"[concat('webapp',uniqueString(resourceGroup().id))]\"\n}<\/code><\/pre><p class=\"wp-block-paragraph\">And how I use it in the resource:<\/p><pre class=\"wp-block-code\"><code>\"name\": \"[variables('web-app-name')]\"<\/code><\/pre><p class=\"wp-block-paragraph\">What does this do? Let me explain!<\/p><h3 class=\"wp-block-heading\">Understanding uniqueString() Function<\/h3><p class=\"wp-block-paragraph\">The uniqueString() function creates a unique hash from input.<\/p><pre class=\"wp-block-code\"><code>uniqueString(resourceGroup().id)<\/code><\/pre><p class=\"wp-block-paragraph\">This takes the resource group ID and creates a unique string from it.<\/p><p class=\"wp-block-paragraph\">Example:<\/p><ul class=\"wp-block-list\"><li>Resource Group ID: \/subscriptions\/abc123\/resourceGroups\/my-rg<\/li><li>uniqueString result: ghe7d4kj2p5a<\/li><\/ul><p class=\"wp-block-paragraph\">The result is always:<\/p><ul class=\"wp-block-list\"><li>13 characters long<\/li><li>Only lowercase letters and numbers<\/li><li>Same for same input (deterministic)<\/li><li>Different for different input<\/li><\/ul><p class=\"wp-block-paragraph\">So if I use resource group my-rg, I always get ghe7d4kj2p5a. If you use resource group your-rg, you get different string like k8j3h5m9n2p4.<\/p><p class=\"wp-block-paragraph\">This is perfect! Each person gets their own unique name.<\/p><h3 class=\"wp-block-heading\">Understanding concat() Function<\/h3><p class=\"wp-block-paragraph\">The concat() function joins strings together.<\/p><pre class=\"wp-block-code\"><code>concat('webapp', uniqueString(resourceGroup().id))<\/code><\/pre><p class=\"wp-block-paragraph\">This joins:<\/p><ul class=\"wp-block-list\"><li>webapp (my prefix)<\/li><li>ghe7d4kj2p5a (unique string)<\/li><\/ul><p class=\"wp-block-paragraph\">Result: webappghe7d4kj2p5a<\/p><p class=\"wp-block-paragraph\">Now every deployment gets unique name automatically!<\/p><h3 class=\"wp-block-heading\">Understanding Variables Section<\/h3><pre class=\"wp-block-code\"><code>\"variables\": {\n    \"web-app-name\":\"[concat('webapp',uniqueString(resourceGroup().id))]\"\n}<\/code><\/pre><p class=\"wp-block-paragraph\">Variables are like shortcuts. I define the name once in variables, then use it many times in resources.<\/p><p class=\"wp-block-paragraph\">To use a variable:<\/p><pre class=\"wp-block-code\"><code>\"name\": \"[variables('web-app-name')]\"<\/code><\/pre><p class=\"wp-block-paragraph\">Why use variables?<\/p><ol class=\"wp-block-list\"><li>Define once, use many times<\/li><li>Easy to change later<\/li><li>Makes template cleaner<\/li><li>No copy-paste errors<\/li><\/ol><h3 class=\"wp-block-heading\">Real Example: Web App with Linked SQL Template<\/h3><p class=\"wp-block-paragraph\">Now I want to make BOTH Web App and SQL Server names unique. Here&#8217;s my complete example:<\/p><p class=\"wp-block-paragraph\">Main template:<\/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        \"web-app-name\":\"[concat('webapp',uniqueString(resourceGroup().id))]\"\n    },\n    \"resources\": [\n        {\n            \"type\": \"Microsoft.Web\/serverfarms\",\n            \"apiVersion\": \"2022-03-01\",\n            \"name\": \"plan787878\",\n            \"location\": \"[resourceGroup().location]\",\n            \"sku\": {\n                \"name\":\"F1\",\n                \"capacity\":1\n            },\n            \"properties\":{\n                \"name\":\"plan787878\"\n            }\n        },\n        {\n            \"type\": \"Microsoft.Web\/sites\",\n            \"apiVersion\": \"2022-03-01\",\n            \"name\": \"[variables('web-app-name')]\",\n            \"location\": \"[resourceGroup().location]\",\n            \"properties\":{\n                \"name\":\"[variables('web-app-name')]\",\n                \"serverFarmId\":\"[resourceId('Microsoft.Web\/serverfarms','plan787878')]\"\n            },\n            \"dependsOn\":[\n                \"[resourceId('Microsoft.Web\/serverfarms','plan787878')]\"\n            ]\n        },\n        {\n            \"type\":\"Microsoft.Resources\/deployments\",\n            \"apiVersion\": \"2021-04-01\",\n            \"name\":\"LinkedTemplate\",\n            \"properties\": {\n                \"mode\": \"Incremental\",\n                \"templateLink\": {\n                    \"uri\": \"https:\/\/templatestore465656.blob.core.windows.net\/templates\/sqldatabase.json\",\n                    \"contentVersion\":\"1.0.0.0\"\n                },\n                \"parametersLink\": {\n                    \"uri\": \"https:\/\/templatestore465656.blob.core.windows.net\/templates\/sqldatabase-parameters.json\",\n                    \"contentVersion\":\"1.0.0.0\"\n                }\n            }\n        }\n    ],\n    \"outputs\": {\n        \"webappname\": {\n            \"type\": \"string\",\n            \"value\":\"[variables('web-app-name')]\"\n        },\n        \"sqlserverfqdn\": {\n            \"type\": \"string\",\n            \"value\":\"[reference('LinkedTemplate').outputs.sqlserverfqdn.value]\"\n        }\n    }\n}<\/code><\/pre><p class=\"wp-block-paragraph\">SQL template (linked):<\/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        \"SQLLogin\": {\n            \"type\":\"string\",\n            \"metadata\":{\n                \"description\":\"The administrator user name\"\n            }\n        },\n        \"SQLPassword\": {\n            \"type\":\"secureString\",\n            \"metadata\":{\n                \"description\":\"The administrator password\"\n            }\n        }\n    },\n    \"functions\": [],\n    \"variables\": {\n        \"sql-server-name\":\"[concat('server',uniqueString(resourceGroup().id))]\"\n    },\n    \"resources\": [\n        {\n            \"type\": \"Microsoft.Sql\/servers\",\n            \"apiVersion\": \"2022-02-01-preview\",\n            \"name\": \"[variables('sql-server-name')]\",\n            \"location\": \"[resourceGroup().location]\",\n            \"properties\":{\n                \"administratorLogin\": \"[parameters('SQLLogin')]\",\n                \"administratorLoginPassword\": \"[parameters('SQLPassword')]\"\n            }\n        },\n        {\n            \"type\": \"Microsoft.Sql\/servers\/databases\",\n            \"apiVersion\": \"2022-02-01-preview\",\n            \"name\": \"[format('{0}\/{1}',variables('sql-server-name'),'appdb')]\",\n            \"location\": \"[resourceGroup().location]\",\n            \"sku\":{\n                \"name\":\"Basic\",\n                \"tier\":\"Basic\"\n            },\n            \"properties\":{},\n            \"dependsOn\":[\n                \"[resourceId('Microsoft.Sql\/servers',variables('sql-server-name'))]\"\n            ]\n        }\n    ],\n    \"outputs\": {\n        \"sqlserverfqdn\": {\n            \"type\": \"string\",\n            \"value\":\"[reference(variables('sql-server-name')).fullyQualifiedDomainName]\"\n        }\n    }\n}<\/code><\/pre><p class=\"wp-block-paragraph\">Now both Web App and SQL Server get unique names automatically!<\/p><h3 class=\"wp-block-heading\">Understanding Outputs<\/h3><p class=\"wp-block-paragraph\">Look at the outputs section in my templates:<\/p><p class=\"wp-block-paragraph\">In main template:<\/p><pre class=\"wp-block-code\"><code>\"outputs\": {\n    \"webappname\": {\n        \"type\": \"string\",\n        \"value\":\"[variables('web-app-name')]\"\n    },\n    \"sqlserverfqdn\": {\n        \"type\": \"string\",\n        \"value\":\"[reference('LinkedTemplate').outputs.sqlserverfqdn.value]\"\n    }\n}<\/code><\/pre><p class=\"wp-block-paragraph\">In SQL template:<\/p><pre class=\"wp-block-code\"><code>\"outputs\": {\n    \"sqlserverfqdn\": {\n        \"type\": \"string\",\n        \"value\":\"[reference(variables('sql-server-name')).fullyQualifiedDomainName]\"\n    }\n}<\/code><\/pre><p class=\"wp-block-paragraph\">Outputs let you get information AFTER deployment.<\/p><p class=\"wp-block-paragraph\">After I deploy, Azure CLI shows me:<\/p><pre class=\"wp-block-code\"><code>{\n  \"outputs\": {\n    \"webappname\": {\n      \"type\": \"String\",\n      \"value\": \"webappghe7d4kj2p5a\"\n    },\n    \"sqlserverfqdn\": {\n      \"type\": \"String\",\n      \"value\": \"serverghe7d4kj2p5a.database.windows.net\"\n    }\n  }\n}<\/code><\/pre><p class=\"wp-block-paragraph\">Now I know:<\/p><ul class=\"wp-block-list\"><li>My Web App name: webappghe7d4kj2p5a<\/li><li>My SQL Server: serverghe7d4kj2p5a.database.windows.net<\/li><\/ul><p class=\"wp-block-paragraph\">I can use these in my CI\/CD pipeline!<\/p><h3 class=\"wp-block-heading\">Getting Outputs from Linked Templates<\/h3><p class=\"wp-block-paragraph\">This is the tricky part:<\/p><pre class=\"wp-block-code\"><code>\"value\":\"[reference('LinkedTemplate').outputs.sqlserverfqdn.value]\"<\/code><\/pre><p class=\"wp-block-paragraph\">Let me break it down:<\/p><ul class=\"wp-block-list\"><li>reference(&#8216;LinkedTemplate&#8217;) &#8211; Get the linked template deployment<\/li><li>.outputs &#8211; Get the outputs section<\/li><li>.sqlserverfqdn &#8211; Get the specific output<\/li><li>.value &#8211; Get the actual value<\/li><\/ul><p class=\"wp-block-paragraph\">So I can get data from linked template and pass it to main template outputs!<\/p><h3 class=\"wp-block-heading\">Using Outputs in Azure DevOps Pipeline<\/h3><p class=\"wp-block-paragraph\">Here&#8217;s how I use ARM template outputs in my Azure DevOps pipeline. This is from my actual pipeline file:<\/p><pre class=\"wp-block-code\"><code># ASP.NET Core (.NET Framework)\n# Build and test ASP.NET Core projects targeting the full .NET Framework.\n\ntrigger:\n- main\n\npool:\n  vmImage: 'windows-latest'\n\nresources:\n- repo: self\n\nvariables:\n  solution: '**\/*.sln'\n  buildPlatform: 'Any CPU'\n  buildConfiguration: 'Release'\n\nstages:\n- stage: Build\n  displayName: Build stage\n  jobs:\n  - job: Build\n    displayName: Build\n    steps:\n    - task: NuGetToolInstaller@1\n\n    - task: NuGetCommand@2\n      inputs:\n        restoreSolution: '$(solution)'\n\n    - task: DotNetCoreCLI@2\n      displayName: Build\n      inputs:\n        command: build\n        projects: '**\/*.csproj'\n        arguments: '--configuration $(buildConfiguration)'\n\n    - task: DotNetCoreCLI@2\n      inputs:\n        command: publish\n        publishWebProjects: True\n        arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'\n        zipAfterPublish: True\n\n    - task: PublishPipelineArtifact@1\n      inputs:\n        targetPath: '$(Build.ArtifactStagingDirectory)'\n        artifactName: 'sqlapp-artifact'\n\n    - task: PublishPipelineArtifact@1\n      inputs:\n        targetPath: '$(Build.SourcesDirectory)\/sqlapp\/Templates'\n        artifactName: 'template-artifact'\n\n- stage: Deploy\n  displayName: Deployment stage\n  jobs:\n  - job: Deploy\n    displayName: Deploy\n    steps:\n\n    - download: current\n      artifact: sqlapp-artifact\n\n    - download: current\n      artifact: template-artifact\n\n    - pwsh: |\n        Get-ChildItem -Path $(Pipeline.Workspace)\\*.* -Recurse -Force | Out-String -Width 180\n      errorActionPreference: continue\n      displayName: 'List content'\n      continueOnError: true<\/code><\/pre><pre class=\"wp-block-code\"><code>    - task: AzureResourceManagerTemplateDeployment@3\n      displayName: 'ARM Template deployment: Resource Group scope'\n      inputs:\n        azureResourceManagerConnection: 'Azure subscription 1 (6912d7a0-bc28-459a-9407-33bbba641c07)'\n        subscriptionId: '6912d7a0-bc28-459a-9407-33bbba641c07'\n        resourceGroupName: 'template-grp'\n        location: 'North Europe'\n        csmFile: '$(Pipeline.Workspace)\/template-artifact\/main.json'\n        action: 'Create Or Update Resource Group'\n        deploymentMode: 'Incremental'\n\n    - task: SqlAzureDacpacDeployment@1\n      displayName: 'Azure SQL InlineSqlTask'\n      inputs:\n        azureSubscription: 'Azure subscription 1 (6912d7a0-bc28-459a-9407-33bbba641c07)'\n        ServerName: sqlserver8000505.database.windows.net\n        DatabaseName: appdb\n        SqlUsername: sqlusr\n        SqlPassword: 'Azure@123'\n        deployType: InlineSqlTask\n        SqlInline: |\n          IF (NOT EXISTS (SELECT * \n                       FROM INFORMATION_SCHEMA.TABLES \n                       WHERE TABLE_SCHEMA = 'dbo' \n                       AND  TABLE_NAME = 'Products'))\n          BEGIN\n\n          CREATE TABLE Products\n          (\n           ProductID int,\n           ProductName varchar(1000),\n           Quantity int\n           )\n\n\n           INSERT INTO Products(ProductID,ProductName,Quantity) VALUES (1,'Mobile',100)\n\n           INSERT INTO Products(ProductID,ProductName,Quantity) VALUES (2,'Laptop',200)\n\n           INSERT INTO Products(ProductID,ProductName,Quantity) VALUES (3,'Tabs',300)\n\n           END\n        IpDetectionMethod: IPAddressRange\n        StartIpAddress: 0.0.0.0\n        EndIpAddress: 0.0.0.0\n        DeleteFirewallRule: false\n\n    - task: AzureRmWebAppDeployment@4\n      displayName: 'Azure App Service Deploy'\n      inputs:\n        azureSubscription: 'Azure subscription 1 (6912d7a0-bc28-459a-9407-33bbba641c07)'\n        WebAppName: newapp1094848\n        Package: '$(Pipeline.Workspace)\/sqlapp-artifact\/**\/*.zip'\n\n    - task: AzureAppServiceSettings@1\n      displayName: 'Azure App Service Settings: newapp1094848'\n      inputs:\n        azureSubscription: 'Azure subscription 1 (6912d7a0-bc28-459a-9407-33bbba641c07)'\n        appName: newapp1094848\n        resourceGroupName: 'template-grp'\n        connectionStrings: |\n          [\n            {\n              \"name\": \"SQLConnection\",\n              \"value\": \"Server=tcp:sqlserver8000505.database.windows.net,1433;Initial Catalog=appdb;Persist Security Info=False;User ID=sqlusr;Password=Azure@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;\",\n              \"type\": \"SQLAzure\",\n              \"slotSetting\": false\n            }\n          ]<\/code><\/pre><p class=\"wp-block-paragraph\">In my pipeline, I deploy the ARM template in the Deploy stage.<\/p><p class=\"wp-block-paragraph\">The key task is:<\/p><pre class=\"wp-block-code\"><code>- task: AzureResourceManagerTemplateDeployment@3\n  displayName: 'ARM Template deployment: Resource Group scope'\n  inputs:\n    azureResourceManagerConnection: 'Azure subscription 1 (6912d7a0-bc28-459a-9407-33bbba641c07)'\n    subscriptionId: '6912d7a0-bc28-459a-9407-33bbba641c07'\n    resourceGroupName: 'template-grp'\n    location: 'North Europe'\n    csmFile: '$(Pipeline.Workspace)\/template-artifact\/main.json'\n    action: 'Create Or Update Resource Group'\n    deploymentMode: 'Incremental'<\/code><\/pre><p class=\"wp-block-paragraph\">This task:<\/p><ol class=\"wp-block-list\"><li>Takes my main.json template from artifacts<\/li><li>Deploys it to template-grp resource group<\/li><li>Uses Incremental mode (safe!)<\/li><li>Creates Web App with unique name<\/li><li>Calls linked template for SQL Database<\/li><\/ol><p class=\"wp-block-paragraph\">After ARM deployment finishes, I run SQL script to create tables, then deploy my application code to the Web App.<\/p><p class=\"wp-block-paragraph\">The pipeline works end-to-end:<\/p><ol class=\"wp-block-list\"><li>Build stage &#8211; Build .NET application<\/li><li>Publish artifacts &#8211; Application code + ARM templates<\/li><li>Deploy stage &#8211; Deploy ARM templates<\/li><li>Create SQL tables with inline SQL script<\/li><li>Deploy application to Web App<\/li><li>Configure connection string<\/li><\/ol><h3 class=\"wp-block-heading\">More Useful Functions<\/h3><p class=\"wp-block-paragraph\">Let me show you other functions I use:<\/p><p class=\"wp-block-paragraph\">Using toLower():<\/p><pre class=\"wp-block-code\"><code>\"variables\": {\n    \"storage-name\":\"[toLower(concat('storage',uniqueString(resourceGroup().id)))]\"\n}<\/code><\/pre><p class=\"wp-block-paragraph\">This makes everything lowercase. Storage account names must be lowercase!<\/p><p class=\"wp-block-paragraph\">Using resourceGroup().location:<\/p><pre class=\"wp-block-code\"><code>\"location\": \"[resourceGroup().location]\"<\/code><\/pre><p class=\"wp-block-paragraph\">This uses the resource group location automatically. I don&#8217;t need to type &#8220;North Europe&#8221; everywhere!<\/p><p class=\"wp-block-paragraph\">Using multiple concat():<\/p><pre class=\"wp-block-code\"><code>\"variables\": {\n    \"vm-name\":\"[concat('vm-', parameters('environment'), '-', uniqueString(resourceGroup().id))]\"\n}<\/code><\/pre><p class=\"wp-block-paragraph\">If environment parameter is &#8220;dev&#8221;, result: vm-dev-ghe7d4kj2p5a<\/p><p class=\"wp-block-paragraph\">If environment parameter is &#8220;prod&#8221;, result: vm-prod-ghe7d4kj2p5a<\/p><h3 class=\"wp-block-heading\">My Mistakes and Fixes<\/h3><p class=\"wp-block-paragraph\">I forgot square brackets around function:<\/p><pre class=\"wp-block-code\"><code>\"name\": \"concat('webapp', uniqueString(resourceGroup().id))\"<\/code><\/pre><p class=\"wp-block-paragraph\">This doesn&#8217;t work! ARM treats it as plain text, not a function.<\/p><p class=\"wp-block-paragraph\">Fix: Add square brackets:<\/p><pre class=\"wp-block-code\"><code>\"name\": \"[concat('webapp', uniqueString(resourceGroup().id))]\"<\/code><\/pre><p class=\"wp-block-paragraph\">I used wrong variable name:<\/p><pre class=\"wp-block-code\"><code>\"variables\": {\n    \"webappname\": \"...\"\n}\n\n\/\/ Later in resource\n\"name\": \"[variables('web-app-name')]\"  \/\/ Different name!<\/code><\/pre><p class=\"wp-block-paragraph\">Error: &#8220;The template variable &#8216;web-app-name&#8217; is not found&#8221;<\/p><p class=\"wp-block-paragraph\">Fix: Use exact same name everywhere.<\/p><p class=\"wp-block-paragraph\">I forgot single quotes in concat:<\/p><pre class=\"wp-block-code\"><code>concat(webapp, uniqueString(resourceGroup().id))  \/\/ Wrong! Missing quotes<\/code><\/pre><p class=\"wp-block-paragraph\">Fix: Add quotes around string:<\/p><pre class=\"wp-block-code\"><code>concat('webapp', uniqueString(resourceGroup().id))  \/\/ Correct!<\/code><\/pre><p class=\"wp-block-paragraph\">I tried to use outputs before deployment finished:<\/p><p class=\"wp-block-paragraph\">In same template, I tried:<\/p><pre class=\"wp-block-code\"><code>\"resources\": [\n    {\n        \"name\": \"webapp\",\n        \"type\": \"Microsoft.Web\/sites\",\n        ...\n    },\n    {\n        \"name\": \"another-resource\",\n        \"properties\": {\n            \"value\": \"[reference('webapp').outputs.something]\"  \/\/ Wrong!\n        }\n    }\n]<\/code><\/pre><p class=\"wp-block-paragraph\">This doesn&#8217;t work! I can only use outputs AFTER deployment, not during deployment.<\/p><p class=\"wp-block-paragraph\">Fix: Use dependsOn and reference() correctly, or use outputs only in pipeline steps after deployment.<\/p><h3 class=\"wp-block-heading\">What I Learned<\/h3><ol class=\"wp-block-list\"><li>uniqueString() creates unique names &#8211; No more &#8220;name already exists&#8221; errors<\/li><li>concat() joins strings &#8211; Easy to add prefixes<\/li><li>Variables make code cleaner &#8211; Define once, use many times<\/li><li>Outputs give information &#8211; Use in CI\/CD pipelines<\/li><li>Square brackets are required &#8211; For all ARM functions<\/li><li>Linked templates can return outputs &#8211; Get data from child templates<\/li><li>Azure DevOps can use ARM outputs &#8211; Connect templates to pipelines<\/li><\/ol><h3 class=\"wp-block-heading\">Why This Matters<\/h3><p class=\"wp-block-paragraph\">Before dynamic names:<\/p><ul class=\"wp-block-list\"><li>Manual work every deployment<\/li><li>Name conflicts<\/li><li>Hard to share templates<\/li><li>Cannot automate<\/li><\/ul><p class=\"wp-block-paragraph\">After dynamic names:<\/p><ul class=\"wp-block-list\"><li>Deploy unlimited times<\/li><li>No conflicts<\/li><li>Easy to share<\/li><li>Full automation<\/li><\/ul>","protected":false},"excerpt":{"rendered":"<p>Hello everyone! Today I want to share something that saved me a lot of time &#8211; dynamic resource creation in ARM templates.&hellip;<\/p>\n","protected":false},"author":2,"featured_media":108,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_rezaops_part":"5","_rezaops_linkedin_url":"https:\/\/www.linkedin.com\/pulse\/dynamic-resource-creation-arm-templates-making-unique-reza-chegini-0gvre\/","footnotes":""},"categories":[50,10],"tags":[53,52,8,55],"series":[51],"class_list":["post-106","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-devops","tag-arm-templates","tag-azure","tag-devops","tag-iac","series-azure-arm-templates"],"jetpack_featured_media_url":"https:\/\/rezachegini.com\/wp-content\/uploads\/2026\/10\/dynamic-resource-creation-arm-cover.png","_links":{"self":[{"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/posts\/106","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=106"}],"version-history":[{"count":1,"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/posts\/106\/revisions"}],"predecessor-version":[{"id":107,"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/posts\/106\/revisions\/107"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=\/wp\/v2\/media\/108"}],"wp:attachment":[{"href":"https:\/\/rezachegini.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=106"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/rezachegini.com\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}