July 14, 2026

ARM Templates - Simply Explained

ARM Templates - Simply Explained
ARM Templates - Simply Explained
M365 FM Podcast
ARM Templates - Simply Explained
Apple Podcasts podcast player iconSpotify podcast player iconYoutube Music podcast player iconSpreaker podcast player iconPodchaser podcast player iconAmazon Music podcast player icon

If you've ever built Azure resources by clicking through the Azure Portal, you've probably wondered how large organizations deploy identical environments over and over again without making mistakes. The answer is ARM Templates. In this episode, we explain Azure Resource Manager Templates in plain English, exploring how they automate Azure deployments through Infrastructure as Code. Whether you're an Azure administrator, cloud engineer, developer, or simply beginning your cloud journey, this episode shows how ARM Templates help you build consistent, repeatable, and reliable Azure environments with confidence.

WHAT IS AZURE RESOURCE MANAGER?
Azure Resource Manager, commonly known as ARM, is the management layer behind every action performed in Microsoft Azure. Every deployment made through the Azure Portal, Azure CLI, PowerShell, REST APIs, or SDKs is processed by ARM. It authenticates users, validates permissions, manages dependencies, organizes resources into Resource Groups, and ensures Azure services are created in the correct order. ARM provides a consistent deployment engine regardless of which Azure management tool you choose.

INFRASTRUCTURE AS CODE EXPLAINED
ARM Templates are Microsoft's implementation of Infrastructure as Code (IaC). Instead of manually creating resources through the Azure Portal, administrators describe the desired infrastructure in a JSON file. Azure then reads this template and automatically provisions the required resources. This declarative approach focuses on the final desired state rather than the individual deployment steps, making cloud infrastructure repeatable, version-controlled, and fully automatable across development, testing, staging, and production environments.

THE BUILDING BLOCKS OF AN ARM TEMPLATE
Every ARM Template follows a structured layout consisting of key sections such as the schema definition, content version, parameters, variables, resources, and outputs. Parameters allow templates to be reused across different environments, variables simplify repetitive values, resources define the Azure services to deploy, and outputs return useful deployment information once provisioning is complete. Together, these building blocks create a flexible blueprint that Azure can interpret consistently every time it runs.

REUSABLE DEPLOYMENTS AT SCALE
One of the greatest strengths of ARM Templates is reusability. By combining parameters, variables, conditional deployments, copy loops, and linked templates, organizations can build modular infrastructure that scales across multiple projects and environments. Instead of maintaining separate deployment files for development, testing, and production, the same template can be reused with different parameter files, reducing maintenance while ensuring every deployment remains consistent and predictable.

DEPLOYING ARM TEMPLATES ARM
Templates can be deployed through multiple methods including the Azure Portal, Azure CLI, Azure PowerShell, Azure Cloud Shell, Azure DevOps, and GitHub Actions. Before deployment, Azure validates the template and offers What-If analysis to preview changes before any resources are created. Every deployment is also recorded in Azure's deployment history, providing valuable auditing, troubleshooting, and compliance capabilities throughout the infrastructure lifecycle.

ARM TEMPLATES VS BICEP
While ARM Templates remain the deployment engine behind Azure, Microsoft now recommends Bicep as the preferred authoring language. Bicep offers a cleaner, more readable syntax that automatically compiles into ARM JSON templates during deployment. Features such as automatic dependency handling, reusable modules, simplified expressions, and significantly reduced code make Bicep easier to write and maintain. Nevertheless, understanding ARM Templates remains essential because Azure deployments ultimately execute as ARM, and troubleshooting often requires understanding the underlying template structure.

AVOIDING COMMON MISTAKES
Like any Infrastructure as Code solution, ARM Templates require careful validation. Common issues include JSON syntax errors, incorrect parameter references, outdated API versions, and deployment validation failures. Fortunately, tools such as Visual Studio Code with the ARM Tools extension, deployment validation commands, and Azure deployment logs help identify problems before resources are provisioned, reducing failed deployments and improving reliability across production environments.

GETTING STARTED WITH ARM TEMPLATES
The easiest way to begin learning ARM Templates is by exporting an existing Azure deployment from the Azure Portal and studying its structure. From there, small modifications can be introduced before progressing toward parameterized templates stored in Git repositories and integrated into CI/CD pipelines. As confidence grows, administrators can gradually adopt Infrastructure as Code practices while building reusable deployment libraries for future Azure projects.

KEY TAKEAWAYS
ARM Templates are the foundation of automated Azure infrastructure. By replacing manual portal configuration with reusable Infrastructure as Code, organizations achieve consistent deployments, improved governance, better collaboration, and significantly reduced human error. Although Microsoft recommends Bicep for new projects, understanding ARM Templates remains an essential Azure skill because every Azure deployment ultimately relies on Azure Resource Manager behind the scenes.

Become a supporter of this podcast: https://www.spreaker.com/podcast/m365-fm-modern-work-security-and-productivity-with-microsoft-365--6704921/support.

🚀 Want to be part of m365.fm?

Then stop just listening… and start showing up.

👉 Connect with me on LinkedIn and let’s make something happen:

  • 🎙️ Be a podcast guest and share your story
  • 🎧 Host your own episode (yes, seriously)
  • 💡 Pitch topics the community actually wants to hear
  • 🌍 Build your personal brand in the Microsoft 365 space

This isn’t just a podcast — it’s a platform for people who take action.

