azurerm_key_vault - do not persist change for network_acls on terraform site and reapplies same change on every run
Terraform v0.11.10
azurerm_key_vault
# Configure the Azure Provider
provider "azurerm" {
subscription_id = "${var.subscription_id}"
client_id = "${var.client_id}"
client_secret = "${var.client_secret}"
tenant_id = "${var.tenant_id}"
alias = "default"
}
resource "azurerm_resource_group" "test_rg" {
name = "kvtest"
location = "${var.azurerm_location}"
provider = "azurerm.default"
}
resource "azurerm_virtual_network" "test_vnet" {
name = "test-vnet"
address_space = ["10.103.12.0/22"]
location = "${var.azurerm_location}"
resource_group_name = "${azurerm_resource_group.test_rg.name}"
provider = "azurerm.default"
}
resource "azurerm_subnet" "test_subnet" {
name = "test-subnet"
address_prefix = "10.103.14.0/24"
virtual_network_name = "${azurerm_virtual_network.test_vnet.name}"
resource_group_name = "${azurerm_resource_group.test_rg.name}"
provider = "azurerm.default"
#service_endpoints = ["Microsoft.KeyVault"]
}
###############################################
# Key Vault
###############################################
resource "azurerm_key_vault" "test_kv" {
name = "test-raf-kv"
location = "${var.azurerm_location}"
tenant_id = "${var.tenant_id}"
resource_group_name = "${azurerm_resource_group.test_rg.name}"
provider = "azurerm.default"
# ROLLBACK - NEVER PERSISTED - APPLIES ON EVERY RUN
network_acls {
default_action = "Allow"
bypass = "AzureServices"
}
# RELEASE - WORKS FINE AFTER CHANGE TERRAFORM INDICATES 0 CHANGES ON EACH RUN
/*
network_acls {
default_action = "Deny"
bypass = "AzureServices"
ip_rules = ["${var.ip_rules}"]
virtual_network_subnet_ids = ["${azurerm_subnet.test_subnet.id}"]
}
*/
lifecycle {
prevent_destroy = true
}
sku {
name = "standard"
}
access_policy {
tenant_id = "${var.tenant_id}"
object_id = "<some object id>"
certificate_permissions = [
"list"
]
key_permissions = [
"list"
]
secret_permissions = [
"list"
]
}
enabled_for_disk_encryption = true
enabled_for_deployment = true
enabled_for_template_deployment = true
}
resource "azurerm_key_vault_key" "test_key" {
name = "generated-certificate"
vault_uri = "${azurerm_key_vault.test_kv.vault_uri}"
key_type = "RSA"
key_size = 2048
provider = "azurerm.default"
key_opts = [
"decrypt",
"encrypt",
"sign",
"unwrapKey",
"verify",
"wrapKey",
]
}
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
~ azurerm_key_vault.test_kv
network_acls.#: "0" => "1"
network_acls.0.bypass: "" => "AzureServices"
network_acls.0.default_action: "" => "Allow"
Plan: 0 to add, 1 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
azurerm_key_vault.test_kv: Modifying... (ID: /subscriptions/
network_acls.#: "0" => "1"
network_acls.0.bypass: "" => "AzureServices"
network_acls.0.default_action: "" => "Allow"
azurerm_key_vault.test_kv: Modifications complete after 1s (ID: /subscriptions/
Once applied terraform should indicate that there will be 0 changes.
it applies this change et every run even tough its already reflected on azure site.
When I comment out network_acls { block the terraform stops reapplying it but it must be done after I run following at least once
network_acls {
default_action = "Allow"
bypass = "AzureServices"
}
Ideally to remove all my network acl change I would like to simply comment out network_acls { but its currently not the case as terraform doesn't perform any change at that point.
I'm encountering the same problem with azurerm_storage_account. The following rule is also never persisted:
network_rules {
bypass = "Logging"
}
Which results in
network_rules.#: "0" => "1"
network_rules.0.bypass.#: "0" => "1"
network_rules.0.bypass.86530918: "" => "Logging"
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
Sounds like the same problem with a different resource. I don't know if this deserves another issue.
@OwenGr thanks for reporting this - whilst this is related, would you mind opening a new issue for that?
Had the same issue with ip rules within a network acl with single IPs. What solved my problem was to always add the netmask (so in address in cidr notation). So for example if you want to add the ip address 1.2.3.4 you should always use 1.2.3.4/32 instead. Until i did that tf always wanted to change that stuff.
@r0bnet solution works. Thanks!
Hi,
Having same issue when deploying Key Vault and using
network_acls {
default_action = "Allow"
bypass = "AzureServices"
}
Really need to don't have this update on each run.
Thanks,
Alex
Error :
Resource '{storage account name}' was disallowed by policy. Error Type: PolicyViolation
{
"error": {
"code": "NetworkAclsValidationFailure",
"message": "Validation of network acls failure: SubnetsHaveNoServiceEndpointsConfigured:Subnets guy-dv-uset2-web of virtual network /subscriptions/{SubcriptionID}/resourceGroups/{resource-Group-Name}/providers/Microsoft.Network/virtualNetworks/{VNet-Name} do not have ServiceEndpoints for Microsoft.Storage resources configured. Add Microsoft.Storage to subnet's ServiceEndpoints collection before trying to ACL Microsoft.Storage resources to these subnets.."
}
}
Plesae check below template code, which I am trying to execute :
`
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"AppEnv": {
"type": "Object"
},
"storageAccountObject": {
"type": "Array"
},
"virtualNetworks_V_NET_NAME": {
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"copy": {
"name": "storageAccountObjectCopy",
"count": "[length(parameters('storageAccountObject'))]",
"mode": "serial",
"batchSize": 1
},
"name": "[parameters('storageAccountObject')[copyIndex()].storageAccounts_name]",
"location": "[resourceGroup().location]",
"tags": "[parameters('storageAccountObject')[copyIndex()].storageAccountTag]",
"sku": "[parameters('storageAccountObject')[copyIndex()].storageAccountSkuObject]",
"kind": "[parameters('storageAccountObject')[copyIndex()].storageAccountKindOff]",
"properties": {
"networkAcls": {
"bypass": "[parameters('storageAccountObject' [copyIndex()].storageAccountProperties.NetworkAcls.Bypass]",
"ipRules": [],
"copy": [
{
"name": "virtualNetworkRules",
"count": "[length(parameters('storageAccountObject')[copyIndex()].storageAccountProperties.NetworkAcls.VNetSubNetRule)]",
"input": {
"id": "[concat(parameters('virtualNetworks_V_NET_NAME'),'/subnets/', parameters('storageAccountObject')[copyIndex()].storageAccountProperties.NetworkAcls.VNetSubNetRule[copyIndex('virtualNetworkRules')].subnets)]",
"action": "[parameters('storageAccountObject')[copyIndex()].storageAccountProperties.NetworkAcls.VNetSubNetRule[copyIndex('virtualNetworkRules')].subnetsaction]",
"state": "[parameters('storageAccountObject')[copyIndex()].storageAccountProperties.NetworkAcls.VNetSubNetRule[copyIndex('virtualNetworkRules')].subnetsstate]"
}
}
],
"defaultAction": "Deny"
},
"supportsHttpsTrafficOnly": true,
"encryption": {
"services": {
"file": {
"enabled": true
},
"blob": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"accessTier": "[parameters('storageAccountObject')[copyIndex()].storageAccountProperties.AccessTier]"
}
}
]
}
`
please let me know if anyone found a fix for it. I am using VSTS CI/CD Pipeline
Hi Guys,
Thanks for the help. Never mind. I got a fix. There is an issue with subnet access. Please find the attachment for more details.
Web Subnet doesn't have access to the storage account.
App Subnet has access to both storage and key vault.

Any updates on this? Would love to stop seeing these in all of my plans.
Problem is, when terraform apply sets default_action to Allow in network_acls, Azure is actually going to set the actual networkAcls field to null.
Example: run terraform apply with the following configuration:
resource "azurerm_key_vault" "test_kv" {
name = "test-kv"
...
network_acls {
default_action = "Allow"
bypass = "AzureServices"
}
}
Then run az keyvault show -n test-kv, and we can see in output:
{
"id": "/subscriptions/******/resourceGroups/*****/providers/Microsoft.KeyVault/vaults/***",
"location": "eastus2",
"name": "***",
"properties": {
....
"networkAcls": null,
"provisioningState": "Succeeded",
"sku": {
"name": "premium"
},
"tenantId": "****",
"vaultUri": "https://****.vault.azure.net/"
},
"resourceGroup": "****",
"tags": {},
"type": "Microsoft.KeyVault/vaults"
}
I'll probably going to raise a PR to fix this.
Initial PR attempt made to fix the issue: https://github.com/terraform-providers/terraform-provider-azurerm/pull/4805 . Might want to add some tests for this.
@richardzone
I also get this with ip's added to the firewall
network_acls.0.ip_rules.1133755571: "" => "REDACTED"
network_acls.0.ip_rules.1441086601: "REDACTED" => ""
network_acls.0.ip_rules.179266854: "" => "REDACTED"
network_acls.0.ip_rules.1933605234: "" => "REDACTED"
network_acls.0.ip_rules.2118414243: "REDACTED" => ""
network_acls.0.ip_rules.2463102908: "REDACTED" => ""
network_acls.0.ip_rules.2563707103: "REDACTED" => "REDACTED"
network_acls.0.ip_rules.2673569789: "REDACTED" => ""
network_acls.0.ip_rules.2709033493: "REDACTED" => ""
Where it's just creating new records in place. Will this be solved then as well?
So every IP is inserted and the old reference is replaced
This has been released in version 1.40.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:
provider "azurerm" {
version = "~> 1.40.0"
}
# ... other configuration ...
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
Had the same issue with ip rules within a network acl with single IPs. What solved my problem was to always add the netmask (so in address in cidr notation). So for example if you want to add the ip address
1.2.3.4you should always use1.2.3.4/32instead. Until i did that tf always wanted to change that stuff.