Azure / azure-sdk-for-rust

This repository is for active development of the *unofficial* Azure SDK for Rust. This repository is *not* supported by the Azure SDK team.
MIT License
685 stars 232 forks source link

Improve Probing Logic for Azure Instance Metadata Service (IMDS) for Virtual Machines #1584

Open joshfree opened 6 months ago

joshfree commented 6 months ago

Tracking issue for addressing customer feedback on IMDS VM delays with DefaultAzureCredential due to IMDS probing retry logic in Azure Identity SDK. @ahsonkhan is driving this investigation.

Currently our SDKs are inconsistent across languages where some languages have zero retries, some have a single 0.5 second retry, and others (.NET) have up to 8-seconds of retries.

We need to review all languages here and make them consistent across languages, as well as publish a Sample and Blog about IDMS on VMs with Azure Identity SDK and how customers can write 2-3 lines of cose to skip IMDS when needed.

Related: https://github.com/Azure/azure-sdk-for-rust/issues/1503

cataggar commented 6 months ago

With the VirtualMachineManagedIdentityCredential enabled by default in DefaultAzureCredential:

  1. The timeout is forced on anyone using credentials that come after. This is felt in CLI apps and scripts.
  2. The timeout may not be long enough and may not retry when deployed to a VM.

To disable that credential, this may be done:

    let credential = std::sync::Arc::new(
        azure_identity::DefaultAzureCredentialBuilder::new()
            .exclude_virtual_machine_managed_identity_credential()
            .build()?,
    );

It is more complex than using the factory method:

let credential = azure_identity::create_default_credential()?;

With it not enabled by default:

  1. There would be no delay for credentials that come after.
  2. The timeout would not need to be as short and could retry.

VM users using DefaultAzureCredential would need to include it:

    let credential = std::sync::Arc::new(
        azure_identity::DefaultAzureCredentialBuilder::new()
            .include_virtual_machine_managed_identity_credential()
            .build()?,
    );

Due to the above problems, I tried to make it opt-in by default in #1532. I still think we should.


In #1532, I added SpecificAzureCredential and added a factory method that creates it or a DefaultAzureCredential.

let credential = azure_identity::create_credential()?;

The way to opt into it is to set AZURE_CREDENTIAL_KIND environment variable. It can help both these situations:

  1. It can be set to Azure CLI to avoid the delay.
  2. It was be set to Virtual Machine to avoid the timeout imposed when use in DefaultAzureCredential.

If VirtualMachineManagedIdentityCredential were to not be included by default, setting it to Virtual Machine would opt-in on the VM. No code changes are necessary.