🔥 Most people wait. The best ones don’t.

👉 Connect with me on LinkedIn and send me a message:
"I want in"

Let’s build something awesome 👊

1
00:00:00,000 --> 00:00:02,900
Welcome to another episode of Microsoft Knowledge Nuggets on M6-5.

2
00:00:02,900 --> 00:00:04,460
FM, I'm your host, Mirko Peters.

3
00:00:04,460 --> 00:00:06,900
Today's topic is one that almost everyone has heard of,

4
00:00:06,900 --> 00:00:09,540
but few really understand, arm templates.

5
00:00:09,540 --> 00:00:11,220
Let's start with a simple question.

6
00:00:11,220 --> 00:00:12,900
Are you still clicking through the Azure Portal

7
00:00:12,900 --> 00:00:14,140
to build your environments?

8
00:00:14,140 --> 00:00:16,260
We've all been there, but imagine you need to deploy

9
00:00:16,260 --> 00:00:18,940
the same setup 10 times, or worse,

10
00:00:18,940 --> 00:00:21,180
you have to rebuild your entire production environment

11
00:00:21,180 --> 00:00:23,620
from scratch after something goes wrong.

12
00:00:23,620 --> 00:00:26,380
Clicking through every blade and drop down by hand is slow,

13
00:00:26,380 --> 00:00:28,620
and it practically guarantees mistakes.

14
00:00:28,620 --> 00:00:31,660
It's like building a houseroom by room without any kind of plan.

15
00:00:31,660 --> 00:00:32,980
You'll end up with something that works,

16
00:00:32,980 --> 00:00:35,820
but you'll never replicate it exactly the same way twice.

17
00:00:35,820 --> 00:00:37,980
By the end of this episode, you'll understand

18
00:00:37,980 --> 00:00:39,820
what arm templates actually are,

19
00:00:39,820 --> 00:00:42,140
and how they replace all that manual clicking

20
00:00:42,140 --> 00:00:43,660
with a reusable blueprint.

21
00:00:43,660 --> 00:00:46,140
This is the foundation of modern Azure management,

22
00:00:46,140 --> 00:00:48,500
not just a nice to know concept.

23
00:00:48,500 --> 00:00:50,780
What exactly is as your resource manager?

24
00:00:50,780 --> 00:00:51,940
Let's break down the name.

25
00:00:51,940 --> 00:00:54,340
Azure Resource Manager, or Arm, for short,

26
00:00:54,340 --> 00:00:56,260
it sounds like something you install or download.

27
00:00:56,260 --> 00:00:57,060
It's not.

28
00:00:57,060 --> 00:00:59,380
Actually, Arm is the control layer behind every single action

29
00:00:59,380 --> 00:01:00,460
you take in Azure.

30
00:01:00,460 --> 00:01:02,860
Every time you click a button in the portal runner command

31
00:01:02,860 --> 00:01:05,300
in PowerShell, or the Azure CLI, or make a call

32
00:01:05,300 --> 00:01:08,460
through an SDK or a REST API, that request goes through Arm

33
00:01:08,460 --> 00:01:08,980
first.

34
00:01:08,980 --> 00:01:10,180
It authenticates you.

35
00:01:10,180 --> 00:01:11,740
It checks your authorization.

36
00:01:11,740 --> 00:01:13,940
Then it roots the request to the right Azure service

37
00:01:13,940 --> 00:01:14,860
to create the resource.

38
00:01:14,860 --> 00:01:17,260
Here's the thing, because Arm handles every request

39
00:01:17,260 --> 00:01:19,020
the same way, you get consistent results

40
00:01:19,020 --> 00:01:20,740
no matter which tool you use.

41
00:01:20,740 --> 00:01:23,460
Create a virtual machine through the portal or the CLI.

42
00:01:23,460 --> 00:01:24,340
It goes through Arm.

43
00:01:24,340 --> 00:01:25,260
The result is the same.

44
00:01:25,260 --> 00:01:26,420
No weird inconsistencies.

45
00:01:26,420 --> 00:01:28,220
That's powerful when you're working across a team

46
00:01:28,220 --> 00:01:30,220
where some people prefer the portal and others prefer

47
00:01:30,220 --> 00:01:31,220
the command line.

48
00:01:31,220 --> 00:01:33,300
Arm also manages resource groups.

49
00:01:33,300 --> 00:01:35,420
Think of a resource group as a folder,

50
00:01:35,420 --> 00:01:37,700
a logical container for all the related resources

51
00:01:37,700 --> 00:01:39,260
in a project or application.

52
00:01:39,260 --> 00:01:41,580
When you deploy a web app, you might have a virtual machine,

53
00:01:41,580 --> 00:01:44,300
a storage account, a virtual network, and a database.

54
00:01:44,300 --> 00:01:46,300
You put all of those in the same resource group,

55
00:01:46,300 --> 00:01:49,060
so you can manage them together, track costs together,

56
00:01:49,060 --> 00:01:50,860
and when you're done, delete the whole thing

57
00:01:50,860 --> 00:01:52,700
with one action instead of hunting down

58
00:01:52,700 --> 00:01:54,500
each individual resource.

59
00:01:54,500 --> 00:01:56,060
Arm handles dependencies too.

60
00:01:56,060 --> 00:01:57,940
You probably never think about it.

61
00:01:57,940 --> 00:01:59,740
If you're creating a virtual machine,

62
00:01:59,740 --> 00:02:01,620
it needs a network interface first.

