winglang / wing

A programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡
https://winglang.io
Other
4.9k stars 194 forks source link

Not enough randomness for Azure Storage Account names #4947

Open garysassano opened 9 months ago

garysassano commented 9 months ago

I tried this:

terraform apply

This happened:

│ Error: creating Azure Storage Account "defaultc82bf964": storage.AccountsClient#Create: Failure sending request: StatusCode=0 -- Original Error: autorest/azure: Service returned an error. Status=<nil> Code="StorageAccountAlreadyTaken" Message="The storage account named defaultc82bf964 is already taken."
│ 
│   with azurerm_storage_account.StorageAccount,
│   on main.tf.json line 60, in resource.azurerm_storage_account.StorageAccount:
│   60:       }
│ 

I expected this:

I expected the deployment to work, but the name defaultc82bf964 was already taken, which means the current name generation isn't random enough.

Is there a workaround?

Change to a different name which is unique within Azure.

Component

SDK

Wing Version

No response

Node.js Version

No response

Platform(s)

No response

Anything else?

No response

Community Notes

staycoolcall911 commented 9 months ago

Hi @garysassano thanks for reporting. This issue lacks some steps for reproduction - can you please provide the Wing code you were trying to run? Does this happen with any Wing code when you try to compile for tf-azure?

garysassano commented 9 months ago

@staycoolcall911 This issue can occur when compiling any code to the tf-azure target. The root of the problem lies in the way the Azure Storage Account name is generated, as seen here at the app level in the Wing SDK. The generated string, which in this case resembles defaultxxxxxxxx, is not sufficiently unique for a large-scale cloud like Azure, leading to a risk of name collisions with existing Storage Accounts.

github-actions[bot] commented 7 months ago

Hi,

This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!

Chriscbr commented 7 months ago

Thanks for raising this issue @garysassano. To add some context here - it seems like the Azure Storage account resource on Terraform has a name field which "must be unique across the entire Azure service, not just within the resource group." AWS's S3 Bucket Terraform provider behaves similarly with the bucket argument (it requires a globally unique string), but the resource also offers a separate bucket_prefix argument which we're able to use in the SDK to defer the responsibility of globally-unique name generation to the provisioning engine.

We could naively generate a random string in JavaScript during preflight to use for the bucket name, but this would result in nondeterministic test snapshots, which is highly problematic.

One solution could be to add a similar name_prefix type field to the upstream Terraform provider. But in lieu of that, another option could be to use the Terraform random_id resource to generate unique name - it might look something like this:

resource "random_id" "storage1" {
  byte_length = 8
}

resource "azurerm_storage_account" "account1" { // logical ID does not need to be globally unique
  ...
  name = "cloudBucket3A2B1C{random_id.storage1.hex}" // prefix with generated name for readability
}