 Hey, good morning, good afternoon, good evening everybody. Welcome to Episode 10 on our series on using Bicep to deploy your Azure infrastructure as code. My name is Josh Waddell. I am a Senior Service Engineer with the FastTrack for Azure for ISV and start-ups teams. With me today is Neil Peterson. Neil, why don't you introduce yourself? Hey, Josh. Yeah. My name is Neil Peterson. I'm a Site Reliability Engineer in a supply engineering team at Microsoft. Manage a bunch of Azure resources using Bicep. Nice. I'm happy to be here. Thanks for having me. Absolutely. Joining us today is Will Valida. He is going to be our moderator for today's session. If you have any questions on the topic at hand, feel free to drop a question into the chat. He's monitoring the chat on YouTube, Twitch, and every other place that we are streaming today. Everybody say hello to Will, and feel free to drop your questions in there. He'll get those over to me and Neil, and we'll try to answer him as best we can. All right. Thanks, Buntz, Will. All right. Neil, talk to us a little bit about today's module and what we're going to be doing. Yeah. This is episode 10, I think you said. We learned a lot about working with Bicep all the way from the fundamentals through some advanced concepts. Here, we're taking it a little bit real, I think, because many of us have been working with ARM templates for a long time. We may have production systems that we've deployed with ARM templates or the classic JSON ARM template. This module is about migrating from the JSON templates to Bicep templates. I think one of the goals here is really to provide a framework, a series of steps to work through as we're making that jump from JSON to Bicep. To be able to do it without introducing issues, without introducing breaking changes, because if we think about it, we may have deployed something using a JSON template, made some updates, deployed it using the same JSON template, made some updates, deployed it using the same JSON template, and now we want to slide in a Bicep template to manage the same deployment. How do we get from that JSON template to a Bicep template while retaining the fidelity of being able to just continually deploy or deploy over that existing deployment? In essence, we're going to be talking about migrating from JSON templates to Bicep templates and not just JSON to Bicep. We're also going to talk about how you can take an existing deployment or set of resources. Maybe you don't have the JSON template anymore and capture those from the Azure APIs and then build Bicep templates from that capture that we can then start deploying back over that deployment. So migrating your Azure resources and JSON ARM templates to Bicep. I think just one little last thing here, I think just to reiterate, I think we're going to see a lot of concepts that we've already learned about, but the bigger picture here is kind of that framework of migration, keeping fidelity, reducing the risk of introducing breaking changes. No, yeah, you're absolutely right. We're really going to kind of be talking about a recommended workflow. What are the steps that you need to take from getting your existing ARM template repo over into Bicep? Or as you mentioned, even taking some existing resources where you may not have a JSON template. So we're going to try to give you some information to help you guide you through that process. If you do want to follow along with today in the learn module, there is a QR code and a link on the screen right now. Feel free to scan that and you'll be able to follow along with what we're talking about today, not only the information, but the exercises that we're going to get into a little bit later. So in terms of the learning objectives, what we're doing today, we're going to talk about converting those JSON ARM templates over to Bicep. We're going to talk about creating Bicep definitions for existing resources. And then we're also going to go through some verification. We're going to verify those template conversions by using the what if operation and documentation. As Neil mentioned, some of the concepts that we're going to be talking about today, we've talked about before in previous episodes. On the what if statement right there in objective number three, there was an excellent episode last week that covered the what if operation. So we're going to revisit some of that information today. So let's talk a little bit about our story, our scenario. We've had this scenario as part of our episodes from the very beginning. You are responsible. You, the Azure infrastructure admin, responsible for configuring Azure infrastructure for your toy company. In this particular scenario, you've learned how Bicep improves your overall template offering process and over JSON ARM templates. You've learned about the benefits of Bicep over ARM. So now we're talking about migrating any of those existing templates that we have from ARM over to Bicep. So again, the toy company, I kind of jumped ahead a little bit on the conversation there, but recently your company has acquired a smaller competitor that is creating a popular toy truck. They also use Azure for its application infrastructure, but that previous company did all of their deployments manually inside the portal. So we're going to go through the process here of standardizing on Bicep and converting those templates from JSON ARM over to Bicep. So when we talk about the steps of what we're going to be doing today, Neil, what are we looking at here? What are we going to be covering? Yeah, so like at a high level, this is kind of that workflow or framework that we mentioned before. So we'll talk about converting either Azure resources that have already been deployed into Bicep or maybe you've already just, you have the existing JSON template. In fact, kind of more detailed, we'll talk about taking Azure resources that have already been deployed, pulling them down as JSON in converting that to Bicep. We'll then be talking about migration. What we'll see is that like, you know, it, well, it's very valuable to be able to pull resources from Azure APIs. You know, there are some cleanup and stuff that you want to do. You really want to kind of like massage through the data and make sure that it's really, really ready to go. And I mean, it's an opportunity to do a bunch of things, make sure that it's valid, but also clean it up, implement standards, implement commenting, like whatever you might want to do. And that's kind of the migration phase. We'll then talk about refactoring, which is kind of a little bit about what I just talked about, renaming things, just again, making sure you're adhering to your company standards and that it is factored the way you want it to be. Talk about testing it and then finally deploying it. So really just kind of the end-to-end workflow of moving from deployed resources or JSON all the way through testing and redeployment with your new latest and greatest Bicep templates. And then, yeah, I mean, after, you know, after working through this module, and I worked through it, I never really kind of worked through the workflow and it is very helpful. So after working through this, you're going to kind of have experienced it hands-on, good. And, you know, some of the stuff is just kind of busy work or there's, you know, there's a lot of like just like kind of reading through stuff and just validating that everything is the way you want it to be. But, you know, the, I think the benefit here is really kind of working through that process, working through the workflow, really thinking about like what the framework is intending to do, which is kind of keep you safe and kind of keep using that word fidelity. I think you mentioned it to me and I think that's a really good way to put it. Like make sure that you've got that kind of migration fidelity reducing risk and kind of getting your head around what it means to do that migration and performing a couple of times is definitely going to kind of set you off on the right path, which is the goal of this module for sure. Yeah, I mean, if we've got resources in production and we're making these changes, right? We don't want to damage or change anything that's actually in prod, right? We don't want those phone calls coming in from the users that applications are down or VMs aren't working. So yeah, that fidelity is kind of like one of the key points of this process. Josh, I think that's a great point. Like, you know, I think a lot of times when we're like going down a learning path, you know, we're just thinking about like, hey, how do I learn how to do this thing? And this is really about like keeping you safe in production, right? Like there is risk in some of these activities and taking the time and kind of putting it into a workflow or framework that, you know, you've got all the checks. Like have I done, you know, the refactoring phase? I mean, the goal here is learning to be safe in production. Absolutely. One of the goals is learning to be safe in production. So I think that's a real good point to make sure that Pops is safety in production. All right, so we're gonna get into the first section here. This is gonna be the first two phases. Convert and migrate your resources to a bicep file. So, Neil, talk to us a little bit about introduce the convert and migrate phase and what we're gonna be focusing on here. Yeah, absolutely. So first two phases, convert and then migrate. So specifically when we talk about convert, in fact, I think we've got slides for all of them if we wanna- We do, yeah, we'll go ahead and just move right into the convert phase, yeah. Yeah, so when we're talking about converting a couple of things here. One might be that you've been deploying using infrastructure as code for a while. You've maybe got source repo where you've got your JSON templates. They're good, they've deployed them many times. They're the way that you need them to be for your environment. So converting here would be taking that JSON template and converting it over to a bicep template. And the good news here is we've got great tooling for this. In fact, we got great tooling all over this module so that is the good news upfront. So converting that JSON template to a bicep template. And then the second piece might be like maybe we don't have that template, but we've got resources running in Azure. Do we have options for kind of converting those existing or taking that existing representation of those resources and producing a bicep file of those and the good news is yes. Now it's not straightforward or it's not necessarily straightforward from like resources to bicep template. We actually, and we'll see this in one of the demonstrations, but we actually take those existing resources and there's an export functionality that exports them to JSON. It's been around for a long time, much longer than bicep. But at that point we now have a representation of those resources in JSON form and then we can do the same conversion using bicep commands and decompile command to convert that JSON representation of those existing resources to a bicep template. Yeah, and here's some graphics. Thank you. I think I went one slide too far. Yeah, no worries. Let's go back though. I think there's some cool stuff here. Yep. And so these graphics basically talk about, or represent what I just talked about. So the very top one there, we've got an existing JSON file and we're gonna decompile that to a reference bicep file. Now one note here, it says read only there. That's kind of more like workflow framework type stuff. It's not like a read only file. You can actually go and modify that. But what we really wanna pop is that that conversion is awesome and it does a lot of the work for you, but you still do wanna go and redo it and refactor it and clean it up. So kind of like in the context of this workflow, think about that bicep file that we're producing here is kind of like your reference file. We could take that and deploy it, but the recommendations is to do some work on it, which is why we have it kind of labeled as read only. So top one, existing JSON file, convert it to a bicep file. Second graphic there is that scenario where we don't have the JSON file necessarily, but we've got the resources in Azure. So we can export those to a JSON file and then perform the same process where we decompile that to a bicep file. This third one down here is pretty cool and it's some relatively new functionality where we can actually take an existing resource. So resource by resource, not a whole deployment or a whole resource group and import them into Visual Studio Code as bicep or as native bicep. So how this works is you would basically get the resource ID of an existing resource, let's say like a virtual network, and using tooling inside of Visual Studio Code, drop in that resource ID, the bicep extension for Visual Studio Code will do the work to produce the bicep for that individual resource. Now, correct me if I'm wrong, Josh, but in this last one, we would have to go resource by resource. There's no kind of import resource group or import deployment directly to bicep. Yeah, that's correct. It's just an individual resource import and it kind of makes sense when we talk about that workflow a little bit later, we really wanna, when we do that conversion or that migration to the bicep file that you're gonna talk about here in a little bit, we wanna kind of handle it resource by resource. So it's actually kind of nice that it's just a single resource at a time because we really wanna focus on each individual resource that we're migrating, make sure that again, using your word fidelity, right, that the fidelity of that resource, it is exactly the way that we need it to be. One other thing I wanna kind of focus on on this particular slide is in that second scenario. More specifically, the two boxes there, Azure exporting to an existing JSON file. That feature has been there for a very long time, even predates bicep. And a lot of customers that I work with, I spent a lot of time talking to customers about infrastructure as code, ARM templates and bicep. And one of the things, especially for somebody new to infrastructure as code is, how do I get started? How do I know what a template is actually supposed to look like? And people become familiar with this export process and we can go into the resource or the resource group and we can export all of those contents to a JSON file, but that doesn't mean we can always redeploy that file as is, right? There's gonna be a lot of noise inside that file, some read-only properties that we don't need to include and we can kind of clean up that particular file. So I always like to say that that export process, those two boxes there in step two is really just kind of a starting point, right? This is how you wanna look at what your resources look like in JSON and then from there, you're gonna build a file that's gonna be repeatable, something that we can redeploy kind of as is. All right, so let's talk a little bit about how Azure represents resources and we talked about this back in the intro to infrastructure as code conversation, but it's really good to mention here again. So again, Azure Resource Manager, this is kind of the control plane, the service that allows us to deploy and manage our resources in Azure. ARM tracks all the changes and all the deployments for all of our resources regardless of how those resources were deployed. So if you take a look at this particular diagram, we see that if we're building something in the portal or we're using Azure PowerShell or Azure CLI in kind of an imperative format or we're using an ARM template or some sort of other deployment tool, whether it's through like Visual Studio or something along those lines, all of those tools are interacting with Azure Resource Manager to deploy those particular resources, right? So it doesn't matter what method you actually choose to do those deployments. So when we get into the process or the conversation around exporting those resources to a JSON template, it doesn't matter again how those resources were actually deployed. Those resources are represented within the Azure portal as JSON. You have the ability to go look at the JSON configuration of pretty much any resource that exists inside of your subscription. So inside the portal, you can go to either the resource or the resource group, go down to the export template section and you can actually look at that representation. And from there, you can make the actual download process. You can download that template, save it including the parameters file and then you can open that up inside of VS Code. One other point to kind of mention here is that we see down at the bottom, you can use the portal CLI or PowerShell to export those single resources or multiple resources or entire resource groups. So again, no matter what tool you use to deploy, you can also use multiple tools to do the actual exporting. So talk a little bit about this export process and how this particular export process works. The export resource definition or resource group is a snapshot of the resource in its current state. It exists as how it is deployed in Azure. So for example, you know, key point here is if, you know, Neil, if you deploy a virtual network via template and then I'm on the networking team and I go into the portal and I add some additional subnets or I make some changes at an at gateway, at a route table, right? The export process is gonna include my changes, right? It's not gonna include, it's not gonna be just the original template that was deployed. So that's something to really keep in mind, right? As an organization shifts to a methodology of deployments are only done through infrastructure as code, through pipelines or GitHub actions, right? You need to keep that in mind, right? So any manual changes, right, will be reflected within that particular export. The other point to make here is, and we kind of touched on this a little bit before, the exported template may include some properties and values that are not necessary in your bicep file that you wanna deploy. Your repeatable file that you wanna deploy. We'll provide a link a little bit later to the ARM Temperate Reference Center, which is a website that'll actually detail what all of the required properties are to do an actual deployment of a resource, but some of these properties don't need to be included, right? So when we get into the exercise a little bit later, we'll kind of point out a couple of those read-only properties and we'll remove them from our file before we try a redeploy. So also the exported template won't likely include all the parameters, right? Some of the properties that you're gonna see in some of the exported templates will be hard-coded values. And as we've gone through these episodes over the course of the last 10 weeks, we've talked about making these deployments repeatable, how we may have a production version of our application or a dev version of our application and we use parameters, right, to differentiate between those particular deployments. So some things will come out as hard-coded and we wanna make sure that we convert those over to parameters to make it a little bit easier, right? One last point here on the exporting resources to JSON. Some resources do not actually properly export and we're gonna talk about that a little bit later. Sometimes you need to go in and manually recreate those resources after you do a deployment. So for example, like a VM extension doesn't export in the download template process. So we need to go rebuild that particular piece, but we'll take a look at that in a little bit. Yeah, I think just a little bit of commentary for myself on this. I mean, if you really think about what's going on here and what we're really doing, taking a bunch of deployed resources and then quickly within seconds, snapping those into a JSON file, it's very, very hard work or a very complex work in by no means is it perfect, right? Like that's kind of why we're here. There is a series of things that you need to go through, but I do know that the product team is actively engaged. I mean, this is something that has just gone through a series of improvements over the years and I only expect those to continue. The other thing is I don't know, I don't know if we mentioned this in here at any point, but would this be a decent point to kind of mention like control plane versus data plane when we start talking about exporting resources as well? Yeah, yeah, we do touch on that in a little bit, but go ahead and kind of introduce that conversation. We talked about this in module one, in episode one on intro to infrastructure as code. So from an Azure resource manager perspective, there's the control plane and there's the data plane. The control plane is interfacing and deploying those resources, managing those resources in Azure. So for example, if I deploy a template that builds a virtual network, that's a control plane operation. Data plane operation is you can think of what's inside the resource, right? And I always use this example with my customers when I talk to them. So, Neil, if I give you a permission within the environment to build a virtual machine, right? That's a control plane operation, but that doesn't necessarily mean that I can give you a permission to log into the virtual machine and install applications and do those other things. That's kind of like a data plane operation or saving storage to the storage account, right? So when we're talking about this particular piece, this exporting of templates and migrating these files, it's not always dealing with the data plane. This is really more of a control plane conversation. Yeah, and I think that was what I was hoping to pop is that let's take the storage account or database of any flavor that's available in Azure. While we can do an export on those, we're gonna get a representation of the resource itself, but not the data. So this is not a backup strategy necessarily. This is about the resources that we're deploying in Azure. All right, cool. Yeah, and if we hit back on that later in the module, sorry if I jumped the gun, but I thought I'd need to bring it up. No, it's a really good statement to make here when we talk about ARM and what we're really focusing on. So I appreciate you bringing that up, absolutely. Yeah, cool. Okay, so one last point to make, and Neil kind of hit on this earlier when he showed you kind of the diagram there and he mentioned kind of the read-only files, right? This deployment that we're saving, right? This template that we're downloading, whether it's a resource or a resource group, this is our starting point, right? We're gonna use this to build our new files from there, right? So that's what we wanna do. We wanna treat the exported file as a starting point, right? We don't wanna make initial modifications to that particular file. Okay, so Neil, talk about kind of a little bit of a difference here. We talked about exporting existing resources. What about saving deployments to a JSON template? What do we mean by that particular piece? Yeah, and I don't have a ton of experience here, so I might lean on you a little bit as well. But if you're working in the portal, let's say you go and you start to create a new virtual machine or whatever it might be, but you don't actually hit create now, you're given the opportunity at that point to download a JSON representation of that deployment. So the subtle difference here, what we've been talking about so far is exporting a JSON representation of existing resources, and here we're talking about saving a deployment kind of pre-deployment time, if you will. What I don't know, and I'd be interested in, Josh, can you go to like a previous deployment though, something that's already been deployed and save a JSON representation of that deployment? Yeah, you absolutely can, right? So if you think about how deployments happen within Azure, most of the deployments are resource group level deployments, right? We do have other deployments that do at the subscription level at the management group level, which is another episode we're gonna have actually in the future. But if you've ever gone into, say, a resource group, there's a section within the center blade called deployments, and you can look at all of the deployments that have happened to that specific resource group, you can drill into those individual deployments and actually click on the template that was used to make the deployment. So earlier, when I was talking about the export process, and I gave the example of, Neil, you deployed the virtual network from template, but I manually updated the virtual network. When I export that template, I mean, it's exporting the changes that I put into there as well. But if I wanted to get that original template that you use to build that virtual network, I can go to the deployments, I can click on the template, and then I can download that specific template. So I can have my kind of starting point and my ending point if I wanted access to that. Right, so that subtle differences is exporting, we're gonna get all changes, saving from deployment, I'm kind of going back in history to whenever that deployment was made and getting a template representation from that point in time. Absolutely, absolutely. Cool. All right, so you talked a little bit about it, but why don't you go ahead and kind of re-mention the import existing resources to bicep feature? Yeah, and I probably kind of stole the thunder on this slide that I think I've covered about most of it, but this is awesome. I mean, I use this a lot, particularly as I have been ramping up on bicep and kind of going deep with bicep over the last year or so. But this is a feature of Visual Studio Code where you can insert in existing resource via the resource ID of that resource. So kind of talking through how this would work, I've got Visual Studio Code open, I've got the Azure portal or maybe I'm pulling resource IDs using command line tools, but for ease of conversation, I can click on a virtual network, go to the properties of that virtual network, take the resource ID for that virtual network, and then just use some tooling inside of Visual Studio Code, give it that resource ID, and within about a second or two, I'm gonna have a native bicep representation of that resource. Again, some of the differences here between inserting existing resources and exporting to JSON is that with this functionality here, I would need to go resource by resource. I couldn't kind of take a representation of the whole resource group or a deployment itself. So, but there's certainly some value here in terms of migration to bicep. In particular, I use this as well, just it's a good way, like maybe I'm not working on a migration, but I just am building a new template and I just wanna see an example of what a virtual network looks like as bicep. And I'll just run this really quickly and copy and paste and massage and do whatever I need to do to it. So all around an awesome feature. Yeah, fantastic functionality, absolutely. Which kind of leads into the decompilation process or decompiling. So, what is decompiled? What is bicep decompiled? Yeah, so far we talked a lot about exporting in getting the JSON or maybe I already have the JSON. So the next thing is to migrate that JSON to bicep. And obviously this doesn't apply if you're using the insert resource functionality and you're pulling resources straight to bicep. So this is specifically, I have JSON. However I got it, I have a JSON representation of my resources in Azure. And if we think back to like earlier episodes when we kind of learned like what is bicep? I mean, bicep is just a language that ultimately produces a JSON file that has been deployed to Azure. But we can go the other way and that's what decompilation is. So I've got this JSON file and I wanna convert that to a bicep file. And we've got tooling to do that for us. And we'll see if we're done and it's pretty simple. You have a bicep decompiled here, my file hit enter and within motion of that JSON file. Awesome, awesome. Looking forward to seeing that in the demo. It's actually really cool to see how that works. So that kind of leads us into the migrate phase. You know, we kind of talked about the convert phase there. So in the migrate phase, here we're actually taking that decompiled template, right? And we're gonna start kind of building, you know, our new bicep files. So as we did kind of mentioned early on, Neil brought this up at the beginning of the show. You know, really this is a series of best practices or some recommended steps or recommended workflow, right? So one of the things that we're gonna talk about here is, you know, go ahead and create a brand new empty bicep file and we're gonna take that decompiled file and we're gonna kind of copy those resources over individually, right? And we wanna kind of approach each of those resources one at a time, make sure that all the properties are correct and parameter names and so forth. So create that file, copy those resources across and then we're gonna go through the process of identifying and recreating any of those missing resources. So just from a graphical perspective here, right? We're gonna be referring to either Azure or to our reference bicep file, right? So either referring to Azure from the import resource or from our reference bicep file. We're gonna create that empty bicep file. We're gonna copy those files across and we're gonna eventually get to a fully deployable bicep file. So again, this is just a recommended best practice, right? Create a brand new bicep file. This is going to be our final file, right? We're gonna be copying those resources across and this is just gonna kind of be our starting point, right? When I did this kind of using this framework or using this workflow, it's kind of like, okay, I've got the exported file and now I'm gonna create a new file and copy everything over. It seemed a little redundant. I could have taken the first file and kind of cleaned it up. However, as a structures code developer, I wanna know everything that's going on. I wanna read every line. I wanna have my thumbprint on the entirety of the thing. And I think this phase right here is just a good opportunity to, like we could just export, clean up a little bit and probably deploy comfortably, but the opportunity here is to really make that export your own as if you've kind of written it from scratch. No, absolutely. And when I started years ago, getting into infrastructure as code and getting into ARM templates, I honestly believe, I'll stand by this statement whether you agree or disagree, but if you wanna learn something about a resource and what a resource does in Azure and what its purposes are and how it can work, building a template file of that resource is a fantastic exercise to learning more. I'm in the infrastructure space, right? I'm not a developer, right? I don't know much about app services, but I can tell you pretty much every property on an app service because of all the times that I've gone and built template files around that, okay, this particular property does this, that particular property does that. So I agree with you completely. You wanna review that line by line. So let's take that section at a time, put it into the new file and kind of go from there. It's great. Make it your own at that point. Yep, absolutely. So again, step two on this process, again, kind of a little, we're gonna copy those resources over to the new bicep file and we're gonna treat it, go one at a time and kind of resolve each of those individual resources. So the one thing that we mentioned before as well is that some resources do not export properly. This can include virtual machine extensions, other settings, certain things do not export properly. And we do need to go through and kind of recreate some of those unsupported resources. So one of the tools that's available with inside the portal is the Azure Resource Explorer. You may have used it, may not, but as you can see here kind of on the graphic, we can search for Resource Explorer in the Azure search bar in the top of the portal and we can actually kind of drill down in a hierarchical structure to get to those individual resources that we weren't able to export. So for example, in this picture, it's highlighting the dependency agent for Windows, which is an extension on a VM that's required for Microsoft monitoring to tie it into Log Analytics and Azure Monitor. We can actually drill in with the Azure Resource Explorer and look at the JSON configuration for that dependency agent. Unfortunately, it doesn't export, but we still at least do have a place that we can go to give us a nice starting point to look at what that resource looks like from a JSON perspective, okay? All right, with that being said, we've talked for a little bit, giving you all the theory about some of these first two phases. So now we're actually gonna jump into our first exercise. So we're gonna look at converting and migrating our resources. So I think, Neil, you're gonna take over the share and show us on how some of this works from VS Code. Yep, absolutely. So we are going to work through this first exercise, Convert and Migrate Resources. And it's pretty simple. Josh, we talked a lot. So I'm gonna go pretty riskily through this just to make up a little bit of time, but we won't skip or anything. Bottom line, it's pretty simple stuff. Feel free to follow along at home. Just quickly, I'll kind of scroll through this and then we'll just dig into the exercise itself. So the first thing we're gonna do in this exercise is create a virtual machine using the Azure portal. I've already done that, so we won't walk through that step. And it gives you some recommended property values for your deployment in here. Let's see, the next thing we're gonna do is export the resource group contents to a JSON template. So all resources inside of that resource group will create the template. We're then going to, the exercise walks you through preparing your local environment, making sure that Visual Studio Code is all set up. I've got all this done already, so we won't have to walk through that. And then we're gonna go through the decompilation process. So taking that JSON file and converting that to a bicep template. And then we're gonna go through that migration process. So like we talked about, we certainly could clean up the existing file, the file that we've created via decompilation, but we wanna make it our own, we wanna create a new file and kind of go line by line and copy our resources over. So we'll do that. And then finally, we'll check for missing resources and talk about that a little bit. So in essence, we're deploying some stuff into Azure, exporting it to a JSON template, converting that to a bicep template and then walking through the migration phase. Hey, Neil, can you zoom in a little bit on the portal here? Sure thing, thanks for that. Awesome. All right, cool. So I've got a single resource group in here, KoiTruck, and I used most of the defaults. So if you're walking through the exercise and you're following all the recommended like property values and whatnot, it should look almost identical to this. And so we can see in here, I've got a virtual network, virtual machine, public IP address, network security group, and some other things. Now, I could go into any one of these resources and do an export template, kind of like at a resource by resource level, but what we want to do here is export all resources within the resource group. So in the portal here, we can see that I'm on the KoiTruck resource group. And if I scroll down in here, under automation, we've got this export template feature right there. So I'm just going to click on that. It actually produces a template for me pretty quickly right here in the portal that I'm going to go ahead and click on this download button. And what that has done, let me just paste this on my desktop here, is downloaded a zip file. And when I open this zip file up, just bear with me here. Oh, I kind of got a mess here. Let me just claim this up. It wouldn't be a demo without some technical difficulties. Right, no doubt. Come on. All right, here we go. I'm just going to create a new folder and drop these in here. And so you can see I've got a template.json and a parameters.json file. And so let me go ahead and open this up with VS Code. And then so if I click on my template.json file, here we've got a json, ARM template representation of that environment. As well as the parameters file. So, you know, thus far in the exercise we've deployed the virtual machine using the portal. I'd already done that. And then we use the export template feature for exporting that deployment or all of those resources to a native ARM template. The next thing that we want to do is if you're working through the exercise, we'll make sure that you've got VS Code all set up the way you need it to be. And you've got the tools installed, which I already have. So the next thing that we're going to do is decompile this json template into a bicep template or convert it from json to bicep. And this is super simple. So I'm going to do az bicep, decompile, file, and then just template.json. And I hit enter, and there is my new bicep template. And I've got the bicep extension installed in VS Code and we can see that that was just launching, cool. And there's a couple of warnings that are thrown during the decompilation process. We'll actually address most of these in the next exercise. And so if we look at this thing now, I have got representation of my resources, I've got some parameters. I mean, I have essentially a bicep template that was created from the json template. So the next thing that we're going to do here, I'm just looking through the exercise real quick. Yeah, so basically the exercise is calling out, like yeah, there's some linting warnings in here. While it's a valid bicep template, we can implement some best practices, clean it up. There's quite a bit we can do to this thing to kind of make it a little bit more production ready, which we're going to get to in the next module. However, kind of going back to that, like let's make it our own, let's make sure that this thing is ready to go. This right here is really just our reference template. We want to go ahead and migrate this thing over to what will ultimately be our final template. So I'm going to go ahead and create a new file. And I'll name it main.bicep. I'll open these side by side, might be a little hard to read. And I'm going to go ahead and start copying things over and just kind of validating as we go. So I'm just going to go ahead and grab all these parameters and not really happy with the names of these parameters. So there'll be some refactoring that we're going to want to do there. But I can, through this process of inspecting this thing, it's pretty obvious to me, like, okay, there's something we can do here. It definitely doesn't look very reusable, right? When we talk about that aspect, like those names are something that we're not going to use in multiple environments. Okay, and then kind of go in resource by resource. So there's my network security group. And yeah, it looks pretty good. I've deployed a bunch of these things and they're pretty simple. There's not a lot to it. Next thing here is my public IP address and just taking a quick scan on this thing. Like, you know, I can already see some things like, hey, I might be able to clean this up. And, you know, kind of, I mean, this is infrastructure as code and one of the things that I try to do when building any piece of code is really limiting the code that is inside of my code or rather making sure that I don't have redundancies or just things that aren't necessary. And right away, I can kind of already start to see some things that I might be able to clean up during that phase. Like, so here is my virtual network. Go ahead and move that over. Same thing in here. I've got virtual network pairings as empty. You know, I might want to do some things like parameterize or generalize some of these specific values. And here's my virtual machines. I'm going to go ahead and grab this thing. Same thing, there's a data disk that's empty. I've got an admin administrative name kind of like in there is like a string literal. I might want to parameterize that thing and copy over that. What is this right here? So this is the subnet. Something that kind of stands out to me here is that I've got a resource declaration for that subnet but I believe as I was inspecting this thing I also saw that subnet defined on the virtual network if I'm not mistaken. Yeah, it might be defined twice. Yeah, I think it is. I won't waste the time looking for it. And let's see. And this final resource is the network interface. Go ahead and pull that over. Now I'm going to close my reference file and kind of just look really quickly at my new kind of like this is going to be my final file. And yeah, there's quite a bit we can clean up in here. Oh yeah, there it is right there. So we're looking at this virtual network resource and I can see that I've got the subnet defined in there as default. But then during that export and then decompilation process we have a second resource that is the subnet. So we're seeing kind of some of the value and really inspecting this thing and kind of coming up with a plan on how to clean it up and really making it our own. The final thing in this module is that during this process you're also going to really want to like make sure that you're getting everything. Like as Josh talked about earlier, some resources just are not exportable at this time. And like we said, the team behind this is continually improving this process. And so one thing is notice here that we've got a disk resource in this resource group but that was not exported. And that's okay in this situation. So like a virtual machine when we're deploying a virtual machine that disk is created for us but that's not always the case. You might run into a situation where there's a resource that doesn't export and hence does not come through on kind of the decompilation process and that you're gonna have to go and kind of manually build yourself. And there's some methods for doing that. And I think we actually touch upon those in some of the content here as well. Yeah, we do, absolutely. And so at that point like we've exported the resources to JSON, we've converted to Bicep, we've taken our Bicep reference file and moved that over to our kind of final Bicep file. And the next thing that we're gonna wanna do is again kind of really make this thing ours, clean it up, put in place some of our company standards and kind of best practices around Bicep which we're going to do in the next exercise. Awesome, awesome, thanks Neil, appreciate that. All right, so let's go ahead and go back to the slide deck and let's talk a little bit about refactoring. So the next phase, the third phase out of five is refactoring our Bicep file. And as Neil showed us with the previous exercise, we've got a Bicep file that we've converted from JSON. We've got a new file that exists but there's definitely a lot of things that we can clean up inside of that file. We had some hard coded entries. We've got some strange parameter names and things like that. So that's what we're focusing on in terms of refactoring. So what are we gonna do here in the refactoring section? We're gonna talk about first about reviewing the resource API versions. We're gonna talk about reviewing the linter suggestions in the new Bicep file. We saw a couple of those there. Revising names, parameters, variables and symbolic names, simplify any expressions. If there's any string concatenation or anything along those lines, we wanna simplify that process. Neil pointed out the additional subnet resource that got created there. So that kind of falls under reviewing child and extension resources and the way that ARM and Bicep define those. Talk potentially about modularizing our Bicep file, adding comments and then also following some Bicep best practices. And a lot of the topics that you see here in this list, we have covered in previous modules. So as we get to those sections, we're gonna give you the links and the QR codes to those previous modules if you wanna learn some more in those areas. So the first thing, reviewing resource API definitions. When we introduced you to Bicep back in episode two and how to build your first Bicep template, you learned about how resources and resource providers have different API version for each resource. So as new features are added, features are removed, new API versions of app service plans or virtual networks are introduced. So we wanna make sure that in our exported template, we have the latest or excuse me, the converted Bicep file. We have the latest API version for a particular resource type. So this is a good practice to review your API versions and your templates regardless of your migrating, right? This is something that you wanna take a look at from time to time, make sure that you've got the appropriate features available on your resources at the time of deployment. The Bicep tooling inside of Visual Studio Code, when you do build resources, it does provide for you the available API versions for individual resources. So as you start refactoring the file, simply just backspace delete the existing API version in the app sign, type it back in and it's gonna give you the list of the current API versions actually in appropriate order, right? Reviewing the linter suggestions in your new Bicep file. We saw quite a few of those in that converted template. One that kind of struck out right away was we had hard-coded locations for our resources. Everything said West US. And there's recommendations within the Bicep linter that we don't wanna do hard-coded locations. We wanna use individual parameters to identify locations for resources. So pay attention to the errors that are showing up, the linting suggestions that are showing up inside of Visual Studio Code and address those as you start working towards your final file. All right. So revising parameters, variable and symbolic names. So one of the things that you may notice in this converted file that some of the parameter names and variable names and symbolic names look a little strange, right? So in the export and decompilation process, if you take a look here in this particular graphic, the variable for app service plan name in the decompilation process actually ends up being app service plan name underscore var, right? So we wanna kinda clean that up a little bit again, some of the goal here is to make these templates reusable by other members on our team and reusable for other environments. So a variable like app service plan name, right? Would be pretty consistent across deployment. So we wanna go ahead and take a look at these naming conventions and kinda clean it up a little bit so we can match our naming conventions within our organization. We talked about this process, revising parameters, variables and symbolic names in episode eight of our series. So there's a QR code and a link down there. So if you wanted to go back and watch that particular episode, feel free, okay? All right, so simplifying expressions. Neil, talk to us a little bit about what simplifying expression means. Yeah, I'll just keep it very quick. I mean, without doubt, we've seen it throughout the series. BISA has introduced a bunch of quality and life improvements around the syntax of building these templates, particularly around things like string interpolation and how we build expressions. And those don't always, like some of those quality of life improvements don't always come through once we go from like exporting resources to JSON and then creating the BISA file from that. So you might find that you've got some room to improve kinda just the formatting and readability of your BISA templates. So for instance, you might end up with a BISEP template that still uses the concat function, which is completely valid. However, we've got better ways to express concatenated strings in BISEP templates. So you might just find some opportunity to clean things up, make the BISEP template a little bit more readable. Awesome. And then likewise, I did the episode on child extensions a couple back in within Azure, we've got a couple of different ways to express parent-child relationships and your organization may have standardized on one of those ways. You might just have a personal preference. So you might end up in a situation where your decompiled BISEP template doesn't necessarily match how you want to express child-parent relationships or as well as extension resources. So there might be some room to kind of refactor those around. Go check out the episode on child and extension resources for kind of like a deep dive on what those different methods might be. Oops, sorry, went too far. There you go. And then modularization. Another huge thing in BISEP is a huge improvement in how we can modularize our templates. So kind of in a big deployment, I've got a big resource group with a bunch of stuff in it. If I export that thing, I'm going to get a big JSON template. If I decompile that, I'm going to get a big BISEP template. Just keeping things simple. I might want to modularize that thing. I might want to take maybe my virtual machine resource and pull that out of that big template, put it in its own template so that I can refer to that as a module. And so this is like, if that's something you want to do, this is something that you're going to have to kind of work through in this conversion process, is breaking it down and modularizing things. So really just another opportunity to kind of improve if it works for you and your organization, the export process and kind of like ending up with something that works better for your teams. And then as well, so comments and descriptions. I mean, we've kind of nailed it a couple of times. One of the goals in this migration process is really making, taking that reference template and making it your own. And that might include adding some comments. There's a, I in particular find BISEP very self-documenting. I don't find a need for a lot of commenting, but absolutely this is your opportunity to go in and kind of like document things if that works for you and your organization. All right. And then finally, one other thing, and we'll put this link in the chat as well, is to just kind of follow the overall BISEP best practices, just in case you've missed anything based on our standard recommendations. So with all that being said, we've gotten through that content. Let's talk a little bit about actually refactoring the file. So I'm actually going to go ahead and kind of work here in VS code. So should be able to see that. Okay. All right. So this is going to be exercised to from the learn module. And we're going to be going through the process of refactoring this BISEP file. We're going to update symbolic names. We're going to remove that redundant subnet resource that we looked at before. We're going to change some parameters to variables, update some resource locations, add some additional parameters and variables, remove any unnecessary properties. I know Neil pointed out a few of those when he was reviewing the file. We're going to also create a parameters file and then finally verify your template. All right. So the first thing that we're going to want to do is we're going to actually want to update our symbolic names. So the first one, and if you remember from our previous conversations, the symbolic names are what you see here on line seven after resource. This is the symbolic name for the network security group. We have one for the public IP address, one for the virtual network. And this name isn't very easy to understand. Network security groups, underscore, toy truck server, underscore, NSG name, resource, that's not very clear and easy to understand. So what we're going to do is we're going to start making some changes to these symbolic names. And so what I do here, I'm going to highlight the name. I'm going to hit F2. And this is going to allow me to actually make updates to any reference to this particular name that's used throughout the template. So I'm going to simply change this to network security group. And once I hit enter, that's going to make any adjustments again to that name throughout the template. I'm going to do the same thing for public IP address. So I'm going to hit F2 and we're just going to do public IP address there. And then we're going to do that for virtual networks, the virtual machines, as well as our default subnet. So let me go ahead and highlight this. And so we just got a little bit of busy work to get through here. All right. Got the virtual network done. Oops. Go ahead and take care of the virtual machine and do the virtual network. Oh, this is the actual snow. Yeah, there's the virtual network. All right. Now this is the one, I'm sorry, this is actually the default subnet. So we're going to go ahead and change this name to default subnet. This is the extra subnet resource that we saw there. And then I'm also going to make a change to the network interface. Oh, all right. So it's looking cleaner already. We got rid of some of those crazy symbolic names. So now we're going to go ahead and remove actually the default subnet resource. So let's go ahead and find that default subnet resource and we're going to purge this here. All right. To find the delete subnet, one second. I'm deleting that in the right spot. Let's see IP config one. Yeah, let's go ahead and remove that default subnet resource. All right. So we should see an error now. If you look at the network interface, we see that we're getting an error here. The network interface is referencing the ID of the default subnet, but we just actually removed that particular resource. So in order to get that back for the network interface, we're going to scroll up into the virtual network and we're going to add a child resource that defines that existing subnet. So underneath this section, I'm going to paste in a resource default subnet. We're using the existing keyword here, which means that this is an existing resource within the virtual network configuration. And if we now go down to, we need to go down and make a modification to the ID of the default subnet here so it can actually reference that particular resource. So the syntax that we're going to use for this is going to be virtual network, and then we're going to do two colons and we're going to go to default subnet and then we do dot ID. So now the network interface can reference that existing subnet. Neil, any comments on that piece right there? I mean, not totally related, but that syntax there, so virtual network and then the two semicolons, that was new to me recently and just a call out that is some kind of shorthand for referencing a child resource. Yeah, that one was kind of new to me as well when I started working with Bicep. And really one of the areas that we see that the most is specifically on working with child resources and subnets. I see that all the time with subnets, especially if you're trying to reference like a subnet ID in an output or something like that. Yeah, I think it's just one of those things that like the first time I saw it, I was like, what is this thing? And then the more I worked with it, it's just another one of these quality of life things. Yep, absolutely. All right, so the next thing that we're gonna do is we're going to start making some changes. We're gonna change some of our parameters actually over to variables. So the first thing I'm gonna do here is I'm gonna look for the parameter for the virtual network vNET name. And we're gonna make a change to this. So here we're gonna go ahead and do our F2 process again and we're gonna switch this to simply just virtual network name. All right, so we're gonna make a change there to virtual network name, like so. And then we're actually gonna go ahead and turn this actually into a variable. So I'm gonna move it to below my parameter section, right? So I'm gonna go ahead and get rid of some of that white space there. And we're gonna move this down here. We're gonna change this from a parameter to a variable and we're gonna go ahead and just get rid of that string because we don't need to identify that that particular piece is a string. We're gonna do the same thing for the other parameters that we have identified here. So we'll go ahead and do this with the virtual machine next. So this is going to actually become virtual machine name. So I'm gonna use F2 and we're gonna do virtual machine name get rid of our string and we're gonna turn this again into a variable. Okay. Okay. So we're gonna do this for the next two resources or the next two resources as well. Let's go ahead and do this for the network interface. And we're gonna call this network interface name and this down, change this to a variable and get rid of our string. Okay. All right. For the sake of time, I'm actually gonna go ahead and just kind of bring in the other two. And I'm gonna just go ahead and bring those in here real quick. Actually, no, I'm gonna go ahead and make a change. Let's go ahead and make a change. So here we're gonna create this as the public IP address name. So I'm gonna highlight this, option F2, look IP address name, change this to a var and get rid of string. This work might be a little tedious and not the most exciting at times. Security group name and then we'll get rid of the string piece. Oops, I did not do my F2, did I? I should be good there. That all looks pretty good, done it. All right. All right. So the next thing that we wanna do is we're gonna actually address the linting error for our location. So here we have a location for West US that exists in multiple places, right? So we're gonna create a new parameter and I'm just copying this from the exercise here. We're building a new parameter called location. And that location is gonna be using the function that points to the location of where the resource group actually exists. So we're actually just gonna go ahead and look through a search for West US and we're gonna replace that with location and that should get rid of most of our linting errors there for location. All right. So the next thing that we wanna do is we're gonna add some additional parameters and variables. And so we're gonna add the following parameters. We're just copying this directly from the exercise. If you notice that these parameters already have some nice descriptions in there. So when we talk about commenting our code, we're taking advantage of those descriptions. We're gonna also add some additional variable declarations. This is coming from the exercise as well. So I'm gonna add a variable for a virtual network default subnet name and virtual network image reference. And then I'm also gonna do one more variable reference but we have to actually take a look at what exists in our environment. So here's a virtual machine OS disk name. I need to go take a look at the actual name that was in the portal. And I need to make sure that I have the appropriate name here. Cause remember, this is the resource that wasn't exported. So I do need to bring that in from the portal or from my original source template. All right. Any comments on this, Neil? Where we're at so far? No, we're good. All right, cool. All right. Let me make sure that I've got my values for network interface name appropriate as well. 810, right? Cause that's a unique value. Every time you build a network interface, it's gonna put a three digit number on there. All right. So the next thing that we're gonna do is we're gonna go ahead and start updating some of these properties, right? So the public IP address, we're gonna update the public IP address resource to refer to the public IP address skew name, right? So here's the skew that we see here. So we're gonna go with skew.name for that particular property. Oh, excuse me. I typed in that actually wrong. Let me find that here. Where is that? Oh, excuse me. I made a little bit of a mistake there. All right. We're gonna update this with this particular parameter, the public IP address skew name, which is right here. We're gonna use basic as the skew of our public IP address. We're gonna update the virtual network resource to use all of the virtual network parameters and variables. So let's go ahead and take a look at virtual network address prefix. Look here, we're gonna go down and place that here under address prefixes. So Neil, you were pointing that out before. We wanna get rid of that kind of hard-coded IP address in that area there. All right, default subnet name. We're gonna go ahead and grab this particular variable. We're gonna bring this down to the name and get rid of that hard-coded name of default. So again, we're referencing a variable for there. Make sure we change both the subnets property and the nested one down here. So this was listed as two spots. So we need to make sure that we update the name. Not only our subnet declaration within here, but also that existing resource. Next one we're gonna do is the virtual network subnet address prefix. I'm gonna go ahead and highlight that one. And we're gonna put that in for the prefix of the default subnet. We're gonna start doing the same thing with the virtual machine. So we're gonna make updates to the size. We're gonna use the size name parameter. So let's go ahead and find the size name parameter right here. And VS Code is giving us all of the linting here to let us know what variables and parameters we're actually not referencing. So if you see kind of like the yellow squiggly line here, basically that means that we're not referencing those anywhere in the file. So the image reference is the next one that we're gonna take a look at here. So we're gonna go down to the virtual machine. We're gonna look for the image reference and we're gonna replace this entire section with a variable for image reference, virtual machine image reference, which you can see here is defining the publisher, the offer, the SKU and the version. So the next thing that we're gonna take a look at is the OS disk name. Where do we find that? We're gonna take the OS disk name variable, drop down into our virtual machine and we're gonna put that right here and replace that particular value there. Virtual machine manage disk type. Storage account type. Take that parameter, put it down here where it says premium LRS. So again, removing a hard coded and then we're gonna do the admin username. So we don't want any hard coded admin credentials or anything along those lines. So we'll get rid of toy truck admin there, reference that actual parameter. And then what we're gonna do here is we're actually gonna add a new property for admin password. And we're gonna reference the virtual machine admin password parameter from up top. So when we take a look at that parameter, that virtual machine admin password, you notice that we're listing it as a secure parameter, which is gonna make sure that that is not displayed anywhere in the actual process. So a couple of more steps here to complete this. We wanna remove a couple of unnecessary properties and Neil kind of pointed this out earlier today or earlier in the conversation. The security rules here in the network security group, we're not actually defining any of that. So we can actually remove that from the network security group. In our public IP address resource, we can remove the IP address property because it's actually automatically set. Let's see, am I in the right one in the public IP address resource? We can get rid of the IP tags, right? And we can actually get rid of this IP address because it's a dynamic IP, right? So even though it exported the actual IP address of the public IP, it's a dynamic address. So we can go ahead and clear that out of there, right? In the virtual network one, we can get rid of the virtual network peering section. And we can also get rid of the delegations right here, on line 73. Virtual machine, we can clean up a couple of things. The storage profile OSDIS manage disk ID. So we no longer need this ID value here because we're not referencing the actual ID. We can also get rid of the required guest provision signal and the data disks portion here. And the secrets, I believe, can go as well. And what was the other one I was looking for there? All right, I don't see it, no worries. So in the network interface resource, we're gonna get rid of the private IP address because this is also dynamic, right? We can get that from the IP configuration and then also the DNS settings can go away as well because we're gonna be using defaults, right? So the only other piece to do is to actually create a parameters file so that when do the deployment into Azure, it's gonna reference a parameters file. We are simply copying this over from the actual exercise. So we're basically just copying and pasting this into the parameters file. So when the actual deployment occurs, it's gonna reference this particular parameters file, okay? So I think we've got everything cleaned up there. Our template looks good and we have completed the refactoring of our bicep file. Awesome. Okay, so let's actually move back to the slide presentation and we will move on to testing and deploying the converted template. So we're on to phases four and five of our process here. So Neil, talk to us a little bit about these two phases. Yeah, so you just kind of like bringing us up to speed at this point. So we've converted a JSON template to bicep, a bicep reference file. We've migrated to our final file and then you just went through the refactor exercise. So now we know like, hey, this bicep template is ours. We've implemented our best practices and the thing that we cleaned it up. We've commented it on it. We've done the things that we wanna do to it. Now we need to test this thing, make sure that it's good to go. Like we talked about earlier, we don't wanna break production. We don't wanna change production resources. And we've got some methods and tools for doing this. And then finally, once we know that this thing is good, we're gonna move on to deploying it. So for the test phase, there's a couple of things that we can do here. The first is we've got a tooling called what if, which essentially takes the template, compares it to the resources in Azure and then kind of gives you the delta. It shows you what's going to change, what's no longer there. And it's fascinating tooling and really encompasses a lot of this test phase. I think due to, for the sake of time, I know, correct me if I'm wrong, Josh, but didn't we do like a deep-dive episode just on what if with the PM of the feature itself? Actually it was last week. Okay, cool. We did do it last week's episode. Awesome episode, so you should go check it out, yeah. Yeah, so I think for the sake of time, we'll just kind of like, leave it at like, it's great tooling for testing your deployment against, or your template against existing resources and kind of getting that delta so that you've got a good understanding of what's changed or what might change if you go into that deployment. Let's see. And once we've validated that things look good and we're okay with the results of what if, potentially we would want to deploy that template into just like a test environment. I don't know if you've got separate subscription, separate environments, but again, just to deploy it, A, make sure it deploys, which it should, but B, something that I would personally do is like take that test deployment, maybe pull it up on another screen in the portal, which I find easy to kind of like visually parse and just kind of look at my deployment and like does this thing look the way it should? I mean, it should be pretty identical to the reference that you kind of exported from. And so yeah, so run what if to see what's changed or what will change once you're okay with that, go ahead and perform a test deployment, which then brings us to the actual deployment. And there's a couple of things that we want to do here and not all of it is kind of like bicep technical. This is change, we're making change into our environments. We're changing from JSON based template deployments to bicep template deployments. So we definitely want to like anticipate any kind of issues that might come up and do things like prepare a rollback plan, run the what if operation, make sure that we're running that against our production environment. So that we understand what kind of changes we might make to production. And then deploy manually. And I think the theory here is that, we might have CI systems in place as your DevOps gethub actions. And we could certainly take that file and kind of get in there and utilize, make changes to our CI logic to deploy the bicep template versus the JSON template. But that's a lot of work. It might be a good idea to actually go ahead and run the manual deployment against production, just to make sure things are good. Once it all looks good, now let's go ahead and create some new change to update our CI system. And then finally running smoke test, just making sure that applications are still functional, things are still the way that we want them to be and let it sit for a while before we kind of declare victory. And obviously your organization is gonna have things like change control and processes that you might need to go through. And this is the phase in which you would do that. So talking about a couple of other points on what you just kind of went into there, Neil, this kind of circles us back to the data plane versus control plane conversation. So in part of that rollback plan, like make sure that you've got a plan in place that can deal with actually the data plane piece after you've made a deployment, is your data protected? Are the applications there, et cetera, et cetera. So you need to make sure that that's part of the conversation there. As Neil mentioned, running the what-if operation again against production, but that parentheses again, nothing wrong with running that tool one more time to make sure that no changes are gonna be introduced into your production environment. Yeah, and certainly if this process is taking days or weeks or whatever, I mean, change could have occurred since the first time you ran what-if. So you probably wanna do that right before you kind of go into that final deployment for sure. Absolutely. Deploy manually again, if we've got a DevOps pipeline or GitHub actions, we may wanna consider doing this from our local machine first. And then as mentioned, run the smoke test, make sure that you can make a database connection, make sure that you can log into a virtual machine and verify that all services are running, right? So, exercise three, we're gonna take a brief look at this. We are kind of running low on time, but Neil's gonna take a- What do you think, Josh? I mean, the exercise is essentially what-if do you, do you wanna run into it or do you think for the sake of time to make sure we can get to some of the questions and stuff? Yeah, no, I'm good with that. Let's, yeah, we'll just go ahead and put that off and we'll jump into the knowledge check, absolutely. Yeah, and definitely if you're following along, it's a great exercise to go through because it takes kind of what-if from just like this conceptual thing that we learn about to actually inserting it into this migration process. But again, really the exercise is taking the refactored template running what-if against it, kind of seeing some of the deltas, fixing some of it up and then running through a deployment. So it's really just a rehash of things that we've kind of gone through in other modules within the series. Awesome, cool. So yeah, one more slide to talk about real quick and we'll get into the knowledge check. This is that workflow, right? So everything that we've talked about in this particular discussion today, these are the steps, right? The exporting or importing, making those conversions, doing your migration, your refactoring, your test and your deploy, and then a final deploy to production. So this is actually an excellent slide, excellent graphic, it's in there in the learn module, it kind of takes you through that overall recommended workflow. All right, so the knowledge check. We're gonna go ahead and ask you all a couple of questions. Okay, so question one, if you actually wanna go ahead and take a visit to HTTPS aka.ms slash polls or use the QR code for question one. So question one, Neil, what do we have? Yep, so you need to convert an existing JSON template to BISEP by using built-in tooling. What command do you run from the terminal? And there's three options here, BISEP build, AZ, BISEP decompile and BISEP convert. All right, we've got a couple of answers coming in. So go ahead and go ahead and vote and we'll talk about the answer here in a second. All right, what do you think, Neil? What does it look like here? What are you thinking? So I am going to go with B. You're gonna go with B. All right, did Neil get it correct? Yes, yes, he did, AZ, BISEP decompile, awesome. Okay, question two. So you need to export a deployed Azure resource to an ARM template. What steps do you take to complete this task? So we need to deploy a existing resource. So in the portal, go to the resource you wanna export, select export template and then download the template. In the portal, go to the resource group you wanna export, select export template and then select download. In the Azure portal, select creator resource, enter template in the search box and then select template deployment from the Azure marketplace. All right, so let's go ahead and vote on question two. All right, seeing some answers come in here. Looking good so far. I don't know if I wanna create a resource in option C and in selection C. I don't know if I wanna create a resource. I wanna export something that's kind of already existing. So the answer is, A, so we're gonna go to the portal. Select the resource that we wanna export, select export template and then download to save a copy of the template. Neil took you through that process earlier today. All right, so question three, Neil, what do we got? All right, what is a true statement about exporting templates in the Azure portal? You can use the export template function to create a complete export of any resource and you can use it to redeploy resources. You can use the export template function export the entire contents of your Azure subscription or see the export template function doesn't always perform a complete export of an Azure resource. It should be used as a reference point when you build your templates. So I think I know the answer. Go ahead and get some votes in and Josh, I think this is probably gonna be our last question due to time constraints. Agreed, agreed. All right, so everybody go ahead and get your answers in. Wait a couple more seconds here. I think I know what it's going to be. I think we definitely talked about this today. Yeah, I think we kind of nailed home over and over and over again, which I think is important kind of the reference point here. Absolutely. And so we'll go ahead and go with C. That answer is C. Okay, so we're gonna go ahead and skip over question four. So my apologies on the time constraints. So what did we talk about today? So in today's module, we went through the process of converting JSON ARM templates to Bicep. We talked about creating Bicep definitions for your existing resources and we went through verifying those template conversions using the what if operation and documentation. So Neil, what, oops, sorry, I missed the slide here. I'm gonna talk to that real quick. Yeah, so what is this? So here is a link to the actual module. I know we didn't get to hit all the exercises kind of live in this session, but that's okay. Definitely check this out. Walk through the module again. It's kind of rehashing some stuff that we've seen through the whole kind of series, but it brings it together and really kind of builds out a workflow or framework for doing this stuff in production, which is super important. Awesome. And we have been running the series every Thursday at 10 a.m. Pacific, but we are taking a break for the next couple of weeks. There's kind of a big developer conference coming up here over the course of the next couple of weeks that a lot of people are gonna be a part of. So we are resuming the series. This is getting into our advanced Bicep series. We're coming back on May 31st at 10 a.m. Pacific and that's gonna be on reviewing Azure infrastructure changes by using Bicep and pull requests. So thank you to everybody for attending, Neil. Thanks for joining us today. It was a fantastic conversation. Really enjoyed it. Yeah, thanks for having me, Josh. Awesome. And there's two links down there at the bottom, two QR codes and two links that can kind of prep you for that next session. So thanks again, everybody. Really appreciate you being here and we'll talk to you again soon. Bye. Take care.