63
00:02:01,620 --> 00:02:04,060
That network interface needs a virtual network.

64
00:02:04,060 --> 00:02:06,460
Arm figures out that order automatically.

65
00:02:06,460 --> 00:02:08,860
It knows which resources depend on others

66
00:02:08,860 --> 00:02:10,660
and creates them in the right sequence.

67
00:02:10,660 --> 00:02:12,780
You don't have to manage that complexity yourself.

68
00:02:12,780 --> 00:02:13,620
Arm just handles it.

69
00:02:13,620 --> 00:02:16,380
So Arm is the engine that makes all of this work,

70
00:02:16,380 --> 00:02:18,540
but it needs a language or format it can read.

71
00:02:18,540 --> 00:02:20,260
That's where Arm templates come in.

72
00:02:20,260 --> 00:02:22,420
Infrastructure as code, the big idea.

73
00:02:22,420 --> 00:02:24,380
Welcome back to M365.

74
00:02:24,380 --> 00:02:25,860
FM for another knowledge nugget.

75
00:02:25,860 --> 00:02:26,980
I'm Mirko Peters,

76
00:02:26,980 --> 00:02:30,180
and today we're breaking down the big idea behind Arm templates.

77
00:02:30,180 --> 00:02:33,140
These are the language Azure resource manager uses

78
00:02:33,140 --> 00:02:35,460
to understand what you want to deploy.

79
00:02:35,460 --> 00:02:37,300
Before we dive into the template structure,

80
00:02:37,300 --> 00:02:38,900
let's talk about the bigger idea.

81
00:02:38,900 --> 00:02:41,420
Infrastructure as code or IAC.

82
00:02:41,420 --> 00:02:44,260
Infrastructure as code is exactly what it sounds like.

83
00:02:44,260 --> 00:02:45,740
Instead of clicking around in a portal

84
00:02:45,740 --> 00:02:47,100
or typing one-off commands,

85
00:02:47,100 --> 00:02:48,940
you manage everything through code.

86
00:02:48,940 --> 00:02:52,580
You write down what you want, your servers, networks, storage,

87
00:02:52,580 --> 00:02:54,660
in a file, hand it to Azure,

88
00:02:54,660 --> 00:02:56,060
and it builds it all for you.

89
00:02:56,060 --> 00:02:57,940
Simple, right? That's the core concept.

90
00:02:57,940 --> 00:02:59,700
Now, there are two ways to approach this.

91
00:02:59,700 --> 00:03:01,580
The first is imperative, the old way

92
00:03:01,580 --> 00:03:03,540
where you give step-by-step instructions,

93
00:03:03,540 --> 00:03:06,660
first create this resource, then that one, then connect them.

94
00:03:06,660 --> 00:03:09,140
It's like telling a contractor exactly how to build a house,

95
00:03:09,140 --> 00:03:11,180
pour the foundation here, frame the walls there,

96
00:03:11,180 --> 00:03:12,620
add the roof last.

97
00:03:12,620 --> 00:03:15,860
Miss a step or do them in the wrong order and things break.

98
00:03:15,860 --> 00:03:17,460
The second approach is declarative,

99
00:03:17,460 --> 00:03:19,140
and that's what Arm templates use.

100
00:03:19,140 --> 00:03:21,140
Instead of telling Azure how to build something,

101
00:03:21,140 --> 00:03:23,900
you just describe what you want the end result to look like.

102
00:03:23,900 --> 00:03:25,460
You hand over the blueprint and say,

103
00:03:25,460 --> 00:03:27,420
"I want a virtual machine with this much memory

104
00:03:27,420 --> 00:03:30,140
connected to this network with this storage attached."

105
00:03:30,140 --> 00:03:32,060
Then, as your figures out the rest,

106
00:03:32,060 --> 00:03:34,500
the order, the dependencies, the configuration,

107
00:03:34,500 --> 00:03:36,540
while you just describe the final state.

108
00:03:36,540 --> 00:03:39,420
And these benefits are worth talking about, first repeatability.

109
00:03:39,420 --> 00:03:42,060
You can deploy the exact same environment 100 times

110
00:03:42,060 --> 00:03:44,300
and it will be identical every single time.

111
00:03:44,300 --> 00:03:47,780
No variation, no well-it-worked in dev surprises.

112
00:03:47,780 --> 00:03:49,180
Then, there's version control.

113
00:03:49,180 --> 00:03:50,940
Your infrastructure becomes a text file,

114
00:03:50,940 --> 00:03:52,300
you can check into Git,

115
00:03:52,300 --> 00:03:54,780
track every change and roll back if something goes wrong.

116
00:03:54,780 --> 00:03:56,180
Automation comes next.

117
00:03:56,180 --> 00:03:58,660
You can plug these templates into a CI/CD pipeline

118
00:03:58,660 --> 00:04:00,700
and have deployments happen automatically.

119
00:04:00,700 --> 00:04:03,580
And finally, your template becomes living documentation.

120
00:04:03,580 --> 00:04:04,940
Anyone on your team can look at it

121
00:04:04,940 --> 00:04:06,860
and see exactly what resources exist

122
00:04:06,860 --> 00:04:08,340
and how they're configured.

123
00:04:08,340 --> 00:04:10,460
Here's the thing, Arm templates are idempotent.

124
00:04:10,460 --> 00:04:12,100
That's a fancy word meaning you can deploy

125
00:04:12,100 --> 00:04:14,380
the same template 100 times and get the same result.

126
00:04:14,380 --> 00:04:16,500
If the resources already exist, Arm makes sure

127
00:04:16,500 --> 00:04:17,500
they match the template.

128
00:04:17,500 --> 00:04:19,180
If they don't exist, it creates them.

129
00:04:19,180 --> 00:04:21,820
If something drifted out of configuration, it fixes it.

130
00:04:21,820 --> 00:04:23,180
Same result every single time.

131
00:04:23,180 --> 00:04:24,500
So that's the big idea.

132
00:04:24,500 --> 00:04:27,460
Now let's actually look at what one of these templates looks like.

133
00:04:27,460 --> 00:04:29,100
The anatomy of an Arm template.

134
00:04:29,100 --> 00:04:31,140
Every Arm template follows a standard structure

135
00:04:31,140 --> 00:04:32,420
with six main sections.

136
00:04:32,420 --> 00:04:33,780
Think of it like a recipe.

137
00:04:33,780 --> 00:04:35,180
You have your ingredients, your prep work,

138
00:04:35,180 --> 00:04:37,940
your cooking instructions, and finally the finished dish.

139
00:04:37,940 --> 00:04:39,380
Let's walk through each one.

140
00:04:39,380 --> 00:04:41,420
Schema, this is the first line of the template.

141
00:04:41,420 --> 00:04:44,300
It points to the JSON schema file that tells Azure

142
00:04:44,300 --> 00:04:46,900
what version of the template format you're using.

143
00:04:46,900 --> 00:04:47,980
You don't need to memorize it.

144
00:04:47,980 --> 00:04:50,100
Just copy the URL from Microsoft's documentation

145
00:04:50,100 --> 00:04:51,820
and paste it in as you are using it

146
00:04:51,820 --> 00:04:53,500
to validate your template structure.

147
00:04:53,500 --> 00:04:54,380
Content version.

148
00:04:54,380 --> 00:04:56,460
This is your own version number for the template.

149
00:04:56,460 --> 00:04:59,540
Start with 1.0.0.0 on zero and increment it

150
00:04:59,540 --> 00:05:00,820
whenever you make changes.

151
00:05:00,820 --> 00:05:03,140
It's useful when you're managing multiple versions

152
00:05:03,140 --> 00:05:06,100
of the same template across environments.

153
00:05:06,100 --> 00:05:08,940
Parameters, these are the inputs to your template.

154
00:05:08,940 --> 00:05:10,900
The values you provide when you deploy.

155
00:05:10,900 --> 00:05:13,940
Think of them as the ingredients you can swap out each time.

156
00:05:13,940 --> 00:05:16,460
You might have a parameter for the virtual machine size,

157
00:05:16,460 --> 00:05:18,060
another for the admin username,

158
00:05:18,060 --> 00:05:19,820
and another for the location.

159
00:05:19,820 --> 00:05:21,620
Parameters make your template flexible.

160
00:05:21,620 --> 00:05:23,060
You can use the exact same template

161
00:05:23,060 --> 00:05:25,300
to deploy a small, cheap VM for development

162
00:05:25,300 --> 00:05:27,300
and a large, powerful one for production.

163
00:05:27,300 --> 00:05:29,660
Just change the parameter values, variables.

164
00:05:29,660 --> 00:05:32,020
These are values you define within the template itself.

165
00:05:32,020 --> 00:05:33,340
They're not inputs from the user.

166
00:05:33,340 --> 00:05:36,500
They're more like prep work, constructing naming conventions,

167
00:05:36,500 --> 00:05:38,340
combining strings, or calculating values

168
00:05:38,340 --> 00:05:40,300
that you'll reuse throughout the template.

169
00:05:40,300 --> 00:05:42,020
For example, you might define a variable

170
00:05:42,020 --> 00:05:44,220
that builds a resource name by combining a prefix

171
00:05:44,220 --> 00:05:47,180
and a parameter so you don't have to repeat that logic everywhere.

172
00:05:47,180 --> 00:05:49,460
Resources, this is the heart of the template.

173
00:05:49,460 --> 00:05:51,660
It's where you define the actual Azure resources

174
00:05:51,660 --> 00:05:53,140
you want to create or update.

175
00:05:53,140 --> 00:05:55,060
Virtual machines, storage accounts,

176
00:05:55,060 --> 00:05:57,660
virtual networks, databases, whatever you need.

177
00:05:57,660 --> 00:05:59,660
Each resource has a type like Microsoft.

178
00:05:59,660 --> 00:06:02,060
Compute virtual machines, an API version,

179
00:06:02,060 --> 00:06:04,620
a name, a location, and configuration properties.

180
00:06:04,620 --> 00:06:05,820
This section can get long,

181
00:06:05,820 --> 00:06:08,500
but it's just a list of everything you want Azure to build.

182
00:06:08,500 --> 00:06:09,500
Outputs.

183
00:06:09,500 --> 00:06:10,940
After the deployment finishes,

184
00:06:10,940 --> 00:06:13,220
outputs return useful information back to you.

185
00:06:13,220 --> 00:06:15,660
Like the public IP address of a new VM,

186
00:06:15,660 --> 00:06:17,500
a connection string for a database,

187
00:06:17,500 --> 00:06:20,420
or a resource ID you need for another tool.

188
00:06:20,420 --> 00:06:22,660
It's like the finished dish being presented to you.

