Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Destroy storage account with network rules is impossible (hangs forever) #5434

Closed
krispetkov opened this issue Jan 17, 2020 · 6 comments
Closed

Comments

@krispetkov
Copy link
Contributor

krispetkov commented Jan 17, 2020

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and AzureRM Provider) Version

  • Terraform v0.11.11
  • Provider: v1.41

Affected Resource(s)

  • azurerm_storage_account

Terraform Configuration Files

provider "azurerm" {
  subscription_id = "${var.azure_subscription_id}"
  client_id = "${var.azure_client_id}"
  client_secret = "${var.azure_client_secret}"
  tenant_id = "${var.azure_tenant_id}"
}

resource "azurerm_storage_account" "my_storage_azure" {
  name                      = "${var.myazurestorage_name}"
  resource_group_name       = "${var.resource_group_name}"
  location                  = "${var.location}"
  account_kind              = "StorageV2"
  account_tier              = "Standard"
  access_tier               = "Hot"
  account_replication_type  = "ZRS"
  enable_https_traffic_only = true

  network_rules {
    default_action             = "Deny"
    virtual_network_subnet_ids = ["${var.platform_subnets}","${var.bosh_subnets}"]
  }
}

resource "azurerm_postgresql_server" "my_postgresql_server" {
  name                = "${var.mypostgredb_name}"
  location            = "${var.location}"
  resource_group_name = "${var.resource_group_name}"

  sku {
    name     = "GP_Gen5_2"
    capacity = 2
    tier     = "GeneralPurpose"
    family   = "Gen5"
  }

  storage_profile {
    storage_mb            = 5120
    backup_retention_days = 14
    geo_redundant_backup  = "Disabled"
  }

  administrator_login          = "vcap"
  administrator_login_password = "${var.db_adm_password}"
  version                      = "10"
  ssl_enforcement              = "Enabled"
}

resource "azurerm_postgresql_database" "my_postgre_db" {
  name                = "mypostgredb"
  resource_group_name = "${var.resource_group_name}"
  server_name         = "${azurerm_postgresql_server.my_postgresql_server.name}"
  charset             = "UTF8"
  collation           = "English_United States.1252"
}

resource "azurerm_postgresql_virtual_network_rule" "network_rule_subnets" {
  count                                = "${length(var.platform_subnets)}"
  name                                 = "postgresql-vnet-rule-subnet-${count.index}"
  resource_group_name                  = "${var.resource_group_name}"
  server_name                          = "${azurerm_postgresql_server.my_postgresql_server.name}"
  subnet_id                            = "${element(var.platform_subnets, count.index)}"
  ignore_missing_vnet_service_endpoint = true
}

output "my_storage_account" {
  value = "${azurerm_storage_account.my_storage_azure.name}"
}

output "my_storage_account_primary_key" {
  value = "${azurerm_storage_account.my_storage_azure.primary_access_key}"
  sensitive = true
}

output "my_storage_account_secondary_key"{
  value = "${azurerm_storage_account.my_storage_azure.secondary_access_key}"
  sensitive = true
}

output "my_postgresql_server_name" {
  value = "${azurerm_postgresql_server.my_postgresql_server.name}"
}

output "my_postgresql_server_host" {
  value = "${azurerm_postgresql_server.my_postgresql_server.fqdn}"
}

output "my_postgresql_server_admin_user" {
  value = "${azurerm_postgresql_server.my_postgresql_server.administrator_login}"
}
output "my_postgresql_admin_pass" {
  value = "${azurerm_postgresql_server.my_postgresql_server.administrator_login_password}"
  sensitive = true
}

output "my_postgresql_db_name" {
  value = "${azurerm_postgresql_database.my_postgre_db.name}"
}

output "my_storage_primary_file_endpoint" {
  value = "${azurerm_storage_account.my_storage_azure.primary_file_endpoint}"
}

Debug Output

Recurring:
azurerm_storage_account.my_storage_azure: Still destroying... (ID: /subscriptions/<GUID>-...Microsoft.Storage/storageAccounts/test, 1h42m51s elapsed)

Trace Output

