Yup, you totally can now, I've been doing it for the past week or so.
With Visual Studio (install Azure SDK with it) you can now create a Azure Resource Group
project to manage your resources.

There are some excellent guides online about how Visual Studio works with the Json templates, I got started with this video by Eliot Mansfield and the source code on GitHub because I wanted to make sure I started in a modular approach for my own resources and any that clients may require.
I'm half way building my project:

But I can already deploy key-vaults
, storage accounts
, virtual networks
, vnet gateways
, virtual machines
, etc all organised, parameterized and maintained within my resource groups, all in a few clicks:

If anyone would like to embark in such a project here are some tips that may save you some time:
- Make sure templates are modular, naming resources appropriately is a must, I've taken Eliot's approach and prefix everything with the resource type, remember resources are not deleted when redeploying templates, you can keep your infrastructure up to date by modifying the templates and rerunning in most cases (I think, haven't tested all scenarios, but hope so!)
- Use linked templates whenever possible, but remember these need to be published to an online location. If you're not storing the templates publicly, use a storage account from Azure.
- If you use the
_artifactsLocation
and _artifactsLocationSasToken
parameters in the template, when deploying via Visual Studio it will ask for a Artifact storage account
where the Deploy-AzureResourceGroup.ps1
will upload all your templates and any files set as Content in the project's file properties (F4 when file selected in Solution Explorer) and replace the parameter values. But never include these parameters values manually in a parameters file as the deploy script will fail when trying to replace those with the generated values.
- I have not tested a linked template also linking to another template, seems untidy to me having to pass along the generated artifacts storage keys to the linked template, so I've been avoiding that.
Build the template links in variables, below is an example from one of my templates that uses the deploy scripts generated storage account location and SasToken parameters to access the container, click here to find out more about the SasToken.
{
"variables": {
"templates": {
"vm": {
"folder": "nestedtemplates",
"fileName": "vm.json"
},
"deploy": {
"folder": "rg-lab-superadmin",
"fileName": "deploy.sh"
}
},
"templateLinks": {
"vm": "[concat(parameters('_artifactsLocation'), '/', variables('templates').vm.folder, '/', variables('templates').vm.fileName, parameters('_artifactsLocationSasToken'))]",
"deploy": "[concat(parameters('_artifactsLocation'), '/', variables('templates').deploy.folder, '/', variables('templates').deploy.fileName, parameters('_artifactsLocationSasToken'))]"
}
}
}
- You can use the same principal of the artifacts location above for scripts you want to execute on a targeted VM with the custom script extension.
- Custom scripts on VM's should be redeployable to the same VM over and over again, as you may need to redeploy a whole resource group that includes the VM and those scripts need to consider that.
- VNet resources must be in the same location but not necessarily the same resource group, you can plan for this within the templates, for example whenever I need a vnet resource I also ask for the resource group it's in so you can create the appropriate resourceId() on your template. A common scenario is when you create a VM, my template also created the NIC and this needs to be referenced properly to the vnet that may be on another resource group.