189
00:06:22,660 --> 00:06:24,300
Here's the thing, at minimum,

190
00:06:24,300 --> 00:06:27,740
you only need three of these, schema, content version, and resources.

191
00:06:27,740 --> 00:06:29,940
Parameters, variables, and outputs are optional,

192
00:06:29,940 --> 00:06:31,140
but incredibly useful.

193
00:06:31,140 --> 00:06:32,980
Most real-world templates use all six.

194
00:06:32,980 --> 00:06:34,460
Let me show you the basic skeleton.

195
00:06:34,460 --> 00:06:37,380
At the top is the schema property pointing to the ARM schema.

196
00:06:37,380 --> 00:06:40,460
Then content version set to 1.0.0.0.10.

197
00:06:40,460 --> 00:06:42,300
Then an empty parameter section,

198
00:06:42,300 --> 00:06:43,780
an empty variable section,

199
00:06:43,780 --> 00:06:45,940
the resources array with your actual resources,

200
00:06:45,940 --> 00:06:47,820
and finally an output section.

201
00:06:47,820 --> 00:06:50,740
Every ARM template you'll ever see builds on this foundation.

202
00:06:50,740 --> 00:06:52,620
Now, once you understand the structure,

203
00:06:52,620 --> 00:06:53,700
the next question is,

204
00:06:53,700 --> 00:06:55,220
how to make these templates work

205
00:06:55,220 --> 00:06:56,740
across different environments

206
00:06:56,740 --> 00:06:58,980
without rewriting them every time.

207
00:06:58,980 --> 00:07:00,660
Making templates reusable,

208
00:07:00,660 --> 00:07:02,740
the real power of ARM templates

209
00:07:02,740 --> 00:07:04,380
isn't just automating one deployment.

210
00:07:04,380 --> 00:07:05,660
It's using the same template

211
00:07:05,660 --> 00:07:07,660
for development, testing, staging, and production

212
00:07:07,660 --> 00:07:08,780
with minimal changes.

213
00:07:08,780 --> 00:07:11,540
That's reusability, and it's built into the template design.

214
00:07:11,540 --> 00:07:13,660
Parameterization is your primary tool.

215
00:07:13,660 --> 00:07:16,020
Instead of hard-coding values like the VM size

216
00:07:16,020 --> 00:07:17,380
or the storage account name,

217
00:07:17,380 --> 00:07:18,860
you define them as parameters.

218
00:07:18,860 --> 00:07:19,820
When you deploy,

219
00:07:19,820 --> 00:07:21,500
you provide a separate parameter file

220
00:07:21,500 --> 00:07:24,060
that contains the values for that specific environment.

221
00:07:24,060 --> 00:07:26,700
Your development parameter file might set the VM size

222
00:07:26,700 --> 00:07:28,020
to standard B2s,

223
00:07:28,020 --> 00:07:31,220
while your production file sets it to standard D8-3.

224
00:07:31,220 --> 00:07:32,660
The template stays the same.

225
00:07:32,660 --> 00:07:34,220
The parameter files change.

226
00:07:34,220 --> 00:07:36,180
Variables help you keep the template clean.

227
00:07:36,180 --> 00:07:39,060
Instead of repeating the same naming pattern in 50 places,

228
00:07:39,060 --> 00:07:40,580
define it once as a variable.

229
00:07:40,580 --> 00:07:42,780
If you need to change the naming convention later,

230
00:07:42,780 --> 00:07:44,260
you change it in one spot.

231
00:07:44,260 --> 00:07:46,180
Variables can also use template functions

232
00:07:46,180 --> 00:07:48,700
to combine strings, pick values from parameters,

233
00:07:48,700 --> 00:07:50,380
or do simple calculations.

234
00:07:50,380 --> 00:07:52,860
Conditions let you include or exclude resources

235
00:07:52,860 --> 00:07:54,020
based on a parameter.

236
00:07:54,020 --> 00:07:56,620
For example, you might want to deploy a jump box VM

237
00:07:56,620 --> 00:07:58,020
only in production, not in dev.

238
00:07:58,020 --> 00:08:00,620
You add a condition that checks an environment parameter

239
00:08:00,620 --> 00:08:02,180
and as you are skipped that resource,

240
00:08:02,180 --> 00:08:03,460
when the condition is false.

241
00:08:03,460 --> 00:08:05,180
One template, multiple scenarios.

242
00:08:05,180 --> 00:08:07,420
Copy loops let you deploy multiple instances

243
00:08:07,420 --> 00:08:10,340
of a resource without writing them all out individually.

244
00:08:10,340 --> 00:08:12,940
Need five storage accounts with the same configuration?

245
00:08:12,940 --> 00:08:14,900
Use a copy loop that iterates from one to five

246
00:08:14,900 --> 00:08:15,740
and creates each one.

247
00:08:15,740 --> 00:08:17,980
It's like a for loop for your infrastructure.

248
00:08:17,980 --> 00:08:19,980
Linked templates are for modularity.

249
00:08:19,980 --> 00:08:22,300
Instead of one massive template with everything,

250
00:08:22,300 --> 00:08:24,140
you break it into smaller pieces.

251
00:08:24,140 --> 00:08:27,060
One for networking, one for compute, one for storage,

252
00:08:27,060 --> 00:08:29,500
and link them together from a main template.

253
00:08:29,500 --> 00:08:31,220
This makes each piece easier to manage,

254
00:08:31,220 --> 00:08:32,980
test and reuse independently.

