Skip to content

Commit 15fd0a0

Browse files
assigning user id using ARM at provision time
1 parent 0307e67 commit 15fd0a0

File tree

8 files changed

+66
-263
lines changed

8 files changed

+66
-263
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
// The name of the experiment.
3+
// This is required value and should be unique across incompatible experiments
4+
// (e.g., those with differing tunables, scripts, versions, etc.), since it also
5+
// controls how trial data is stored and reloaded to resume and repopulate the
6+
// optimizer state.
7+
"experiment_id": "RedisTest10",
8+
9+
// Any global parameter can be used as a dollar variable in the global config:
10+
"deploymentName": "$experiment_id",
11+
"vmName": "$experiment_id-vm",
12+
13+
"subscription": "84334f8c-9e72-424d-8fc2-fd6da32e9ad6",
14+
"managedIdentityClientId": "cb2dbf06-0b16-4058-8e33-7561327c8bcf",
15+
"managedIdentityName": "workfm-managed-identity",
16+
"tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
17+
18+
"resourceGroup": "t-kellyko-WorkFM",
19+
"location": "eastus2",
20+
21+
"virtualNetworkName": "kelkost-dv-node-vnet",
22+
"subnetName": "default",
23+
24+
"storageAccountName": "eastus2benchbasestorage",
25+
"storageFileShareName": "eastus2benchbasestoragefileshare",
26+
27+
"vmSize": "Standard_B2s",
28+
"ubuntuOSVersion": "18.04-LTS",
29+
30+
"tunable_params_map": {
31+
32+
// VM provisioning parameter groups (see `azure-vm-tunables.jsonc`):
33+
// ["azure-vm"] (not used at the moment)
34+
"provision": [],
35+
36+
// Boot-time Linux parameter groups (see `linux-boot-tunables.jsonc`):
37+
// ["linux-kernel-boot"]
38+
"linux-boot": ["linux-kernel-boot"],
39+
40+
// Runtime Linux parameter groups (see `linux-runtime-tunables.jsonc`):
41+
// ["linux-swap", "linux-hugepages-2048kB", "linux-scheduler"]
42+
"linux-runtime": ["linux-scheduler"],
43+
44+
// Redis config parameter groups (see `redis-tunables.jsonc`):
45+
// ["redis"]
46+
"redis": []
47+
},
48+
49+
"optimization_targets": {"score": "min"}
50+
}

