WEBVTT 0:00:02.680000 --> 0:00:08.740000 In this video, I'm going to talk about advanced ARM template deployments. 0:00:08.740000 --> 0:00:12.460000 And one thing you should know before I go into this, this video assumes 0:00:12.460000 --> 0:00:18.080000 that you are familiar with the basic concept of deploying ARM templates. 0:00:18.080000 --> 0:00:20.860000 If you are not, take a look at the video on that. 0:00:20.860000 --> 0:00:23.080000 Make sure you go through and understand that because otherwise this is 0:00:23.080000 --> 0:00:26.640000 going to be probably a bit much to take in all at once. 0:00:26.640000 --> 0:00:29.800000 What we are going to look at specifically are some of the more advanced 0:00:29.800000 --> 0:00:33.040000 deployments that we have with virtual machines. 0:00:33.040000 --> 0:00:37.080000 We are going to take a look at deploying multiple NICS, also deploying 0:00:37.080000 --> 0:00:40.320000 multiple data disks. 0:00:40.320000 --> 0:00:42.180000 We will talk about template functions. 0:00:42.180000 --> 0:00:45.860000 And I will tell you, if you are not a developer, the concept of functions 0:00:45.860000 --> 0:00:49.320000 may make you want to run away. 0:00:49.320000 --> 0:00:52.480000 But they are really not that bad and there are so many tools to help you 0:00:52.480000 --> 0:00:55.720000 out that even if you never want to write your own function ever or use 0:00:55.720000 --> 0:00:58.380000 it or reference it, you are probably still going to be okay. 0:00:58.380000 --> 0:01:03.320000 And they give you so much flexibility in how you can construct and use 0:01:03.320000 --> 0:01:05.100000 your template. There we go. 0:01:05.100000 --> 0:01:08.380000 Sold it. We will talk about multiple instances. 0:01:08.380000 --> 0:01:09.940000 That is actually pretty cool too. 0:01:09.940000 --> 0:01:11.460000 I use this all the time. 0:01:11.460000 --> 0:01:15.340000 We will talk about scenarios that you can update via template, what are 0:01:15.340000 --> 0:01:18.000000 some things you can do if you need to update. 0:01:18.000000 --> 0:01:20.800000 And finally, I am going to run a demonstration. 0:01:20.800000 --> 0:01:22.060000 Have a little fun with some of this. 0:01:22.060000 --> 0:01:27.660000 I have got an example where I am trying to set up a load balanced environment. 0:01:27.660000 --> 0:01:33.640000 And I have got my load balanced environment firing off on 1VM. 0:01:33.640000 --> 0:01:36.680000 And I kind of want to modify things so that I get multiple VMs and maybe 0:01:36.680000 --> 0:01:41.640000 we will even throw in multiple NICS per VM as well when we get in there. 0:01:41.640000 --> 0:01:47.940000 All right. Now let's talk about using templates to deploy NICS and disks. 0:01:47.940000 --> 0:01:52.120000 For me, when I start getting into this kind of concept where I am deploying 0:01:52.120000 --> 0:01:58.920000 multiples of something, that is where this gets so powerful. 0:01:58.920000 --> 0:02:03.140000 And I find this so much easier than if I am say scripting. 0:02:03.140000 --> 0:02:04.900000 Let me show you why. 0:02:04.900000 --> 0:02:13.380000 Here is the syntax if you are deploying multiple NICS for a virtual machine. 0:02:13.380000 --> 0:02:16.680000 Notice that I have got my network interfaces. 0:02:16.680000 --> 0:02:19.340000 And there is a little thing that is a little bit new here. 0:02:19.340000 --> 0:02:23.020000 Let's see if I can manage to pull the pin up. 0:02:23.020000 --> 0:02:28.400000 That can be a little bit more daunting. 0:02:28.400000 --> 0:02:35.080000 Anyways, at the network, I have got these brackets. 0:02:35.080000 --> 0:02:37.340000 And the brackets represent an array. 0:02:37.340000 --> 0:02:40.040000 And again, that is a little bit of programming stuff you don't need to 0:02:40.040000 --> 0:02:43.720000 know too much. But what you do want to know is that it makes it really 0:02:43.720000 --> 0:02:47.480000 straightforward to add multiple instances of something. 0:02:47.480000 --> 0:02:51.420000 Because essentially we say, all right, I have got some NIC objects. 0:02:51.420000 --> 0:02:56.220000 Again, there we have got this concept of an object in JSON, which is delimited 0:02:56.220000 --> 0:02:59.320000 by just the braces instead of brackets. 0:02:59.320000 --> 0:03:03.260000 And we go, all right, my first one, it is going to have some ID. 0:03:03.260000 --> 0:03:07.200000 That is going to be the ID of the actual NIC that already exists. 0:03:07.200000 --> 0:03:09.980000 And it is going to have a property. 0:03:09.980000 --> 0:03:13.340000 Primary. Then any other NIC that I want to add, I just add in with an 0:03:13.340000 --> 0:03:16.880000 ID. And I can have more, of course, the number of NICs that I can have 0:03:16.880000 --> 0:03:20.460000 associated with my virtual machine is going to be completely dependent 0:03:20.460000 --> 0:03:25.760000 on the number of NICs that are allowed by the size. 0:03:25.760000 --> 0:03:29.100000 Now, the next thing, data disks, all right. 0:03:29.100000 --> 0:03:31.140000 Now, data disks fairly similar. 0:03:31.140000 --> 0:03:38.240000 Notice with data disks, we've got that bracket syntax, which is a little 0:03:38.240000 --> 0:03:40.640000 bit more which means I can pop multiples in here. 0:03:40.640000 --> 0:03:43.120000 And this really is pretty straightforward. 0:03:43.120000 --> 0:03:47.260000 I've got a definition of a data disk, the line, the name, whether or not 0:03:47.260000 --> 0:03:51.880000 it's cached. Is it going to be right, accelerated, create option, empty, 0:03:51.880000 --> 0:03:52.840000 this size, right? 0:03:52.840000 --> 0:03:53.660000 And then I just do another one. 0:03:53.660000 --> 0:03:58.500000 The only thing that really has to change are the line and the name. 0:03:58.500000 --> 0:04:03.700000 And not all of the settings for any given item are fully required. 0:04:03.700000 --> 0:04:08.980000 It really kind of depends on what your needs are, what the resource is. 0:04:08.980000 --> 0:04:10.380000 And it's all documented. 0:04:10.380000 --> 0:04:12.860000 I'm going to show you where to get to that documentation, although I will 0:04:12.860000 --> 0:04:17.420000 tell you that documentation is pretty thick. 0:04:17.420000 --> 0:04:22.560000 When I'm getting down into the weeds of analyzing the different attributes 0:04:22.560000 --> 0:04:28.100000 of kind of sub objects within a JSON template, that can get pretty deep. 0:04:28.100000 --> 0:04:32.800000 And you may hope to find, say, a quicksar template that frankly does it 0:04:32.800000 --> 0:04:34.320000 for you or some other tooling. 0:04:34.320000 --> 0:04:35.500000 But it is all there. 0:04:35.500000 --> 0:04:37.680000 It's all well documented as you go farther along. 0:04:37.680000 --> 0:04:41.820000 I find myself more and more going to that documentation just because I 0:04:41.820000 --> 0:04:45.700000 know everything's there, which is kind of good and bad thing. 0:04:45.700000 --> 0:04:48.780000 All right. Now, template functions. 0:04:48.780000 --> 0:04:54.180000 JSON JavaScript Object Notation is a text-based standard. 0:04:54.180000 --> 0:04:58.300000 And really by definition, a text -based standard is static, right? 0:04:58.300000 --> 0:05:00.040000 I define some text and that's it. 0:05:00.040000 --> 0:05:05.200000 And that's great when I'm defining attributes for objects that I don't 0:05:05.200000 --> 0:05:12.480000 need to change. However, oftentimes with a deployment template, you may 0:05:12.480000 --> 0:05:15.620000 want your template to be a little more dynamic, a little more reactive 0:05:15.620000 --> 0:05:17.620000 to its environment. 0:05:17.620000 --> 0:05:21.620000 For example, let's say that I've got a resource group and I'm deploying 0:05:21.620000 --> 0:05:26.840000 a template to a resource group and I want all of the objects to be in 0:05:26.840000 --> 0:05:29.980000 the same location as a resource group. 0:05:29.980000 --> 0:05:35.400000 What I would not want to have to do is go to 20 different resource definitions 0:05:35.400000 --> 0:05:40.900000 in my template and set their location manually, right? 0:05:40.900000 --> 0:05:43.420000 Because if it changes, that's just terrible. 0:05:43.420000 --> 0:05:47.320000 What I'd rather be able to do is pick up the location of the resource 0:05:47.320000 --> 0:05:50.040000 group and just use that for all of my objects, unless I want to place 0:05:50.040000 --> 0:05:51.460000 them somewhere else, which is fine. 0:05:51.460000 --> 0:05:54.420000 And I can do that through functions. 0:05:54.420000 --> 0:05:59.220000 And they give you this dynamic capability and they give you this responsive 0:05:59.220000 --> 0:06:01.320000 capability, which is fantastic. 0:06:01.320000 --> 0:06:04.980000 Now, if you use a template, particularly if you're using a template from 0:06:04.980000 --> 0:06:10.780000 a quick start, pretty much guarantee that that template has functions. 0:06:10.780000 --> 0:06:11.740000 And we'll take a look at it. 0:06:11.740000 --> 0:06:14.800000 Now, the way functions work are a little bit interesting. 0:06:14.800000 --> 0:06:19.100000 You've got this format in the template, whatever the property is, you 0:06:19.100000 --> 0:06:20.980000 assign it where there would normally be a string. 0:06:20.980000 --> 0:06:25.320000 There is still a string, but the string, and this is one thing, the little 0:06:25.320000 --> 0:06:29.560000 bit challenging, inside the string, you have these brackets. 0:06:29.560000 --> 0:06:32.520000 Now, the only reason I say that's a little bit challenging is because 0:06:32.520000 --> 0:06:39.740000 in an arm template, the brackets have two different meanings depending 0:06:39.740000 --> 0:06:44.200000 on context. And the top of my head, they're the only symbol that does, 0:06:44.200000 --> 0:06:49.020000 right? If I've got a bracket that's not inside of double quotes, right? 0:06:49.020000 --> 0:06:50.000000 So it's a string. 0:06:50.000000 --> 0:06:54.900000 If it's not inside a string, then it represents an array, right? 0:06:54.900000 --> 0:06:57.040000 Multiple disks, multiple nicks. 0:06:57.040000 --> 0:07:02.920000 If I have brackets and they're inside a string, that's going to tell the 0:07:02.920000 --> 0:07:06.680000 template processor that it's about to see a function. 0:07:06.680000 --> 0:07:10.580000 Okay? And then once you have that, you do have goes pretty straightforward. 0:07:10.580000 --> 0:07:13.300000 That's the only thing, again, I like to point that out because it'll throw 0:07:13.300000 --> 0:07:15.620000 you off if you're new to the syntax, right? 0:07:15.620000 --> 0:07:18.300000 And then whatever the function name is, and then most functions, not all, 0:07:18.300000 --> 0:07:22.400000 but most functions have a parameter or a set of parameters. 0:07:22.400000 --> 0:07:24.000000 And here are some examples. 0:07:24.000000 --> 0:07:31.960000 The first one is one you'll see quite frequently. 0:07:31.960000 --> 0:07:38.200000 Going to a location attribute of a resource, you want the location to 0:07:38.200000 --> 0:07:39.380000 be the same as a resource group. 0:07:39.380000 --> 0:07:44.020000 There is a function resource group which retrieves various information 0:07:44.020000 --> 0:07:46.220000 about the resource group. 0:07:46.220000 --> 0:07:49.400000 And in this case, I can use it to retrieve the location. 0:07:49.400000 --> 0:07:51.280000 So resource group.location. 0:07:51.280000 --> 0:07:57.120000 Another very common function I use all the time is concat. 0:07:57.120000 --> 0:08:02.360000 Concat takes two strings and essentially pushes them together end to end. 0:08:02.360000 --> 0:08:05.640000 And also, here I have variables. 0:08:05.640000 --> 0:08:09.100000 Any variable, remember, I talked about variables when I was going over 0:08:09.100000 --> 0:08:11.920000 the basics of a template. 0:08:11.920000 --> 0:08:15.680000 If you have variables, you're using a function because the way you reference 0:08:15.680000 --> 0:08:18.400000 a variable is with the variables function. 0:08:18.400000 --> 0:08:21.300000 That just becomes wrote. 0:08:21.300000 --> 0:08:23.180000 It becomes, you don't even think about it. 0:08:23.180000 --> 0:08:26.920000 OK, but here I've got some variable named base name, and I'm going to 0:08:26.920000 --> 0:08:31.960000 take that variable and really just append via dash VM after it. 0:08:31.960000 --> 0:08:37.460000 Another really common function is resource ID. 0:08:37.460000 --> 0:08:45.180000 Every resource in Azure has a full ID that goes to the effect of slash 0:08:45.180000 --> 0:08:50.840000 subscriptions slash your subscription number slash resource groups slash 0:08:50.840000 --> 0:08:56.420000 your resource group slash resource type slash the name of your resource 0:08:56.420000 --> 0:08:59.680000 and possibly slash subtype subname. 0:08:59.680000 --> 0:09:01.500000 OK, it can get very long. 0:09:01.500000 --> 0:09:07.580000 That can be a bit much to try and pop into your template, not to mention 0:09:07.580000 --> 0:09:11.400000 the fact that if I'm deploying this into different resource groups by 0:09:11.400000 --> 0:09:14.600000 definition, that means I have to pick that up. 0:09:14.600000 --> 0:09:18.700000 So what they do is they give you a function called resource ID and it 0:09:18.700000 --> 0:09:22.820000 says, OK, with resource ID, just take the type. 0:09:22.820000 --> 0:09:25.080000 So here's virtual machines. 0:09:25.080000 --> 0:09:29.840000 And as a second parameter, the name, and then it's going to automatically 0:09:29.840000 --> 0:09:34.480000 generate the right resource ID when I'm referencing that. 0:09:34.480000 --> 0:09:38.560000 And you'll see this for things like dependencies. 0:09:38.560000 --> 0:09:43.660000 Also for example, let's say I've got a virtual machine and I need to refer 0:09:43.660000 --> 0:09:46.680000 to the NIC that it's going to use. 0:09:46.680000 --> 0:09:49.640000 It's going to use this syntax right here. 0:09:49.640000 --> 0:09:52.120000 In addition to these, there are many more. 0:09:52.120000 --> 0:09:53.500000 They're well documented. 0:09:53.500000 --> 0:09:55.940000 There are deployment related functions. 0:09:55.940000 --> 0:09:59.140000 So if you want to get things like, you know, the name of a deployment, 0:09:59.140000 --> 0:10:02.020000 the current deployment, you can do that resource. 0:10:02.020000 --> 0:10:04.100000 We're going to talk about array and object. 0:10:04.100000 --> 0:10:06.820000 And then you've got kind of your standard if you've ever written any kind 0:10:06.820000 --> 0:10:11.060000 of code or even written scripts, you're probably familiar with things 0:10:11.060000 --> 0:10:15.420000 like string and numeric in comparison and logical functions. 0:10:15.420000 --> 0:10:20.940000 OK, so tons of capability there for you if you need it. 0:10:20.940000 --> 0:10:25.700000 OK, and again, this is also something if you haven't done templates before, 0:10:25.700000 --> 0:10:29.780000 don't go look into this and say, wow, I will never get this. 0:10:29.780000 --> 0:10:31.980000 Remember, A, you're going to have tools. 0:10:31.980000 --> 0:10:34.540000 You're going to have quick start templates that are going to start and 0:10:34.540000 --> 0:10:36.880000 have a lot of that information for you. 0:10:36.880000 --> 0:10:39.860000 Right. And so this is just something as you start, you see what others 0:10:39.860000 --> 0:10:40.580000 have done there. 0:10:40.580000 --> 0:10:43.620000 Hopefully you'll get a better idea of it and you can start to then implement 0:10:43.620000 --> 0:10:46.780000 these yourselves or you already implementing them and I just wasted 30 0:10:46.780000 --> 0:10:48.280000 seconds of your time. 0:10:48.280000 --> 0:10:53.400000 Right. Now, what I want to talk about is multiple instances and with multiple 0:10:53.400000 --> 0:10:59.580000 instances, let's say that I am provisioning a virtual machine. 0:10:59.580000 --> 0:11:05.880000 And let's say that virtual machine is running a web app. 0:11:05.880000 --> 0:11:10.380000 But then I say, you know what, really I need three of these virtual machines 0:11:10.380000 --> 0:11:15.520000 that are configured essentially the same way, different names maybe, maybe 0:11:15.520000 --> 0:11:24.960000 some things changed, but pretty much they're the same. 0:11:24.960000 --> 0:11:26.760000 And I have its own Nick. 0:11:26.760000 --> 0:11:36.580000 Right. And it may also have its own public IP, depending on what I'm doing, 0:11:36.580000 --> 0:11:38.080000 probably not, but it could. 0:11:38.080000 --> 0:11:40.440000 And maybe there's disks associated, right. 0:11:40.440000 --> 0:11:44.120000 And so all of a sudden now I've tripled the number of resources that I 0:11:44.120000 --> 0:11:45.600000 need to provision. 0:11:45.600000 --> 0:11:48.080000 Right. And with a standard template, you certainly can do that, but that 0:11:48.080000 --> 0:11:54.080000 tends to become a very just messy environment. 0:11:54.080000 --> 0:11:56.560000 It becomes hard to manage your template. 0:11:56.560000 --> 0:12:01.380000 We have the ability to relatively easily implement multiple instances 0:12:01.380000 --> 0:12:04.860000 of a resource object definition. 0:12:04.860000 --> 0:12:12.500000 And the way we do that is with something called, I cannot get this out, 0:12:12.500000 --> 0:12:17.660000 strike two. There we go. 0:12:17.660000 --> 0:12:20.340000 With something called a copy element. 0:12:20.340000 --> 0:12:24.700000 You add a copy element to a template definition. 0:12:24.700000 --> 0:12:30.420000 And what it's going to do is it is going to repeat that definition, however 0:12:30.420000 --> 0:12:33.020000 many items you have set for count. 0:12:33.020000 --> 0:12:35.700000 Right. And so this has a name and has a count. 0:12:35.700000 --> 0:12:36.720000 The name is VM copy. 0:12:36.720000 --> 0:12:40.520000 So more than likely this would be part of a virtual machine. 0:12:40.520000 --> 0:12:46.560000 Now, however, when you are doing that, you may want to, for example, have 0:12:46.560000 --> 0:12:48.020000 different names. 0:12:48.020000 --> 0:12:51.160000 So here, for example, I've got an array. 0:12:51.160000 --> 0:12:53.980000 Okay. And I've talked about the array delimiters before. 0:12:53.980000 --> 0:12:58.040000 That's that bracket outside of double quotation marks. 0:12:58.040000 --> 0:13:00.000000 That's an array delimiter. 0:13:00.000000 --> 0:13:01.960000 And this says, okay, I have an array. 0:13:01.960000 --> 0:13:08.360000 It's an object that represents three different titles on prem, hub, and 0:13:08.360000 --> 0:13:14.340000 spoke. Each one of those can be addressed by a positional indicator. 0:13:14.340000 --> 0:13:15.540000 And what does that mean? 0:13:15.540000 --> 0:13:21.660000 Well, that means this guy right here, this is the key to all of this. 0:13:21.660000 --> 0:13:23.420000 Copy index is a function. 0:13:23.420000 --> 0:13:29.360000 It is only available in resources where you have a copy element. 0:13:29.360000 --> 0:13:33.360000 If I try to use copy index and I don't have a copy element on the resource, 0:13:33.360000 --> 0:13:36.580000 it's going to give me an error when it tries to evaluate that template. 0:13:36.580000 --> 0:13:40.600000 But if I have a copy, I can refer to the copy index. 0:13:40.600000 --> 0:13:45.980000 And the copy index is just zero for the first one, one, two, three, etc. 0:13:45.980000 --> 0:13:53.600000 Okay. And what this does, it says, all right, I have an array, variables, 0:13:53.600000 --> 0:13:54.900000 base names, right? 0:13:54.900000 --> 0:13:56.520000 That's this array right here. 0:13:56.520000 --> 0:14:01.740000 Well, for each time through that copy, right, so it's going to have three 0:14:01.740000 --> 0:14:05.700000 copies, each time through, I want to pull a different base name based 0:14:05.700000 --> 0:14:06.840000 on the copy index. 0:14:06.840000 --> 0:14:10.580000 So the first time, variables, base name zero would be on prem. 0:14:10.580000 --> 0:14:14.780000 The next time it runs through, variables, base name, one would be hub, 0:14:14.780000 --> 0:14:17.640000 etc. And it just pops a VM after it. 0:14:17.640000 --> 0:14:21.400000 And that is a standard copy element. 0:14:21.400000 --> 0:14:25.000000 Again, if you're a developer, you're starting to think loops. 0:14:25.000000 --> 0:14:27.460000 If you're not a developer, it doesn't matter, right? 0:14:27.460000 --> 0:14:32.240000 You can look at this and say, if I have the need to create multiple instances 0:14:32.240000 --> 0:14:37.260000 of a particular resource and I need to be able to differentiate them somehow, 0:14:37.260000 --> 0:14:41.680000 I have this copy and I have this copy index function that I can use in 0:14:41.680000 --> 0:14:45.840000 conjunction to differentiate whatever properties I want. 0:14:45.840000 --> 0:14:49.120000 And if I want to be very explicit about them, I can create arrays and 0:14:49.120000 --> 0:14:50.500000 reference those arrays. 0:14:50.500000 --> 0:14:52.360000 Lots of things you can do. 0:14:52.360000 --> 0:14:57.640000 All right. Now, I'm going to go on to another concept here, updating via 0:14:57.640000 --> 0:15:04.220000 templates. This for me is one of the best features of templates. 0:15:04.220000 --> 0:15:08.780000 It is entirely possible that I am recording this after lunch and that 0:15:08.780000 --> 0:15:13.880000 I spent a good part of my lunch fixing a template that I'm going to tell 0:15:13.880000 --> 0:15:16.980000 you. You'll never know that for sure because the template is right now. 0:15:16.980000 --> 0:15:21.000000 But the fact that I could run a template and some things worked and some 0:15:21.000000 --> 0:15:25.680000 things didn't work, and then run it again, for me is fantastic because 0:15:25.680000 --> 0:15:30.700000 it lets me build my templates over time, testing each part and not having 0:15:30.700000 --> 0:15:31.980000 to worry about it. 0:15:31.980000 --> 0:15:33.900000 All right. I'm going to get to that in just a moment. 0:15:33.900000 --> 0:15:37.140000 All right. But first, I want to talk about one thing that you have to 0:15:37.140000 --> 0:15:40.240000 know about templates and that you may not ever use. 0:15:40.240000 --> 0:15:44.980000 When you deploy a template, the deployment process, not the template itself, 0:15:44.980000 --> 0:15:48.140000 but the deployment process has a mode. 0:15:48.140000 --> 0:15:53.400000 And the mode has two possible options, complete or incremental. 0:15:53.400000 --> 0:15:57.400000 The default is incremental and that's usually what you will want. 0:15:57.400000 --> 0:16:03.940000 An incremental deployment is only going to deploy new resources when they're 0:16:03.940000 --> 0:16:07.460000 not already in the resource group you are deploying to. 0:16:07.460000 --> 0:16:14.300000 A complete template deployment will erase the entire contents, will deprovision 0:16:14.300000 --> 0:16:19.500000 the entire element before deploying whatever object. 0:16:19.500000 --> 0:16:20.620000 It gives you a clean slate. 0:16:20.620000 --> 0:16:24.160000 The only time that you would ever want to do that is if you're deploying 0:16:24.160000 --> 0:16:27.380000 a template and you just want to make sure you test that that template 0:16:27.380000 --> 0:16:32.440000 is going to deploy properly in a, if you will, green field resource group, 0:16:32.440000 --> 0:16:33.820000 something with nothing in it. 0:16:33.820000 --> 0:16:37.580000 But generally speaking, you're going to take the incremental, which again 0:16:37.580000 --> 0:16:42.880000 is the default. Now the next feature of templates is the one that really 0:16:42.880000 --> 0:16:48.520000 makes me a huge fan of templates and that is that they are and this is 0:16:48.520000 --> 0:16:50.860000 not my word, but they're called, I dampen it in. 0:16:50.860000 --> 0:16:55.420000 And what that means is it's a, I believe it's a mathematical term, I can 0:16:55.420000 --> 0:16:58.380000 apply a function multiple times or in this case I can apply a template 0:16:58.380000 --> 0:17:03.200000 multiple times without impacting the outcome. 0:17:03.200000 --> 0:17:07.300000 So in other words, if I've got an, if I've got a template that is supposed 0:17:07.300000 --> 0:17:11.700000 to deploy 10 objects and I deploy that template and it deploys the first 0:17:11.700000 --> 0:17:15.100000 five objects successfully and then fails. 0:17:15.100000 --> 0:17:19.480000 It never happened to me, but it might happen to somebody or it does. 0:17:19.480000 --> 0:17:22.860000 And what happens at that point is like I have this state where I've got 0:17:22.860000 --> 0:17:25.320000 some of the stuff done, some not done. 0:17:25.320000 --> 0:17:26.300000 So how do I deal with that? 0:17:26.300000 --> 0:17:28.300000 Well, the cool thing is you don't. 0:17:28.300000 --> 0:17:31.560000 What you do is you go in in that case and you would fix whatever is wrong 0:17:31.560000 --> 0:17:32.840000 with the template. 0:17:32.840000 --> 0:17:36.120000 And by the way, I recommend deploying templates with the verbose option 0:17:36.120000 --> 0:17:39.120000 so you can see the details of that deployment. 0:17:39.120000 --> 0:17:42.040000 But in any case, you would fix whatever is wrong and just redeploy the 0:17:42.040000 --> 0:17:45.660000 template. And what it'll do is it'll look and say, oh, cool, I've already 0:17:45.660000 --> 0:17:49.200000 got five, these first five objects are deployed great. 0:17:49.200000 --> 0:17:51.840000 They'll tell you it's exceeded and then it'll go on and deploy whatever 0:17:51.840000 --> 0:17:53.320000 has not deployed yet. 0:17:53.320000 --> 0:17:55.580000 Generally speaking, that works great. 0:17:55.580000 --> 0:17:59.980000 I will tell you there are one or two instances where it doesn't work perfectly. 0:17:59.980000 --> 0:18:05.260000 And I've run into things, for example, if I'm trying to modify a, if I've 0:18:05.260000 --> 0:18:07.840000 got, let's say, for example, I think I was adding a subnet to a virtual 0:18:07.840000 --> 0:18:12.420000 network, but that virtual network already had things dependent upon it. 0:18:12.420000 --> 0:18:13.360000 It wouldn't let me do that. 0:18:13.360000 --> 0:18:18.000000 Not a big deal. Most cases, it is, I damp it in very cool. 0:18:18.000000 --> 0:18:21.980000 Also, let's say you've already deployed a web app, right? 0:18:21.980000 --> 0:18:25.580000 Now you realize that you need to set, you want to automate the process 0:18:25.580000 --> 0:18:30.800000 or you want to define the process to set some basic properties, some app 0:18:30.800000 --> 0:18:32.920000 settings for that web app. 0:18:32.920000 --> 0:18:33.940000 You can do that. 0:18:33.940000 --> 0:18:38.820000 And the reason you can do that is because many properties of resources 0:18:38.820000 --> 0:18:41.820000 are objects that are deployable themselves. 0:18:41.820000 --> 0:18:45.640000 So for example, app service settings, I can deploy app service settings 0:18:45.640000 --> 0:18:50.200000 independently or independently on the app service that you're deploying 0:18:50.200000 --> 0:18:52.080000 them with virtual machine extensions. 0:18:52.080000 --> 0:18:56.020000 I need to inject a configuration script into a virtual machine. 0:18:56.020000 --> 0:18:57.600000 Virtual machine's already running. 0:18:57.600000 --> 0:18:59.820000 I can do that via template. 0:18:59.820000 --> 0:19:05.400000 Network peering, other things just off the top of my head, VPN connections, 0:19:05.400000 --> 0:19:07.120000 VPN gateway connections. 0:19:07.120000 --> 0:19:11.600000 So all of these things can be updated via templates. 0:19:11.600000 --> 0:19:17.040000 Now, for the fun part, I'm going to go through and demonstrate, hopefully 0:19:17.040000 --> 0:19:21.500000 successfully, no, it will be, a complex deployment using a template. 0:19:21.500000 --> 0:19:28.180000 Now, complex more than just what you drop out with a tool, whether it's 0:19:28.180000 --> 0:19:31.700000 using the portal or I'm going to open this up, I'm going to work with 0:19:31.700000 --> 0:19:35.480000 this in what is really my favorite tool to work with templates. 0:19:35.480000 --> 0:19:38.160000 And that is visual studio code. 0:19:38.160000 --> 0:19:41.480000 Now, if you're interested in working with templates, definitely take a 0:19:41.480000 --> 0:19:42.820000 look at visual studio code. 0:19:42.820000 --> 0:19:46.100000 I know the name suggests it's for developers and it's got tons of features 0:19:46.100000 --> 0:19:51.120000 for developers, but it's got some pretty cool add-ons or extensions for 0:19:51.120000 --> 0:19:53.380000 working with ARM templates. 0:19:53.380000 --> 0:19:55.040000 And I definitely take advantage of those. 0:19:55.040000 --> 0:20:01.040000 So we're going to go ahead and take a look at a complex deployment. 0:20:01.040000 --> 0:20:05.360000 All right, here I have a template. 0:20:05.360000 --> 0:20:10.440000 Now the template is open in this space over here. 0:20:10.440000 --> 0:20:12.540000 And I'm just kind of right over here. 0:20:12.540000 --> 0:20:13.440000 This is where our template is. 0:20:13.440000 --> 0:20:16.720000 In fact, I can collapse that. 0:20:16.720000 --> 0:20:18.960000 So we're really focusing on the template. 0:20:18.960000 --> 0:20:21.400000 And it's got standard template components. 0:20:21.400000 --> 0:20:22.180000 It's got a schema. 0:20:22.180000 --> 0:20:23.320000 It's got a content version. 0:20:23.320000 --> 0:20:24.260000 I've got a parameter. 0:20:24.260000 --> 0:20:27.020000 I have some variables here. 0:20:27.020000 --> 0:20:33.160000 And what this does right now is this deploys a network. 0:20:33.160000 --> 0:20:35.920000 It deploys a load balancer. 0:20:35.920000 --> 0:20:38.820000 It deploys a public IP address for the load balancer. 0:20:38.820000 --> 0:20:42.540000 And it deploys a NIC and a virtual machine. 0:20:42.540000 --> 0:20:47.160000 And the virtual machine uses the NIC and that virtual machine and NIC 0:20:47.160000 --> 0:20:52.200000 combination is associated with the load balancer back in pool. 0:20:52.200000 --> 0:20:54.180000 So that's a bit. 0:20:54.180000 --> 0:20:59.500000 But what I'm going to do is make it so that we actually end up with three 0:20:59.500000 --> 0:21:03.860000 instances of the virtual machine. 0:21:03.860000 --> 0:21:08.980000 And to do that, what I'm going to do first is I'm going to simply make 0:21:08.980000 --> 0:21:17.660000 this an array. We'll go VM names. 0:21:17.660000 --> 0:21:23.020000 And we're going to say DB. 0:21:23.020000 --> 0:21:27.280000 App server. No, this is terrible. 0:21:27.280000 --> 0:21:30.240000 We'll say app. I've got to remember what I'm doing. 0:21:30.240000 --> 0:21:34.160000 App server one. That's right. 0:21:34.160000 --> 0:21:41.280000 App server two. And app server end. 0:21:41.280000 --> 0:21:44.840000 Now, I'll also tell you that given what I'm doing here, it is possible 0:21:44.840000 --> 0:21:47.940000 that you would want to use a virtual machine scale set. 0:21:47.940000 --> 0:21:50.440000 But this is just an example. 0:21:50.440000 --> 0:21:53.060000 If you know what virtual machine scale sets are and you're going, why 0:21:53.060000 --> 0:21:54.860000 isn't he using a virtual machine scale set? 0:21:54.860000 --> 0:21:56.800000 Because I wanted to show you this. 0:21:56.800000 --> 0:21:59.000000 All right. Now, I'm going to go down through and look at what we have 0:21:59.000000 --> 0:22:02.400000 a little bit. Here is my public IP address. 0:22:02.400000 --> 0:22:03.740000 And start online 21. 0:22:03.740000 --> 0:22:08.480000 And you see online 22, I'm giving it a name using the PIP name that's 0:22:08.480000 --> 0:22:14.360000 up here. OK. And I'm making it standard, giving it a tag. 0:22:14.360000 --> 0:22:16.220000 It's got static public IP. 0:22:16.220000 --> 0:22:18.480000 Then I've got my virtual network. 0:22:18.480000 --> 0:22:22.100000 The virtual network also is named via a variable. 0:22:22.100000 --> 0:22:25.820000 And I tend to do this all the time because any time I'm going to reference 0:22:25.820000 --> 0:22:29.280000 the same name more than once, I want to use a variable to make sure I'm 0:22:29.280000 --> 0:22:31.660000 always referencing it the same way. 0:22:31.660000 --> 0:22:32.900000 It's got location. 0:22:32.900000 --> 0:22:34.360000 Notice the location. 0:22:34.360000 --> 0:22:37.620000 It's using the resource group location function. 0:22:37.620000 --> 0:22:41.500000 And by the way, I initially built this using what are called snippets 0:22:41.500000 --> 0:22:45.680000 within this tool, just kind of popped a very generic version of everything 0:22:45.680000 --> 0:22:50.320000 out. And I just went back and did a fair bit of modification to it. 0:22:50.320000 --> 0:22:52.440000 All right. And so we've got subnet. 0:22:52.440000 --> 0:22:55.420000 I've got a default subnet and I've got a secondary subnet. 0:22:55.420000 --> 0:23:00.120000 Easy enough. Now, then I have my network interfaces. 0:23:00.120000 --> 0:23:03.540000 And right now, the network interfaces are screaming at me because it was 0:23:03.540000 --> 0:23:06.140000 just named V name. 0:23:06.140000 --> 0:23:07.760000 Now I have V name. 0:23:07.760000 --> 0:23:10.600000 So I could say V names. 0:23:10.600000 --> 0:23:11.640000 And I would think it's happy. 0:23:11.640000 --> 0:23:14.840000 But that's going to be a problem because V names is an array. 0:23:14.840000 --> 0:23:20.560000 So what I want is I want to add copy index, which my tooling happily gives 0:23:20.560000 --> 0:23:24.760000 me my IntelliSense. 0:23:24.760000 --> 0:23:28.000000 Okay. Now the only thing is copy index is dependent upon. 0:23:28.000000 --> 0:23:29.660000 And I know you remember. 0:23:29.660000 --> 0:23:36.500000 Can't use it unless you have a copy element. 0:23:36.500000 --> 0:23:40.600000 Okay. And the copy element has two attributes. 0:23:40.600000 --> 0:23:43.520000 It has more than two, but two that really matter. 0:23:43.520000 --> 0:23:47.100000 This is going to be NIC copy. 0:23:47.100000 --> 0:23:50.960000 And it also has a count. 0:23:50.960000 --> 0:23:54.300000 Now I will tell you I usually use a variable for count. 0:23:54.300000 --> 0:23:56.100000 In fact, I'm going to use a variable now. 0:23:56.100000 --> 0:23:58.540000 We'll just put that there for right now. 0:23:58.540000 --> 0:24:03.860000 Okay. It's yelling at me because it should be an integer. 0:24:03.860000 --> 0:24:06.620000 What I'm going to do though is I'm going to go up to my variables. 0:24:06.620000 --> 0:24:09.600000 And this little tool here, the ARM template outline is really nice. 0:24:09.600000 --> 0:24:12.320000 Use it all the time just to navigate through a template, particularly 0:24:12.320000 --> 0:24:15.580000 if that template starts to get really complex. 0:24:15.580000 --> 0:24:17.840000 It's just an easy way to find where you are. 0:24:17.840000 --> 0:24:21.280000 Every tool I use has a variation of that. 0:24:21.280000 --> 0:24:26.380000 And I'm going to put in here and go copy count. 0:24:26.380000 --> 0:24:30.140000 Say three. Okay. 0:24:30.140000 --> 0:24:38.720000 And now I'll go back to my network interface. 0:24:38.720000 --> 0:24:44.260000 Here I am at count and I want to add that function in that's going to 0:24:44.260000 --> 0:24:46.680000 pull it. And that function is going to be the variables function. 0:24:46.680000 --> 0:24:51.500000 So I just add that in and which variable copy count. 0:24:51.500000 --> 0:24:53.120000 And so now we've got that. 0:24:53.120000 --> 0:24:57.960000 It's yelling at me because I added an attribute I need to have a comma. 0:24:57.960000 --> 0:25:04.000000 So there's now going to be three copies of this network interface. 0:25:04.000000 --> 0:25:09.660000 And if I go down here to the IP configurations, they're all going to be 0:25:09.660000 --> 0:25:15.420000 put on the default subnet of the virtual network. 0:25:15.420000 --> 0:25:17.000000 And by the way, they're dependent. 0:25:17.000000 --> 0:25:19.760000 This is dependent upon the virtual network itself. 0:25:19.760000 --> 0:25:25.020000 So the virtual network will be generated prior to the NIC. 0:25:25.020000 --> 0:25:31.620000 Now I come down here and I've got my virtual machine. 0:25:31.620000 --> 0:25:34.640000 Well, I now want the same thing with the virtual machine. 0:25:34.640000 --> 0:25:37.100000 So I'm going to modify the virtual machine the same way. 0:25:37.100000 --> 0:25:44.560000 Say VM names and which instance copy index. 0:25:44.560000 --> 0:25:47.620000 And here's the thing that's pretty cool if you don't actually put it in 0:25:47.620000 --> 0:26:00.120000 the wrong place, is that you get lots of IntelliSense and lots of repetition. 0:26:00.120000 --> 0:26:04.680000 That copy index, something new, but it's always the same. 0:26:04.680000 --> 0:26:06.900000 And then we're going to come down here. 0:26:06.900000 --> 0:26:22.460000 And if I have copy index, I need to have copy. 0:26:22.460000 --> 0:26:26.400000 And now I've lost IntelliSense on this one because my tool doesn't recognize 0:26:26.400000 --> 0:26:31.080000 the 2019 0701. I've got to wait for that to get updated, but that's OK. 0:26:31.080000 --> 0:26:36.740000 We're OK here. It's interesting because it only loses it for this specific 0:26:36.740000 --> 0:26:50.740000 resource. And again, even though the copy count is actually an integer, 0:26:50.740000 --> 0:26:55.540000 because of the way functions work, you always write that in as a string. 0:26:55.540000 --> 0:27:00.600000 Now I've got a little bit of an issue here because I've got this dependency. 0:27:00.600000 --> 0:27:05.820000 And what's pretty interesting though with dependencies, if it is based 0:27:05.820000 --> 0:27:12.020000 on a copy, I can simply go Nick copy. 0:27:12.020000 --> 0:27:17.160000 And that's going to wait for that entire copy process. 0:27:17.160000 --> 0:27:20.220000 In other words, all three of the nicks before it even starts any of the 0:27:20.220000 --> 0:27:21.980000 virtual machines. 0:27:21.980000 --> 0:27:26.860000 And really, the only other thing I need to do here is I want to change 0:27:26.860000 --> 0:27:31.020000 the computer name in the OS profile. 0:27:31.020000 --> 0:27:40.860000 And I want to change the computer name to variables, VM names, which VM 0:27:40.860000 --> 0:27:45.080000 name, copy index. 0:27:45.080000 --> 0:27:48.880000 I've already got parameters, variables and parameters for the user name 0:27:48.880000 --> 0:27:56.980000 and password. This is a canonical Ubuntu server that I'm building. 0:27:56.980000 --> 0:27:58.480000 And here's the same thing again. 0:27:58.480000 --> 0:28:01.220000 I'm naming the OS disk. 0:28:01.220000 --> 0:28:04.200000 I need to give that the right settings. 0:28:04.200000 --> 0:28:16.340000 Is that. And the network profile to reference the right Nick. 0:28:16.340000 --> 0:28:23.360000 Now just because really all I'm doing is copy index, I just want to show 0:28:23.360000 --> 0:28:26.020000 you that something might be a little foreign to you, but it is repetitive, 0:28:26.020000 --> 0:28:28.180000 but there are many more things that you can do. 0:28:28.180000 --> 0:28:38.240000 I'm just using a few of the functions to make this really a dynamic deployment. 0:28:38.240000 --> 0:28:41.660000 And then the rest is low balancer and I'm not changing the low balancer. 0:28:41.660000 --> 0:28:46.680000 So I have updated this the way I want to. 0:28:46.680000 --> 0:28:51.420000 Okay. And now what I want to do is I want to deploy this first. 0:28:51.420000 --> 0:28:54.800000 Let's see if I have. 0:28:54.800000 --> 0:29:06.040000 The resource group that I want. 0:29:06.040000 --> 0:29:09.880000 And hopefully I got that right. 0:29:09.880000 --> 0:29:11.940000 Never ever has the name or resource group name. 0:29:11.940000 --> 0:29:12.500000 Hey, it is name. 0:29:12.500000 --> 0:29:18.020000 Our resource group name and what I want is a VM complex. 0:29:18.020000 --> 0:29:24.980000 So I am going to create a new resource group. 0:29:24.980000 --> 0:29:40.480000 And location is going to be East US because that's where I do everything. 0:29:40.480000 --> 0:29:42.780000 That will create relatively quickly. 0:29:42.780000 --> 0:29:46.420000 All right. Now for the fun part and that is deploying the template, which 0:29:46.420000 --> 0:29:48.200000 hopefully is going to work on the first time. 0:29:48.200000 --> 0:29:50.880000 If not, I'll pretend like I did it on purpose so I could show you how 0:29:50.880000 --> 0:29:52.580000 you can edit them. 0:29:52.580000 --> 0:29:56.300000 New AZ resource group deployment. 0:29:56.300000 --> 0:30:02.160000 And the name is going to be complex. 0:30:02.160000 --> 0:30:13.380000 And the resource group name is going to be VM complex demo. 0:30:13.380000 --> 0:30:22.620000 And the template file is going to be multi. 0:30:22.620000 --> 0:30:28.980000 And finally, so we can see what's going on put on a verbose. 0:30:28.980000 --> 0:30:30.520000 Now it's going to pop up. 0:30:30.520000 --> 0:30:35.720000 I've got a request here for the password because I put that in as a parameter 0:30:35.720000 --> 0:30:40.200000 and specifically I put it in as a secure string. 0:30:40.200000 --> 0:30:44.680000 So it's going up and it is obviously mass. 0:30:44.680000 --> 0:30:46.700000 Now I will tell you anything production. 0:30:46.700000 --> 0:30:50.860000 I'm actually tying this into a key vault and storing anything sensitive 0:30:50.860000 --> 0:30:53.900000 in a key vault. But that's outside the scope of this. 0:30:53.900000 --> 0:30:56.140000 So we won't do that here. 0:30:56.140000 --> 0:30:58.860000 And then it's going to go check to my template is valid. 0:30:58.860000 --> 0:31:03.640000 That's awesome. And it's now going to run through and deploy all of the 0:31:03.640000 --> 0:31:04.660000 resources in this template. 0:31:04.660000 --> 0:31:07.200000 Now this is going to take a few minutes. 0:31:07.200000 --> 0:31:09.600000 So luckily this will be sped up for you. 0:31:09.600000 --> 0:31:14.780000 And when it's done, we'll come back and take a look at what it's generated. 0:31:14.780000 --> 0:31:24.960000 All right. It actually ran completely correctly the first time. 0:31:24.960000 --> 0:31:25.460000 Thank you very much. 0:31:25.460000 --> 0:31:27.060000 Of course it would have. 0:31:27.060000 --> 0:31:30.820000 And as I go through here, we're just look at the last couple lines here. 0:31:30.820000 --> 0:31:34.260000 Notice it says resource, Microsoft compute virtual machines. 0:31:34.260000 --> 0:31:40.260000 And I've got app SVR two app SVR in and app SVR one all succeeded. 0:31:40.260000 --> 0:31:43.720000 That by the way is another advantage of using templates for deployment. 0:31:43.720000 --> 0:31:48.840000 It's going to deploy in parallel, but also respect your dependencies, 0:31:48.840000 --> 0:31:56.040000 right? So I get that kind of optimized deployment time, but still keeping 0:31:56.040000 --> 0:32:00.720000 the integrity of making sure that, well, the dependencies are properly 0:32:00.720000 --> 0:32:02.180000 aligned. All right. 0:32:02.180000 --> 0:32:15.380000 Let's go ahead and let's pop into our environment here and we'll find 0:32:15.380000 --> 0:32:18.700000 our complex. Is it not VM complex? 0:32:18.700000 --> 0:32:20.500000 It was supposed to be. 0:32:20.500000 --> 0:32:24.040000 Oh, wow. Couldn't find. 0:32:24.040000 --> 0:32:29.380000 There we go. All right. 0:32:29.380000 --> 0:32:35.180000 I'm actually going to set the size back to standard, just so we can see 0:32:35.180000 --> 0:32:36.860000 things a little bit better. 0:32:36.860000 --> 0:32:40.160000 And a little bit bigger. 0:32:40.160000 --> 0:32:41.660000 There we go. That's about right. 0:32:41.660000 --> 0:32:46.760000 All right. So you can see, and I'm going to sort these by type. 0:32:46.760000 --> 0:32:51.080000 So there's three OS disks that were generated. 0:32:51.080000 --> 0:32:52.860000 There's the load balancer. 0:32:52.860000 --> 0:32:58.080000 There's three, I think I clicked the load balancer. 0:32:58.080000 --> 0:33:01.840000 There's three network interfaces. 0:33:01.840000 --> 0:33:04.620000 There's the public IP for the load balancer. 0:33:04.620000 --> 0:33:07.500000 And then I've got three virtual machines and a virtual network. 0:33:07.500000 --> 0:33:10.620000 So all of these components have now been deployed. 0:33:10.620000 --> 0:33:12.400000 They've been deployed dynamically. 0:33:12.400000 --> 0:33:14.680000 I've used functions. 0:33:14.680000 --> 0:33:20.880000 I've also used that copy capability to have multiple instances of a resource. 0:33:20.880000 --> 0:33:26.340000 And that is really just a touch of what you can do. 0:33:26.340000 --> 0:33:29.540000 And again, I know I've said this before, but if you're completely new 0:33:29.540000 --> 0:33:34.120000 to this, don't get overwhelmed by these complex things you can do. 0:33:34.120000 --> 0:33:40.240000 Again, just a couple reminders that you can find over 800 currently, examples 0:33:40.240000 --> 0:33:44.260000 of deployments. And there's a very good chance across those 800. 0:33:44.260000 --> 0:33:49.000000 You're going to find a Quick Start template that is pretty close to what 0:33:49.000000 --> 0:33:51.320000 you need. And you can deploy that. 0:33:51.320000 --> 0:33:52.380000 They're open source. 0:33:52.380000 --> 0:33:57.500000 I have often taken maybe two or three Quick Start templates, taken parts 0:33:57.500000 --> 0:34:01.260000 from them, put them together and built my own without having to go and 0:34:01.260000 --> 0:34:01.880000 generate everything. 0:34:01.880000 --> 0:34:03.880000 There's other tools out there as well. 0:34:03.880000 --> 0:34:10.780000 But you do have that capability of really digging into and defining very 0:34:10.780000 --> 0:34:12.800000 custom deployments through a template.