255
00:08:32,980 --> 00:08:35,900
You can have a networking team maintain the network template

256
00:08:35,900 --> 00:08:37,980
and a compute team maintain the VM template

257
00:08:37,980 --> 00:08:40,100
all composing together into a full deployment.

258
00:08:40,100 --> 00:08:41,820
The best practice is to treat your templates

259
00:08:41,820 --> 00:08:44,060
like application code, store them in Git,

260
00:08:44,060 --> 00:08:47,260
version them, and integrate them into a CI/CD pipeline.

261
00:08:47,260 --> 00:08:48,700
Every time someone pushes a change,

262
00:08:48,700 --> 00:08:50,460
the pipeline validates the template,

263
00:08:50,460 --> 00:08:52,860
runs a what-if operation to preview changes

264
00:08:52,860 --> 00:08:54,740
and then deploys it automatically.

265
00:08:54,740 --> 00:08:56,820
No manual steps, no forgotten updates.

266
00:08:56,820 --> 00:08:58,420
So now you know what a template looks like

267
00:08:58,420 --> 00:08:59,900
and how to make it reusable.

268
00:08:59,900 --> 00:09:02,660
The next piece is how you actually get Azure to run it,

269
00:09:02,660 --> 00:09:03,940
how deployment works.

270
00:09:03,940 --> 00:09:06,460
You've written your template, defined your parameters,

271
00:09:06,460 --> 00:09:09,180
set up your variables and mapped out your resources.

272
00:09:09,180 --> 00:09:11,180
Now how do you actually hand this to Azure

273
00:09:11,180 --> 00:09:12,820
and get it to build everything?

274
00:09:12,820 --> 00:09:14,700
You have three main options and which one you pick

275
00:09:14,700 --> 00:09:16,260
depends on what you're trying to do.

276
00:09:16,260 --> 00:09:18,660
The Azure portal is the simplest way to get started.

277
00:09:18,660 --> 00:09:20,420
You upload your JSON file directly,

278
00:09:20,420 --> 00:09:22,940
fill in the parameter values in a clean web form

279
00:09:22,940 --> 00:09:24,100
and click deploy.

280
00:09:24,100 --> 00:09:26,540
It's great for learning, testing, or one-off deployments

281
00:09:26,540 --> 00:09:27,780
where you don't need automation.

282
00:09:27,780 --> 00:09:29,300
You see a visual progress bar,

283
00:09:29,300 --> 00:09:30,980
watch each resource being created,

284
00:09:30,980 --> 00:09:32,780
and if something fails, the error messages

285
00:09:32,780 --> 00:09:33,940
are right there in the portal.

286
00:09:33,940 --> 00:09:36,300
But the portal isn't where ARM templates really shine.

287
00:09:36,300 --> 00:09:38,980
The real power shows up when you move to the command line.

288
00:09:38,980 --> 00:09:41,940
Azure CLI and PowerShell let you script your deployments

289
00:09:41,940 --> 00:09:44,020
and integrate them into CI/CD pipelines

290
00:09:44,020 --> 00:09:46,140
like Azure DevOps or GitHub actions.

291
00:09:46,140 --> 00:09:48,220
Every time you push a change to your template,

292
00:09:48,220 --> 00:09:50,700
the pipeline can automatically validate it, deploy it,

293
00:09:50,700 --> 00:09:51,780
and tell you if something broke.

294
00:09:51,780 --> 00:09:54,220
No manual steps, no one forgetting to click the right button.

295
00:09:54,220 --> 00:09:56,420
You don't even need to install anything to try this.

296
00:09:56,420 --> 00:09:58,460
Azure Cloud Shell is a browser-based terminal

297
00:09:58,460 --> 00:10:01,700
that comes with both Azure CLI and PowerShell pre-installed.

298
00:10:01,700 --> 00:10:04,300
You're already logged in so you can upload your template file,

299
00:10:04,300 --> 00:10:06,620
run a deployment command, and see the results.

300
00:10:06,620 --> 00:10:07,860
All from your browser.

301
00:10:07,860 --> 00:10:09,340
It's a great tool for experimenting

302
00:10:09,340 --> 00:10:11,180
without setting up a local environment.

303
00:10:11,180 --> 00:10:14,020
Before Azure creates any resources, it validates your template.

304
00:10:14,020 --> 00:10:16,060
It checks for syntax errors, missing properties,

305
00:10:16,060 --> 00:10:17,820
and incorrect parameter references.

306
00:10:17,820 --> 00:10:20,260
If something's wrong, it tells you before a single resource

307
00:10:20,260 --> 00:10:23,620
is created, saving you from those frustrating half-failed deployments

308
00:10:23,620 --> 00:10:26,260
where some resources got created and others didn't.

309
00:10:26,260 --> 00:10:29,340
Azure also has a feature called the What If Operation.

310
00:10:29,340 --> 00:10:31,660
You run it before deploying, and it shows you exactly

311
00:10:31,660 --> 00:10:34,740
what will change, which resources will be created, modified,

312
00:10:34,740 --> 00:10:37,300
or deleted, like a dry run that shows the impact

313
00:10:37,300 --> 00:10:39,500
before anything actually happens.

314
00:10:39,500 --> 00:10:41,940
Once your deployment is done, Azure keeps a record.

315
00:10:41,940 --> 00:10:44,020
Every deployment is stored in the resource groups