mlos_bench/mlos_bench/config/schemas/services/remote/azure/azure-deployment-service-subschema.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@
2020
"description": "The name of the resource group to place the deployment in (typically provided in the global config in order to omit from source control).",
2121
"type": "string"
2222
},
23-
"managedIdentityName": {
24-
"description": "The name of the managed identity used for storage authentication (typically provided in the global config in order to omit from source control).",
25-
"type": "string"
26-
},
2723
"deploymentTemplatePath": {
2824
"description": "Path to an ARM template file, or null if it should be skipped.",
2925
"type": ["string", "null"],

mlos_bench/mlos_bench/config/services/remote/azure/arm-templates/azuredeploy-ubuntu-vm.jsonc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
"description": "OS Autotune Linux VM"
2121
}
2222
},
23+
"managedIdentityName": {
24+
"type": "string",
25+
"metadata": {
26+
"description": "User managed identity name"
27+
}
28+
},
2329
"customData": {
2430
"type": "string",
2531
"defaultValue": "",
@@ -187,6 +193,12 @@
187193
"apiVersion": "2021-11-01",
188194
"name": "[parameters('vmName')]",
189195
"location": "[parameters('location')]",
196+
"identity": {
197+
"type": "userAssigned",
198+
"userAssignedIdentities": {
199+
"[resourceID('Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('managedIdentityName'))]": {}
200+
}
201+
},
190202
"properties": {
191203
"hardwareProfile": {
192204
"vmSize": "[parameters('vmSize')]"

mlos_bench/mlos_bench/config/services/remote/azure/service-linux-vm-ops.jsonc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@
1010
// can be overridden by the parameters pushed from the caller Environment.
1111
"subscription": "PLACEHOLDER; AZURE SUBSCRIPTION ID",
1212
"resourceGroup": "PLACEHOLDER; e.g., os-autotune",
13-
"managedIdentityName": "PLACEHOLDER; e.g., mlos-managed-identity",
1413

1514
"deploymentTemplatePath": "services/remote/azure/arm-templates/azuredeploy-ubuntu-vm.jsonc",
1615

1716
// Make sure to list all ARM template parameters that can be overridden by the caller.
1817
"deploymentTemplateParameters": {
19-
18+
"managedIdentityName": "PLACEHOLDER; e.g., mlos-managed-identity",
2019
"storageAccountName": "PLACEHOLDER; e.g., osatsharedstorage",
2120
"storageFileShareName": "PLACEHOLDER; e.g., os-autotune-file-share",
2221
"location": "PLACEHOLDER; e.g., westus2",

mlos_bench/mlos_bench/environments/remote/host_env.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,7 @@ def setup(self, tunables: TunableGroups, global_config: Optional[dict] = None) -
8484
if status.is_pending():
8585
(status, _) = self._host_service.wait_host_deployment(params, is_setup=True)
8686

87-
(status_id_assign, params) = self._host_service.assign_managed_identity(self._params)
88-
if status_id_assign.is_pending():
89-
(status_id_assign, _) = self._host_service.wait_host_managed_identity_assignment(params)
90-
91-
self._is_ready = status.is_succeeded() and status_id_assign.is_succeeded()
87+
self._is_ready = status.is_succeeded()
9288
return self._is_ready
9389

9490
def teardown(self) -> None:

mlos_bench/mlos_bench/services/remote/azure/azure_deployment_services.py

Lines changed: 0 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,6 @@ class AzureDeploymentService(Service, metaclass=abc.ABCMeta):
4848
"?api-version=2022-05-01"
4949
)
5050

51-
_URL_ASSIGN_IDENTITY = (
52-
"https://management.azure.com" +
53-
"/subscriptions/{subscription}" +
54-
"/resourceGroups/{resource_group}" +
55-
"/providers/Microsoft.Compute" +
56-
"/virtualMachines/{vm_name}" +
57-
"?api-version=2022-03-01"
58-
)
59-
6051
def __init__(self,
6152
config: Optional[Dict[str, Any]] = None,
6253
global_config: Optional[Dict[str, Any]] = None,
@@ -82,7 +73,6 @@ def __init__(self,
8273
check_required_params(self.config, [
8374
"subscription",
8475
"resourceGroup",
85-
"managedIdentityName"
8676
])
8777

8878
# These parameters can come from command line as strings, so conversion is needed.
@@ -402,101 +392,6 @@ def _check_deployment(self, params: dict) -> Tuple[Status, dict]: # pylint: di
402392
_LOG.error("Response: %s :: %s", response, response.text)
403393
return (Status.FAILED, {})
404394

405-
def _wait_host_managed_identity_assignment(self, params: dict) -> Tuple[Status, dict]:
406-
"""
407-
Waits for a pending operation on an Azure resource to resolve to SUCCEEDED or FAILED.
408-
Return TIMED_OUT when timing out.
409-
410-
Parameters
411-
----------
412-
params : dict
413-
Flat dictionary of (key, value) pairs of tunable parameters.
414-
415-
Returns
416-
-------
417-
result : (Status, dict)
418-
A pair of Status and result.
419-
Status is one of {PENDING, SUCCEEDED, FAILED, TIMED_OUT}
420-
Result is info on the operation runtime if SUCCEEDED, otherwise {}.
421-
"""
422-
params = self._set_default_params(params)
423-
_LOG.info("Wait for %s to %s", self._deploy_params["vmName"], "be assigned managed identity")
424-
return self._wait_while(self._check_managed_identity_assinment, Status.PENDING, params)
425-
426-
def _check_managed_identity_assinment(self, params: dict) -> Tuple[Status, dict]: # pylint: disable=too-many-return-statements
427-
"""
428-
Check if the identity is assigned to the VM.
429-
Return SUCCEEDED if true, PENDING otherwise.
430-
431-
Parameters
432-
----------
433-
_params : dict
434-
Flat dictionary of (key, value) pairs of tunable parameters.
435-
This parameter is not used; we need it for compatibility with
436-
other polling functions used in `_wait_while()`.
437-
438-
Returns
439-
-------
440-
result : (Status, dict={})
441-
A pair of Status and result. The result is always {}.
442-
Status is one of {SUCCEEDED, PENDING, FAILED}
443-
"""
444-
params = self._set_default_params(params)
445-
config = merge_parameters(
446-
dest=self.config.copy(),
447-
source=params,
448-
required_keys=[
449-
"subscription",
450-
"resourceGroup",
451-
"managedIdentityName",
452-
]
453-
)
454-
455-
vmName = self._deploy_params["vmName"]
456-
subscriptionId = config["subscription"]
457-
resourceGroup = config["resourceGroup"]
458-
managedIdentityName = config["managedIdentityName"]
459-
460-
_LOG.info("Check identity assignment: %s", vmName)
461-
462-
url = self._URL_ASSIGN_IDENTITY.format(
463-
subscription=subscriptionId,
464-
resource_group=resourceGroup,
465-
vm_name=vmName,
466-
)
467-
468-
session = self._get_session(params)
469-
try:
470-
response = session.get(url, timeout=self._request_timeout)
471-
except requests.exceptions.ReadTimeout:
472-
_LOG.warning("Request timed out after %.2f s: %s", self._request_timeout, url)
473-
return Status.RUNNING, {}
474-
except requests.exceptions.RequestException as ex:
475-
_LOG.exception("Error in request checking deployment", exc_info=ex)
476-
return (Status.FAILED, {})
477-
478-
_LOG.debug("Response: %s", response)
479-
480-
if response.status_code == 200:
481-
output = response.json()
482-
state = output.get("properties", {}).get("provisioningState", "")
483-
print("state", state)
484-
485-
print(output)
486-
mid = f"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{managedIdentityName}"
487-
if state == "Succeeded" and "identity" in output and mid in output["identity"]["userAssignedIdentities"]:
488-
return (Status.SUCCEEDED, {})
489-
elif state in {"Accepted", "Creating", "Deleting", "Running", "Updating"}:
490-
return (Status.PENDING, {})
491-
else:
492-
_LOG.error("Response: %s :: %s", response, json.dumps(output, indent=2))
493-
return (Status.FAILED, {})
494-
elif response.status_code == 404:
495-
return (Status.PENDING, {})
496-
497-
_LOG.error("Response: %s :: %s", response, response.text)
498-
return (Status.FAILED, {})
499-
500395
def _provision_resource(self, params: dict) -> Tuple[Status, dict]:
501396
"""
502397
Attempts to (re)deploy a resource.
@@ -570,74 +465,3 @@ def _provision_resource(self, params: dict) -> Tuple[Status, dict]:
570465
_LOG.error("Response: %s :: %s", response, response.text)
571466
# _LOG.error("Bad Request:\n%s", response.request.body)
572467
return (Status.FAILED, {})
573-
574-
def _assign_managed_identity(self, params: dict) -> Tuple[Status, dict]:
575-
"""
576-
Attempts to assign a managed identity to resource.
577-
578-
Parameters
579-
----------
580-
params : dict
581-
Flat dictionary of (key, value) pairs of tunable parameters.
582-
Tunables are variable parameters that, together with the
583-
Environment configuration, are sufficient to provision the resource.
584-
585-
Returns
586-
-------
587-
result : (Status, dict={})
588-
A pair of Status and result. The result is the input `params` plus the
589-
parameters extracted from the response JSON, or {} if the status is FAILED.
590-
Status is one of {PENDING, SUCCEEDED, FAILED}
591-
"""
592-
params = self._set_default_params(params)
593-
config = merge_parameters(dest=self.config.copy(), source=params)
594-
595-
vmName = self._deploy_params["vmName"]
596-
subscriptionId = config["subscription"]
597-
resourceGroup = config["resourceGroup"]
598-
managedIdentityName = config["managedIdentityName"]
599-
600-
_LOG.info("Assign managed identity: %s :: %s", vmName, params)
601-
602-
url = self._URL_ASSIGN_IDENTITY.format(
603-
subscription=subscriptionId,
604-
resource_group=resourceGroup,
605-
vm_name=vmName,
606-
)
607-
608-
json_req = {
609-
"identity": {
610-
"type": "UserAssigned",
611-
"userAssignedIdentities": {
612-
f"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{managedIdentityName}": {}
613-
}
614-
}
615-
}
616-
617-
if _LOG.isEnabledFor(logging.DEBUG):
618-
_LOG.debug("Request: PATCH %s\n%s", url, json.dumps(json_req, indent=2))
619-
620-
response = requests.patch(url, json=json_req,
621-
headers=self._get_headers(), timeout=self._request_timeout)
622-
623-
if _LOG.isEnabledFor(logging.DEBUG):
624-
_LOG.debug("Response: %s\n%s", response,
625-
json.dumps(response.json(), indent=2)
626-
if response.content else "")
627-
else:
628-
_LOG.info("Response: %s", response)
629-
630-
if response.status_code == 200:
631-
return (Status.PENDING, config)
632-
elif response.status_code == 201:
633-
output = self._extract_arm_parameters(response.json())
634-
if _LOG.isEnabledFor(logging.DEBUG):
635-
_LOG.debug("Extracted parameters:\n%s", json.dumps(output, indent=2))
636-
params.update(output)
637-
params.setdefault("asyncResultsUrl", url)
638-
params.setdefault("deploymentName", config["deploymentName"])
639-
return (Status.PENDING, params)
640-
else:
641-
_LOG.error("Response: %s :: %s", response, response.text)
642-
# _LOG.error("Bad Request:\n%s", response.request.body)
643-
return (Status.FAILED, {})

mlos_bench/mlos_bench/services/remote/azure/azure_vm_services.py

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,6 @@ def __init__(self,
131131
config, global_config, parent,
132132
self.merge_methods(methods, [
133133
# SupportsHostProvisioning
134-
self.assign_managed_identity,
135-
self.wait_host_managed_identity_assignment,
136134
self.provision_host,
137135
self.deprovision_host,
138136
self.deallocate_host,
@@ -168,9 +166,8 @@ def _set_default_params(self, params: dict) -> dict: # pylint: disable=no-sel
168166
# Try and provide a semi sane default for the deploymentName if not provided
169167
# since this is a common way to set the deploymentName and can save some
170168
# config work for the caller.
171-
deploy_params = super().deploy_params
172-
if "vmName" in deploy_params and "deploymentName" not in params:
173-
params["deploymentName"] = f"{deploy_params['vmName']}-deployment"
169+
if "vmName" in params and "deploymentName" not in params:
170+
params["deploymentName"] = f"{params['vmName']}-deployment"
174171
_LOG.info("deploymentName missing from params. Defaulting to '%s'.", params["deploymentName"])
175172
return params
176173

@@ -195,25 +192,6 @@ def wait_host_deployment(self, params: dict, *, is_setup: bool) -> Tuple[Status,
195192
"""
196193
return self._wait_deployment(params, is_setup=is_setup)
197194

198-
def wait_host_managed_identity_assignment(self, params: dict) -> Tuple[Status, dict]:
199-
"""
200-
Waits for a pending identity assignment on an Azure VM to resolve to SUCCEEDED or FAILED.
201-
Return TIMED_OUT when timing out.
202-
203-
Parameters
204-
----------
205-
params : dict
206-
Flat dictionary of (key, value) pairs of tunable parameters.
207-
208-
Returns
209-
-------
210-
result : (Status, dict)
211-
A pair of Status and result.
212-
Status is one of {PENDING, SUCCEEDED, FAILED, TIMED_OUT}
213-
Result is info on the operation runtime if SUCCEEDED, otherwise {}.
214-
"""
215-
return self._wait_host_managed_identity_assignment(params)
216-
217195
def wait_host_operation(self, params: dict) -> Tuple[Status, dict]:
218196
"""
219197
Waits for a pending operation on an Azure VM to resolve to SUCCEEDED or FAILED.
@@ -296,26 +274,6 @@ def deprovision_host(self, params: dict) -> Tuple[Status, dict]:
296274
vm_name=config["vmName"],
297275
))
298276

299-
def assign_managed_identity(self, params: dict) -> Tuple[Status, dict]:
300-
"""
301-
Assign managed identity to Azure VM
302-
303-
Parameters
304-
----------
305-
params : dict
306-
Flat dictionary of (key, value) pairs of tunable parameters.
307-
HostEnv tunables are variable parameters that, together with the
308-
HostEnv configuration, are sufficient to provision a VM.
309-
310-
Returns
311-
-------
312-
result : (Status, dict={})
313-
A pair of Status and result. The result is the input `params` plus the
314-
parameters extracted from the response JSON, or {} if the status is FAILED.
315-
Status is one of {PENDING, SUCCEEDED, FAILED}
316-
"""
317-
return self._assign_managed_identity(params)
318-
319277
def deallocate_host(self, params: dict) -> Tuple[Status, dict]:
320278
"""
321279
Deallocates the VM on Azure by shutting it down then releasing the compute resources.

0 commit comments

Comments
 (0)