Skip to content

Commit e2b8799

Browse files
authored
Implement retry logic for IMDS managed identity (#3306)
1 parent facb1c7 commit e2b8799

File tree

4 files changed

+43
-4
lines changed

4 files changed

+43
-4
lines changed

sdk/identity/azure_identity/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
### Bugs Fixed
1818

1919
- `ClientCertificateCredential::get_token()` returned an error when given multiple scopes
20+
- `ManagedIdentityCredential` didn't follow IMDS retry guidance
2021

2122
### Other Changes
2223

sdk/identity/azure_identity/src/app_service_managed_identity_credential.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ impl AppServiceManagedIdentityCredential {
4848
SECRET_ENV,
4949
id,
5050
client_options,
51+
None,
5152
env,
5253
),
5354
}))

sdk/identity/azure_identity/src/imds_managed_identity_credential.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use azure_core::{
66
credentials::{AccessToken, Secret, TokenCredential, TokenRequestOptions},
77
error::{Error, ErrorKind},
88
http::{
9-
headers::HeaderName, request::Request, ClientOptions, Method, Pipeline,
9+
headers::HeaderName, request::Request, ClientOptions, Method, Pipeline, PipelineOptions,
1010
PipelineSendOptions, StatusCode, Url,
1111
},
1212
json::from_json,
@@ -62,13 +62,15 @@ pub(crate) struct ImdsManagedIdentityCredential {
6262
}
6363

6464
impl ImdsManagedIdentityCredential {
65+
#[allow(clippy::too_many_arguments, reason = "private API")]
6566
pub fn new(
6667
endpoint: Url,
6768
api_version: &str,
6869
secret_header: HeaderName,
6970
secret_env: &str,
7071
id: ImdsId,
7172
client_options: ClientOptions,
73+
pipeline_options: Option<PipelineOptions>,
7274
env: Env,
7375
) -> Self {
7476
let pipeline = Pipeline::new(
@@ -77,7 +79,7 @@ impl ImdsManagedIdentityCredential {
7779
client_options,
7880
Vec::default(),
7981
Vec::default(),
80-
None,
82+
pipeline_options,
8183
);
8284
Self {
8385
pipeline,

sdk/identity/azure_identity/src/virtual_machine_managed_identity_credential.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33

44
use crate::env::Env;
55
use crate::{ImdsId, ImdsManagedIdentityCredential};
6-
use azure_core::http::ClientOptions;
76
use azure_core::{
87
credentials::{AccessToken, TokenCredential, TokenRequestOptions},
9-
http::{headers::HeaderName, Url},
8+
http::{
9+
headers::HeaderName, ClientOptions, ExponentialRetryOptions, PipelineOptions, RetryOptions,
10+
StatusCode, Url,
11+
},
12+
time::Duration,
1013
};
1114
use std::sync::Arc;
1215

@@ -27,6 +30,37 @@ impl VirtualMachineManagedIdentityCredential {
2730
env: Env,
2831
) -> azure_core::Result<Arc<Self>> {
2932
let endpoint = Url::parse(ENDPOINT).unwrap(); // valid url constant
33+
let pipeline_options = Some(PipelineOptions {
34+
// https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#error-handling
35+
retry_status_codes: Vec::from([
36+
StatusCode::NotFound,
37+
StatusCode::Gone,
38+
StatusCode::TooManyRequests,
39+
StatusCode::InternalServerError,
40+
StatusCode::NotImplemented,
41+
StatusCode::BadGateway,
42+
StatusCode::ServiceUnavailable,
43+
StatusCode::GatewayTimeout,
44+
StatusCode::HttpVersionNotSupported,
45+
StatusCode::VariantAlsoNegotiates,
46+
StatusCode::InsufficientStorage,
47+
StatusCode::LoopDetected,
48+
StatusCode::NotExtended,
49+
StatusCode::NetworkAuthenticationRequired,
50+
]),
51+
..Default::default()
52+
});
53+
// these settings approximate the recommendations at
54+
// https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#retry-guidance
55+
let client_options = ClientOptions {
56+
retry: RetryOptions::exponential(ExponentialRetryOptions {
57+
initial_delay: Duration::milliseconds(1340),
58+
max_retries: 6,
59+
max_total_elapsed: Duration::seconds(72),
60+
..Default::default()
61+
}),
62+
..client_options
63+
};
3064
Ok(Arc::new(Self {
3165
credential: ImdsManagedIdentityCredential::new(
3266
endpoint,
@@ -35,6 +69,7 @@ impl VirtualMachineManagedIdentityCredential {
3569
SECRET_ENV,
3670
id,
3771
client_options,
72+
pipeline_options,
3873
env,
3974
),
4075
}))

0 commit comments

Comments
 (0)