316
00:10:44,020 --> 00:10:47,260
deployment history, so you can go back and see who deployed what when

317
00:10:47,260 --> 00:10:48,820
and what the template looked like.

318
00:10:48,820 --> 00:10:51,260
It's an audit trail for your infrastructure.

319
00:10:51,260 --> 00:10:53,340
Valuable for troubleshooting and compliance,

320
00:10:53,340 --> 00:10:55,620
but here's the thing, ARM templates are powerful,

321
00:10:55,620 --> 00:10:57,060
but Jason can be hard to read.

322
00:10:57,060 --> 00:11:00,140
All those brackets and curly braces make it verbose fast.

323
00:11:00,140 --> 00:11:03,820
And that's exactly why Microsoft created something better.

324
00:11:03,820 --> 00:11:05,140
The bicep evolution.

325
00:11:05,140 --> 00:11:06,700
So what exactly is bicep?

326
00:11:06,700 --> 00:11:08,060
And why should you care?

327
00:11:08,060 --> 00:11:09,660
Let's start with the old way.

328
00:11:09,660 --> 00:11:12,700
ARM templates have been around for years, and they're reliable.

329
00:11:12,700 --> 00:11:15,300
They power thousands of Azure deployments every day.

330
00:11:15,300 --> 00:11:16,140
But here's the problem.

331
00:11:16,140 --> 00:11:18,620
The Jason syntax is incredibly verbose.

332
00:11:18,620 --> 00:11:20,420
If you've ever opened a large ARM template,

333
00:11:20,420 --> 00:11:21,700
you know exactly what I mean.

334
00:11:21,700 --> 00:11:23,820
Pages of nested brackets and function calls

335
00:11:23,820 --> 00:11:25,420
that make your eyes glaze over.

336
00:11:25,420 --> 00:11:27,180
Microsoft looked at this mess and decided

337
00:11:27,180 --> 00:11:28,740
to build something better.

338
00:11:28,740 --> 00:11:30,380
Bicep is a new language.

339
00:11:30,380 --> 00:11:33,020
Technically speaking, it's a domain-specific language,

340
00:11:33,020 --> 00:11:35,900
designed specifically for deploying Azure resources.

341
00:11:35,900 --> 00:11:38,780
The big idea here is that bicep doesn't replace ARM.

342
00:11:38,780 --> 00:11:40,540
It compiles to ARM Jason.

343
00:11:40,540 --> 00:11:42,500
You write bicep and behind the scenes,

344
00:11:42,500 --> 00:11:44,620
it gets converted into a standard ARM template.

345
00:11:44,620 --> 00:11:46,980
So you get all the power and reliability of ARM,

346
00:11:46,980 --> 00:11:49,260
but with a writing experience that's much cleaner.

347
00:11:49,260 --> 00:11:50,860
What does that actually look like in practice?

348
00:11:50,860 --> 00:11:52,780
bicep cuts the code down dramatically.

349
00:11:52,780 --> 00:11:54,620
A template that needs 50 lines of Jason

350
00:11:54,620 --> 00:11:57,060
can often be written in just 15 lines of bicep.

351
00:11:57,060 --> 00:11:58,980
It supports comments with a hash mark,

352
00:11:58,980 --> 00:12:01,060
uses string interpolation instead of those ugly

353
00:12:01,060 --> 00:12:04,260
concat functions, and the syntax is clean and straightforward.

354
00:12:04,260 --> 00:12:05,900
No more hunting for missing brackets.

355
00:12:05,900 --> 00:12:08,060
bicep also has first class modules.

356
00:12:08,060 --> 00:12:09,860
In ARM templates, reusing components

357
00:12:09,860 --> 00:12:11,180
meant dealing with linked templates

358
00:12:11,180 --> 00:12:13,980
and nested deployments, doable but complex.

359
00:12:13,980 --> 00:12:15,500
bicep makes it simple.

360
00:12:15,500 --> 00:12:17,580
You create a module for a virtual network,

361
00:12:17,580 --> 00:12:20,260
another for a virtual machine, another for a database,

362
00:12:20,260 --> 00:12:22,300
and then compose them together like building blocks.

363
00:12:22,300 --> 00:12:25,340
It's modular, reusable, and easy to understand.

364
00:12:25,340 --> 00:12:28,300
Another big improvement is automatic dependency inference.

365
00:12:28,300 --> 00:12:30,420
In ARM templates, you had to explicitly declare

366
00:12:30,420 --> 00:12:32,340
depends on for every relationship.

367
00:12:32,340 --> 00:12:34,340
Miss one, and your deployment might fail

368
00:12:34,340 --> 00:12:36,740
because resources were created in the wrong order.

369
00:12:36,740 --> 00:12:38,460
bicep looks at your code and figures out

370
00:12:38,460 --> 00:12:40,060
the dependencies on its own.

371
00:12:40,060 --> 00:12:41,660
One less thing to worry about.

372
00:12:41,660 --> 00:12:43,980
Microsoft now recommends bicep for new deployments.

373
00:12:43,980 --> 00:12:46,700
It's fully production ready, covered by support plans,

374
00:12:46,700 --> 00:12:49,100
and has feature parity with ARM templates.

375
00:12:49,100 --> 00:12:50,740
If you're starting something new today,

376
00:12:50,740 --> 00:12:54,020
bicep is the way to go, but here's why ARM templates still matter.

377
00:12:54,020 --> 00:12:55,940
bicep compiles to ARM Jason,

378
00:12:55,940 --> 00:12:57,980
so when something goes wrong during deployment,

379
00:12:57,980 --> 00:13:01,060
the error messages you see are ARM error messages.

380
00:13:01,060 --> 00:13:02,940
When you look at the deployment history in the portal,

381
00:13:02,940 --> 00:13:05,140
you see the ARM template that was deployed.

382
00:13:05,140 --> 00:13:07,380
Understanding ARM, the structure, functions,

383
00:13:07,380 --> 00:13:09,740
and resource definitions helps you troubleshoot

384
00:13:09,740 --> 00:13:11,020
when things go wrong.

385
00:13:11,020 --> 00:13:13,860
bicep is the authoring tool, ARM is the engine.

386
00:13:13,860 --> 00:13:16,020
You need to understand both, so where do you start

387
00:13:16,020 --> 00:13:18,660
if you're completely new to all of this?

388
00:13:18,660 --> 00:13:20,340
Common mistakes and how to avoid them.

389
00:13:20,340 --> 00:13:21,580
Let me save you some headaches.

390
00:13:21,580 --> 00:13:23,740
The most common mistake people make with ARM templates

391
00:13:23,740 --> 00:13:26,100
comes down to simple Jason syntax,

392
00:13:26,100 --> 00:13:27,820
missing a comma at the end of a line,

393
00:13:27,820 --> 00:13:29,020
forgetting a closing bracket,

394
00:13:29,020 --> 00:13:31,100
or putting a quote mark in the wrong place.

395
00:13:31,100 --> 00:13:33,220
These tiny errors can take forever to find

396
00:13:33,220 --> 00:13:35,300
when you're staring at a wall of Jason.

397
00:13:35,300 --> 00:13:36,420
The fix is easy.

398
00:13:36,420 --> 00:13:38,780
Use VS code with the ARM tools extension.

399
00:13:38,780 --> 00:13:40,460
It highlights syntax errors in real time,

400
00:13:40,460 --> 00:13:43,260
so you catch them before you even try to deploy.

401
00:13:43,260 --> 00:13:46,420
Next up, typos in parameter names or variable references.

402
00:13:46,420 --> 00:13:48,700
You define a parameter called VM size,

403
00:13:48,700 --> 00:13:49,940
but somewhere in your template,

404
00:13:49,940 --> 00:13:54,220
you reference parameters VM size, lowercase s instead of capital S.

405
00:13:54,220 --> 00:13:56,340
It won't match and the deployment will fail.

406
00:13:56,340 --> 00:13:59,460
The error message might not be crystal clear about why.

407
00:13:59,460 --> 00:14:01,420
The fix stay consistent with your naming

408
00:14:01,420 --> 00:14:04,100
and let the VS code extension catch mismatches.

409
00:14:04,100 --> 00:14:06,140
Then there's API version confusion.

410
00:14:06,140 --> 00:14:08,660
Every Azure resource type has different API versions

411
00:14:08,660 --> 00:14:09,940
and they change over time.

412
00:14:09,940 --> 00:14:11,260
If you're using an old version,

413
00:14:11,260 --> 00:14:12,860
you might be missing required properties.

414
00:14:12,860 --> 00:14:14,300
If you're using one that's too new,

415
00:14:14,300 --> 00:14:16,460
it might not be available in your region.

416
00:14:16,460 --> 00:14:17,300
The fix.

417
00:14:17,300 --> 00:14:19,900
Check the documentation for the resource type you're deploying

418
00:14:19,900 --> 00:14:21,900
and use the latest stable API version

419
00:14:21,900 --> 00:14:22,860
before you deploy anything,

420
00:14:22,860 --> 00:14:25,500
there's a command called AZ deployment group validate.

421
00:14:25,500 --> 00:14:27,860
This command checks your template for syntax errors,

422
00:14:27,860 --> 00:14:30,500
missing properties and invalid references

423
00:14:30,500 --> 00:14:32,260
without actually creating any resources.

424
00:14:32,260 --> 00:14:35,220
Think of it as a safety net that catches most common mistakes.

425
00:14:35,220 --> 00:14:37,100
And if a deployment does fail, don't panic.

426
00:14:37,100 --> 00:14:39,420
Go to the deployment operations in the portal.

427
00:14:39,420 --> 00:14:41,580
Each operation shows you exactly what happened

428
00:14:41,580 --> 00:14:43,220
with error codes and messages.

429
00:14:43,220 --> 00:14:45,940
Nine times out of 10, the error message tells you exactly

430
00:14:45,940 --> 00:14:46,740
what's wrong.

431
00:14:46,740 --> 00:14:47,620
You just need to read it.

432
00:14:47,620 --> 00:14:50,700
So here's the one thing I want you to remember above all else.

433
00:14:50,700 --> 00:14:51,860
So that's the system.

434
00:14:51,860 --> 00:14:54,540
Arm templates take Azure from a manual clicking exercise

435
00:14:54,540 --> 00:14:56,380
to something you can repeat and rely on.

436
00:14:56,380 --> 00:14:58,420
Starts more, export a template from the portal,

437
00:14:58,420 --> 00:14:59,940
study how it's built, then tweak it.

438
00:14:59,940 --> 00:15:01,660
Subscribe for more plain English breakdowns

439
00:15:01,660 --> 00:15:02,700
and drop a comment.

440
00:15:02,700 --> 00:15:05,060
Let us know which resource you template first.