Can we get ResourceGroup and ResourceGroup part in ResourceID to be case insensitive? They are causing major issues using terraform since Azure ARM API treats them as case insensitive.
Following site shows Azure treats these as Case Insensitive - https://docs.microsoft.com/en-us/azure/architecture/best-practices/naming-conventions#naming-rules-and-restrictions.
I have experienced a few examples of the ARM API returning ResourceGroup in all uppercase which causes Terraform to force a VM rebuild.
More information on why this is a huge issue.
This issue is tied directly to using azure cli to query vm's which are used to generate import statements to refresh state. There are several use cases on why you would want to do this. One of the more recent use case around this is migrating 100+ vm’s from Standard_LRS to Premium_LRS without having to recreate the VMs. This process entails converting the disks using azure cli and then re-importing it back into a terraform module.
Steps to Reproduce
Example:
terraform state rm azurerm_virtual_machine.vm;
terraform import azurerm_virtual_machine.vm /subscriptions/75406810-f3e6-42fa-97c6-e9027e0a0a45/resourceGroups/USTV-WEB/providers/Microsoft.Compute/virtualMachines/MYVMX1;
If you log into the portal after the bash script has ran you will see that the ResouceGroup name is now in all caps because of the az cli commands which were ran. ResourceGroup is treated by the api as not case sensitive and its having major issues with Terraform. https://docs.microsoft.com/en-us/azure/architecture/best-practices/naming-conventions#naming-rules-and-restrictions
If terraform could treat all instances of ResourceGroup (including in the ResourceID comparison) it would help in these and many other scenarios.
Really you can’t use azure cli to generate any sort or import statements because they treat resourceGroup as case insensitive.
az vm list returns all .id values with resourceGroup all uppercase.
saadmin@Rohrer-D:~$ az vm list --query [].id
[
"/subscriptions/0000-0000-0000-0000/resourceGroups/SUS1VA1-WEB/providers/Microsoft.Compute/virtualMachines/sus1va1lhtp001",
"/subscriptions/0000-0000-0000-0000/resourceGroups/SUS1VA1-WEB/providers/Microsoft.Compute/virtualMachines/sus1va1lhtp002",
"/subscriptions/0000-0000-0000-0000/resourceGroups/SUS1VA1-WEB/providers/Microsoft.Compute/virtualMachines/sus1va1wbox001"
]
az vm show returns the resourceGroup perfectly
saadmin@Rohrer-D:~$ az vm show -g SUS1VA1-Web -n sus1va1lhtp001 --query id
"/subscriptions/0000-0000-0000-0000/resourceGroups/SUS1VA1-Web/providers/Microsoft.Compute/virtualMachines/sus1va1lhtp001"
We often need to run cli to do certain tasks such as disk conversions and afterwards we generate the import scripts that we need to execute. Without being able to generate we will be forced to hand create which is not a viable option.
If we use the resourceID with upper case to import the resource back into state it causes terraform to destroy and recreate the vm (very bad). Of course we can run az vm show for every vm, but that is not a good workaround as it would result in hundreds of separate api calls and also very hard to script around seeing how az vm list returns values (all upper) we would use in sub calls to az vm show.
Can we please fix the TF arm provider to ignore case in both resourceGroup and the resourceGroup part of the resourceID? https://docs.microsoft.com/en-us/azure/architecture/best-practices/naming-conventions#naming-rules-and-restrictions
@VaijanathB @tombuildsstuff @katbyte to comment on any workarounds for this? @rohrerb The scenario that you have here is to use Terraform declarative infra as code to create infra, make changes using az cli to that infra, and then try and continue using Terraform infra as code. Such mixed modes are unsupported in Terraform and the Azure provider by design.
@achandmsft I think it would be a bit short-sighted to say that making manual changes and continuing to manage resources with Terraform is completely unsupported. As users, we will inevitably encounter cases where a change is needed that is not supported by the provider, yet. Or a change needs to be made to mitigate a service issue, and doing so manually would solve the problem faster.
That aside.... if the underlying API is expected to becase insensitive, then the tools should be, too. All kinds of technical issues could come up from such mismatched expectations.
hi @rohrerb
Thanks for opening this issue :)
az vm list returns all .id values with resourceGroup all uppercase.
az vm show returns the resourceGroup perfectly
I'd suggest raising these as bugs on the Azure CLI repository - since the API's should return these consistently.
So in general Resource ID's within Azure are case sensitive - it's just wildly inconsistent across API's for historical reasons; for example some of the older API's can return errors when the Resource Group segment of the URI isn't capitalised as resourceGroups in some scenarios.
In addition whilst Terraform is also generally case sensitive (although we're a bit more lenient for Enum values in the Azure Provider than most other Providers since the API's are generally case insensitive for Enum values) - in regard to ID's we rely on the casing of the URI's being correct when we parse segments out of the URI, whilst we could update this - I believe taking this approach would lead to additional complexity inside the Provider whilst making the user experience inconsistent since this is inconsistent across API's.
Instead, I believe the better approach here would be to support multiple commands at import time and for Terraform to handle this for you - for example something along the lines of this:
# NOTE: this doesn't exist yet
$ terraform import azurerm_virtual_machine.test tom-dev --subscription-id=00000000-0000-0000-0000-000000000000 --resource_group_name=tom-dev
There's an issue tracking support for this feature on the Terraform Core repository which I'm going to close this issue in favour of. Whilst I appreciate this is an inconvenience in the short-term - it should be possible to achieve the same thing with JQ using the output of the Azure CLI in the interim.
The scenario that you have here is to use Terraform declarative infra as code to create infra, make changes using az cli to that infra, and then try and continue using Terraform infra as code. Such mixed modes are unsupported in Terraform and the Azure provider by design.
Terraform will detect changes made outside of Terraform to resources managed by Terraform (for instance as you say during a service issue) - and additional resources can be Imported into Terraform's Statefile, as such both scenarios are fully supported.
Thanks!
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!
Most helpful comment
@achandmsft I think it would be a bit short-sighted to say that making manual changes and continuing to manage resources with Terraform is completely unsupported. As users, we will inevitably encounter cases where a change is needed that is not supported by the provider, yet. Or a change needs to be made to mitigate a service issue, and doing so manually would solve the problem faster.
That aside.... if the underlying API is expected to becase insensitive, then the tools should be, too. All kinds of technical issues could come up from such mismatched expectations.