Recurring:
2020/01/17 12:05:07 [TRACE] dag/walk: vertex "output.my_storage_primary_file_endpoint (destroy)", waiting for: "output.my_storage_account_secondary_key (destroy)" 2020/01/17 12:05:07 [TRACE] dag/walk: vertex "output.my_storage_account_primary_key (destroy)", waiting for: "output.my_storage_account (destroy)" 2020/01/17 12:05:07 [TRACE] dag/walk: vertex "root", waiting for: "meta.count-boundary (count boundary fixup)" 2020/01/17 12:05:07 [TRACE] dag/walk: vertex "provider.azurerm (close)", waiting for: "azurerm_storage_account.my_storage_azure (destroy)" 2020/01/17 12:05:07 [TRACE] dag/walk: vertex "output.my_storage_account (destroy)", waiting for: "azurerm_storage_account.my_storage_azure (destroy)" 2020/01/17 12:05:07 [TRACE] dag/walk: vertex "meta.count-boundary (count boundary fixup)", waiting for: "output.my_storage_primary_file_endpoint (destroy)" 2020/01/17 12:05:07 [TRACE] dag/walk: vertex "output.my_storage_account_secondary_key (destroy)", waiting for: "output.my_storage_account_primary_key (destroy)" 2020/01/17 12:05:12 [TRACE] dag/walk: vertex "root", waiting for: "meta.count-boundary (count boundary fixup)" 2020/01/17 12:05:12 [TRACE] dag/walk: vertex "output.my_storage_primary_file_endpoint (destroy)", waiting for: "output.my_storage_account_secondary_key (destroy)" 2020/01/17 12:05:12 [TRACE] dag/walk: vertex "meta.count-boundary (count boundary fixup)", waiting for: "output.my_storage_primary_file_endpoint (destroy)" 2020/01/17 12:05:12 [TRACE] dag/walk: vertex "output.my_storage_account_primary_key (destroy)", waiting for: "output.my_storage_account (destroy)" 2020/01/17 12:05:12 [TRACE] dag/walk: vertex "provider.azurerm (close)", waiting for: "azurerm_storage_account.my_storage_azure (destroy)" 2020/01/17 12:05:12 [TRACE] dag/walk: vertex "output.my_storage_account (destroy)", waiting for: "azurerm_storage_account.my_storage_azure (destroy)" 2020/01/17 12:05:12 [TRACE] dag/walk: vertex "output.my_storage_account_secondary_key (destroy)", waiting for: "output.my_storage_account_primary_key (destroy)" azurerm_storage_account.my_storage_azure: Still destroying... (ID: /subscriptions/<GUID>...Microsoft.Storage/storageAccounts/test, 10s elapsed)

Panic Output

N/A

Expected Behavior

Destroy the storage account

Actual Behavior

Hangs forever and does not destroys the storage account

Steps to Reproduce

  1. terraform apply
  2. terraform destroy

Important Factoids

  • Location: West Europe

References

@krispetkov krispetkov changed the title Destroy storage account never ends Destroy storage account with network rules is impossible Jan 23, 2020
@krispetkov
Copy link
Contributor Author

krispetkov commented Jan 23, 2020

I have found that this issue (unable to destroy the storage account and hangs forever) is related to the network rules. If I remove:
network_rules { default_action = "Deny" virtual_network_subnet_ids = ["${var.platform_subnets}","${var.bosh_subnets}"] }
Than everything is OK and the destroy is working as it should.
But if I want to use network rules than it is impossible to destroy the storage account...

The other strange thing is that if I create the storage account with network rules and I delete the network rules manually from the Azure Portal Console and remove them from the state than it is still impossible to delete the storage account...

@tombuildsstuff can you please give some help here?

@krispetkov krispetkov changed the title Destroy storage account with network rules is impossible Destroy storage account with network rules is impossible (hangs forever) Jan 23, 2020
@mhaarbrink
Copy link

I've encountered a similar problem and issue #3156 provided help. In my case I deployed a storage account via TF with 2 subnets from 1 vnet and 1 subnet from another vnet. Issue 3156 suggested the issue was with multiple subnets in the same vnet. I manually deleted one of the subnets in the first vnet (leaving 1 subnet in each vnet in the rules) and re-ran the destroy and it succeeded.

I believe this happens because of the lock placed on the vnet so you can have more than one subnet in your rules as long as they are from different vnets because it will lock each vnet independently.

@krispetkov
Copy link
Contributor Author

Hi @mhaarbrink

That's right. This is the exact problem. I have made a fix for this bug and I made a PR which is still waiting for approval. And I hope to be approved but for now no one reviewed it.
This is the PR: #5565
You can see a full description of the problem there.

@katbyte katbyte added this to the v1.44.0 milestone Feb 7, 2020
katbyte pushed a commit that referenced this issue Feb 7, 2020
Fix for issue #5434 (and related issues: #5530 , #3156 )

* **Problem:** If you have a storage account with more than one network rule set - the destroy action hangs forever and the real destroy/deletion of the resource never happens. If you have a storage account with zero or one network rule attached then this problem is irrelevant - the destroy action completes successfully.

* **Reason:** In the `resourceArmStorageAccountDelete` method located in _azurerm/internal/services/storage/resource_arm_storage_account.go_ there is a string array which is passed to the mutex lock method `locks.MultipleByName`. The reason for the problem is that the creation of this array does not cover all possible cases. The logic of the method assumes that you have different virtual networks and inserts them into the array used for locking but does not work correctly in the corner case where you have one virtual network with few sub-networks and you are assigning these sub-networks as a network rules to your storage account. Hence the array passed to the lock method contains n-times strings with the same name (same strings). When this array goes to the mutex the first string is used to lock, the second string is used to lock etc. but at the end all the strings are the same and when the first unlock comes - everything is OK but when a second, third or what so ever unlock hits... dead lock there is nothing to unlock because the first unlock already used the string and it was removed and all other unlocks are trying to use something that simply does not exists.

* **Resolution:** Check if there are subnets and attach them to the network name hence all the strings used to populate the array are unique and the lock-unlock problem is resolved.
@katbyte
Copy link
Collaborator

katbyte commented Feb 7, 2020

closed by #5565

@katbyte katbyte closed this as completed Feb 7, 2020
@ghost
Copy link

ghost commented Feb 12, 2020

This has been released in version 1.44.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.44.0"
}
# ... other configuration ...

@ghost
Copy link

ghost commented Mar 28, 2020

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!

@ghost ghost locked and limited conversation to collaborators Mar 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants