Skip to content

Commit 2ebda59

Browse files
authored
feat: custom azure credential (#29)
This PR replaces DefaultAzureCredential with a CustomAzureCredential chain. This custom credential chain reorders the credential preference, to prefer AzureCliCredential, then ManagedIdentityCredential, then EnvironmentCredential (service principal)
1 parent 394557f commit 2ebda59

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

docs/further.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Azure Batch Authentication
22

3-
The plugin uses [DefaultAzureCredential](https://learn.microsoft.com/en-us/python/api/azure-identity/azure.identity.defaultazurecredential?view=azure-python) to create and destroy Azure Batch resources. The caller must have Contributor permissions on the Azure Batch account for the plugin to work properly. If you are using the Azure Storage plugin you should also have the Storage Blob Data Contributor role for the storage account(s) you use.
3+
The plugin uses a CustomAzureCredential chain that prefers the use of AzureCliCredential, then falls back to a ManagedIdentityCredential, and finally, an EnvironmentCredential (service principal) to create and destroy Azure Batch resources. The caller must have Contributor permissions on the Azure Batch account for the plugin to work properly. If you are using the Azure Storage plugin you should also have the Storage Blob Data Contributor role for the storage account(s) you use.
44

55
To run a Snakemake workflow using your azure identity you need to ensure you are logged in using the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/):
66

snakemake_executor_plugin_azure_batch/__init__.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import azure.batch.models as bm
1616
from azure.batch import BatchServiceClient
1717
from azure.core.exceptions import HttpResponseError
18-
from azure.identity import DefaultAzureCredential
1918
from azure.mgmt.batch import BatchManagementClient
2019
from snakemake_interface_common.exceptions import WorkflowError
2120
from snakemake_interface_executor_plugins.executors.base import SubmittedJobInfo
@@ -30,6 +29,7 @@
3029
from snakemake_executor_plugin_azure_batch.constant import AZURE_BATCH_RESOURCE_ENDPOINT
3130
from snakemake_executor_plugin_azure_batch.util import (
3231
AzureIdentityCredentialAdapter,
32+
CustomAzureCredential,
3333
read_stream_as_string,
3434
unpack_compute_node_errors,
3535
unpack_task_failure_information,
@@ -278,29 +278,25 @@ def __post_init__(self):
278278

279279
def init_batch_client(self):
280280
"""
281-
Initialize the BatchServiceClient and BatchManagementClient using
282-
DefaultAzureCredential.
281+
Initialize the BatchServiceClient and BatchManagementClient
283282
284283
Sets:
285284
- self.batch_client
286285
- self.batch_mgmt_client
287286
"""
288287
try:
289288

290-
# initialize BatchServiceClient
291-
default_credential = DefaultAzureCredential(
292-
exclude_managed_identity_credential=True
293-
)
294289
adapted_credential = AzureIdentityCredentialAdapter(
295-
credential=default_credential, resource_id=AZURE_BATCH_RESOURCE_ENDPOINT
290+
credential=CustomAzureCredential(),
291+
resource_id=AZURE_BATCH_RESOURCE_ENDPOINT,
296292
)
297293
self.batch_client = BatchServiceClient(
298294
adapted_credential, self.settings.account_url
299295
)
300296

301297
# initialize BatchManagementClient
302298
self.batch_mgmt_client = BatchManagementClient(
303-
credential=default_credential,
299+
credential=CustomAzureCredential(),
304300
subscription_id=self.settings.subscription_id,
305301
)
306302

snakemake_executor_plugin_azure_batch/util.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,21 @@
66
from azure.core.pipeline import PipelineContext, PipelineRequest
77
from azure.core.pipeline.policies import BearerTokenCredentialPolicy
88
from azure.core.pipeline.transport import HttpRequest
9-
from azure.identity import DefaultAzureCredential
9+
from azure.identity import (
10+
AzureCliCredential,
11+
ChainedTokenCredential,
12+
EnvironmentCredential,
13+
ManagedIdentityCredential,
14+
)
15+
16+
17+
def CustomAzureCredential() -> ChainedTokenCredential:
18+
credential_chain = (
19+
AzureCliCredential(),
20+
ManagedIdentityCredential(),
21+
EnvironmentCredential(),
22+
)
23+
return ChainedTokenCredential(*credential_chain)
1024

1125

1226
# The usage of this credential helper is required to authenticate batch with managed
@@ -26,13 +40,13 @@ def __init__(
2640
azure.common.credentials or msrestazure.
2741
2842
Args:
29-
credential: Any azure-identity credential (DefaultAzureCredential by
43+
credential: Any azure-identity credential (CustomAzureCredential by
3044
default)
3145
resource_id (str): The scope to use to get the token (default ARM)
3246
"""
3347
super(AzureIdentityCredentialAdapter, self).__init__(None)
3448
if credential is None:
35-
credential = DefaultAzureCredential()
49+
credential = CustomAzureCredential()
3650
self._policy = BearerTokenCredentialPolicy(credential, resource_id, **kwargs)
3751

3852
def _make_request(self):

0 commit comments

Comments
 (0)