I have a ARM template that I use to create a keyvault.
For a very specific reason, I need to manually set access policies on my keyvault once it's created.
If I run my ARM template again (to change some settings), the access policies I manually set are deleted.
What function or trick can I use to have an ARM template that combines access policies in the ARM template with the access policies that were set manually?
It is not possible; if you are using access policies, then you must specify them as you deploy the Microsoft.KeyVault/vaults resource.
The ARM reference says
access policies are required
There is a workaround, but it is not simple. Instead of using access policies, you need to use the RBAC model to define access to your key vault.
That is what is recommended by Microsoft in response to a feature request ARM Template for KeyVault to have AccessPolicies non-mandatory:
For anyone who opens this feedback item:
Use RBAC permission model: https://docs.microsoft.com/en-us/azure/key-vault/general/rbac-migration
That could be because you might be deploying the ARM template in Complete mode. Verify the command being used to deploy the template and check for any -Mode parameter being passed.
To elaborate, there are two modes in which ARM templates can be deployed:
Incremental: In incremental mode, Resource Manager leaves unchanged resources that exist in the resource group but aren't specified in the template. Resources in the template are added to the resource group.
Complete: In complete mode, Resource Manager deletes resources that exist in the resource group but aren't specified in the template.
The default mode of deployment is always incremental, although you can override it by passing the -Mode parameter explicitly.
To set the deployment mode to Complete or Incremental explicitly when deploying with PowerShell, use the Mode parameter as follows:
New-AzResourceGroupDeployment `
-Mode Incremental `
-Name ExampleDeployment `
-ResourceGroupName ExampleResourceGroup `
-TemplateFile c:\MyTemplates\storage.json
Skipping the -Mode parameter completely is also as good as deploying in Incremental mode.
Tip: Always use the what-if operation before deploying a template
in complete mode. What-if shows you which resources will be created,
deleted, or modified. Use what-if to avoid unintentionally deleting
resources.
Related
I have an ARM template for an Azure DNS zone that has many Microsoft.Network/dnszones/* resources for A, CNAME, TXT records, etc. I've been able to deploy new records and change records successfully through deployments.
I just noticed however that when I deleted resources corresponding to some DNS records in the ARM template, a deployment of that template didn't actually delete the records in the Azure DNS zone, although the deployment succeeded.
This seems like it breaks the declarative nature of ARM templates if I deleted a resource in the template and it still exists after deployment without errors.
Or am I misunderstanding something about the way the resource provider works?
There are two modes in which ARM templates can be deployed:
Incremental: In incremental mode, Resource Manager leaves unchanged resources that exist in the resource group but aren't specified in the template. Resources in the template are added to the resource group.
Complete: In complete mode, Resource Manager deletes resources that exist in the resource group but aren't specified in the template.
The default mode is incremental, which is why you're not seeing the deleted resources being removed.
To set the deployment mode to Complete explicitly when deploying with PowerShell, use the Mode parameter as:
New-AzResourceGroupDeployment `
-Mode Complete `
-Name ExampleDeployment `
-ResourceGroupName ExampleResourceGroup `
-TemplateFile c:\MyTemplates\storage.json
Tip: Always use the what-if operation before deploying a template
in complete mode. What-if shows you which resources will be created,
deleted, or modified. Use what-if to avoid unintentionally deleting
resources.
We recently created an Azure policy that enforces a certain set of Tags to be present on all resources. This policy blocks deployments that don't contain the required tags in the deployment. However, certain taggable resources, such as Vnets, don't have an option to add Tags during deployment unless you use an ARM template. It looks like Terraform also attempts to deploy the Vnet as a separate step before adding tags, which causes Terraform-deployed Vnets to fail even if the proper tags are provided. With Terraform, if a ARM template is provided, it will bypass this issue.
How can I get Terraform deploy resources such as Vnets without using an ARM template and without having to ditch the azure policy? Ideally, I'd like to be able to exclude Terraform-initiated resource deployments from the Azure Policy, but I can't find a way to differentiate Terraform deployments from normal Azure Web Portal deployments in Azure policy.
Some other Ideas:
Use Terraform to create a temporary Tag on the Resource Group Specifying 'Exempt these resources'. Remove this tag once the Terraform script is done. Reference this tag in the Azure Policy and make deployments exempt if the Tag exists. This solution is OK but I'd prefer a more elegant one
Use Terraform to add the Resource Group as an exemption to the Policy while executing, then revert after
Update the policy to not require Tags on resources that do not support Tagging on initial deployment without ARM templates
Is there a more elegant solution other than the options mentioned above?
Azure Policy doesn't have any way to differentiate between how an ARM operation was performed, it only sees the resultant set of properties that are going to be applied to the resource.
What about using the inherit resource group tag policy (https://github.com/Azure/azure-policy/tree/master/samples/Tags/inherit-resourcegroup-tag)? Terraform could add the tag to the resource group, then deploy the vnet, at which point Policy will apply the tags from the resource group to the vnet.
Our team is using a deployment that uses multiple ARM templates to setup our environment. The first ARM template is set to deployment mode 'Complete' and removes everything, but a storage account. We're using Azure CLI to make the deployment:
az group deployment create \
--mode Incremental \
--resource-group $resourceGroupName \
--template-file $BUILD_SOURCESDIRECTORY'/Infrastructure/azuredeploy.json' \
--parameters $BUILD_SOURCESDIRECTORY'/Infrastructure/azuredeploy.parameters.'$environment'.json' \
--query $query \
--output json
However one of our resource groups contains a few locked resources (which are managed by a different team). In that particular case the strategy with a 'Complete' deployment mode fails, because Azure cannot remove the locked resources.
Understandably of course, but maybe there's a way around this? Can we, for example, instruct the ARM template to ignore specific resources? Or use CLI to instruct something similar?
The obvious way would be to move the resources to a separate resource group, but unfortunately that's not a possiblity for us. I couldn't find any other way yet, but maybe I missed something. Thanks for any answers in advance.
Another way to get around this apart from moving resources to a separate resource group (which you say is ruled out in your case anyway), would be to use Conditions with your resources.
Do note that in complete mode, Resource Manager deletes resources that exist in the resource group but aren't specified in the template. Resources that are specified in the template, but not deployed because a condition evaluates to false, aren't deleted.
For more detail on the syntax and examples, please refer to the following resources:
Structure and syntax of Azure Resource Manager templates
Conditionally deploy a resource in an Azure Resource Manager template
Hope this helps!
I have created a relatively complex IaaS environment in one of my resource groups. The environment is working very well. Now I need to re-build the same environment in another RG for testing and validation.
What would be the easiest way to re-create the same environment in another Resource Group in the same subscription? I tried to export the resource group and downloaded it. The problem is that the file “parameters.json” includes hard coded references to the original resource group name.
Is there an easy way to copy all contents of a RG to another RG in the same environment?
Thank you,
Two approaches can be used here. You can remove the resource group reference from the template and parameter files and then simply specify the resource group when you deploy from the template using PowerShell, the portal, Azure CLI, etc.
To deploy using this method in PowerShell
New-AzureRmResourceGroupDeployment -Name ExampleDeployment -ResourceGroupName ExampleResourceGroup -TemplateFile <PathToTemplate> -TemplateParameterFile <PathToParameterFile>
Or
You can change the resource group to the new resource group in the parameters file and deploy.
You can read more about deploying using templates here.
Edit:
Just a note but you don't have to use a separate file for parameters. You can easily include the parameters in the template file as well.
I'm working on provisioning new Azure environment using ARM templates.
In order to deploy I use the Azure PowerShell New-AzureRmResourceGroupDeployment command, where I specify DeploymentName , ResourceGroupName etc.
However, when I want to remove the deployed resources by running
Remove-AzureRmResourceGroupDeployment -Name DeploymentName -ResourceGroupName RGname -Force
it does not remove resources. It just deletes a tag in deployment tab in Azure portal. Is there a way to rollback or remove deployment with related resources? I don't want to delete whole Resource group.
The general guidance from Microsoft is that a Resource Group contains zero or more resources that share a common lifecycle. Hence, they would probably tell you to separate different deployments into different Resource Groups.
I have actually tried the same thing you have before, but deleting a deployment only deletes the deployment metadata, not the actual resources that were provisioned by the deployment. It would be a great feature request to be able to "slice and dice" resources, based on the most recent deployment that they were a member of.
Here is the supporting documentation:
All of the resources in your group should share the same lifecycle. You will deploy, update and delete them together. If one resource, such as a database server, needs to exist on a different deployment cycle it should be in another resource group.
https://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/#resource-groups
You can do this if you want to roll up your sleeves and write a bit more code... Though Trevor Sullivan has the best suggestion for overall management of resources.
Take a look at this cmdlet:
(Get-AzureRmResourceGroupDeploymentOperation -DeploymentName $DeploymentName -ResourceGroupName $RGName).Properties.ProvisioningOperation
(Get-AzureRmResourceGroupDeploymentOperation -DeploymentName $DeploymentName -ResourceGroupName $RGName).Properties.TargetResource.id
The first will tell you if the operation was a create operation on the resource, the second will give you the resourceId which you can then use to delete with:
Remove-AzureRMResource
But if you organize your resource groups by life cycle then removing the entire group is easier.
The other thing to watch out for here is resources that have dependencies on one another. I'm not sure what will happen in those cases (fail to delete, etc). I can't think of a specific problem to watch out for, just that I haven't spent much time looking at "clean up" this way...
To remove all the deployed resources under a specific resource group,
you should use the Azure PowerShell command:
Remove-AzureRmResourceGroup [-Name] <ResourceGroupName> [-Force <SwitchParameter>]
The Remove-AzureRmResourceGroupDeployment only removed the specific deployment by name and resource group name but not the resources.
Hope this helps!