use managed identity reader access for scaleset configs (#1060)

This commit is contained in:
bmc-msft
2021-07-13 13:20:50 -04:00
committed by GitHub
parent 7a7ded6b7e
commit 39beb1591c
4 changed files with 80 additions and 45 deletions

View File

@ -217,6 +217,15 @@ def get_container_sas_url(
) )
def get_file_url(container: Container, name: str, storage_type: StorageType) -> str:
client = find_container(container, storage_type)
if not client:
raise Exception("unable to find container: %s - %s" % (container, storage_type))
# get_url has a trailing '/'
return f"{get_url(client.account_name)}{container}/{name}"
def get_file_sas_url( def get_file_sas_url(
container: Container, container: Container,
name: str, name: str,

View File

@ -212,6 +212,7 @@ def update_extensions(name: UUID, extensions: List[Any]) -> None:
str(name), str(name),
{"virtual_machine_profile": {"extension_profile": {"extensions": extensions}}}, {"virtual_machine_profile": {"extension_profile": {"extensions": extensions}}},
) )
logging.info("VM extensions updated: %s", name)
def create_vmss( def create_vmss(

View File

@ -11,7 +11,12 @@ from onefuzztypes.enums import OS, AgentMode
from onefuzztypes.models import AgentConfig, Pool, ReproConfig, Scaleset from onefuzztypes.models import AgentConfig, Pool, ReproConfig, Scaleset
from onefuzztypes.primitives import Container, Extension, Region from onefuzztypes.primitives import Container, Extension, Region
from .azure.containers import get_container_sas_url, get_file_sas_url, save_blob from .azure.containers import (
get_container_sas_url,
get_file_sas_url,
get_file_url,
save_blob,
)
from .azure.creds import get_instance_id, get_instance_url from .azure.creds import get_instance_id, get_instance_url
from .azure.monitor import get_monitor_settings from .azure.monitor import get_monitor_settings
from .azure.queue import get_queue_sas from .azure.queue import get_queue_sas
@ -94,9 +99,7 @@ def build_scaleset_script(pool: Pool, scaleset: Scaleset) -> str:
save_blob( save_blob(
Container("vm-scripts"), filename, sep.join(commands) + sep, StorageType.config Container("vm-scripts"), filename, sep.join(commands) + sep, StorageType.config
) )
return get_file_sas_url( return get_file_url(Container("vm-scripts"), filename, StorageType.config)
Container("vm-scripts"), filename, StorageType.config, read=True
)
def build_pool_config(pool: Pool) -> str: def build_pool_config(pool: Pool) -> str:
@ -126,12 +129,7 @@ def build_pool_config(pool: Pool) -> str:
StorageType.config, StorageType.config,
) )
return get_file_sas_url( return config_url(Container("vm-scripts"), filename, False)
Container("vm-scripts"),
filename,
StorageType.config,
read=True,
)
def update_managed_scripts() -> None: def update_managed_scripts() -> None:
@ -167,8 +165,20 @@ def update_managed_scripts() -> None:
) )
def config_url(container: Container, filename: str, with_sas: bool) -> str:
if with_sas:
return get_file_sas_url(container, filename, StorageType.config, read=True)
else:
return get_file_url(container, filename, StorageType.config)
def agent_config( def agent_config(
region: Region, vm_os: OS, mode: AgentMode, *, urls: Optional[List[str]] = None region: Region,
vm_os: OS,
mode: AgentMode,
*,
urls: Optional[List[str]] = None,
with_sas: bool = False,
) -> Extension: ) -> Extension:
update_managed_scripts() update_managed_scripts()
@ -177,29 +187,17 @@ def agent_config(
if vm_os == OS.windows: if vm_os == OS.windows:
urls += [ urls += [
get_file_sas_url( config_url(Container("vm-scripts"), "managed.ps1", with_sas),
Container("vm-scripts"), config_url(Container("tools"), "win64/azcopy.exe", with_sas),
"managed.ps1", config_url(
StorageType.config,
read=True,
),
get_file_sas_url(
Container("tools"),
"win64/azcopy.exe",
StorageType.config,
read=True,
),
get_file_sas_url(
Container("tools"), Container("tools"),
"win64/setup.ps1", "win64/setup.ps1",
StorageType.config, with_sas,
read=True,
), ),
get_file_sas_url( config_url(
Container("tools"), Container("tools"),
"win64/onefuzz.ps1", "win64/onefuzz.ps1",
StorageType.config, with_sas,
read=True,
), ),
] ]
to_execute_cmd = ( to_execute_cmd = (
@ -214,29 +212,31 @@ def agent_config(
"force_update_tag": uuid4(), "force_update_tag": uuid4(),
"type_handler_version": "1.9", "type_handler_version": "1.9",
"auto_upgrade_minor_version": True, "auto_upgrade_minor_version": True,
"settings": {"commandToExecute": to_execute_cmd, "fileUris": urls}, "settings": {
"protectedSettings": {}, "commandToExecute": to_execute_cmd,
"fileUris": urls,
},
"protectedSettings": {
"managedIdentity": {},
},
} }
return extension return extension
elif vm_os == OS.linux: elif vm_os == OS.linux:
urls += [ urls += [
get_file_sas_url( config_url(
Container("vm-scripts"), Container("vm-scripts"),
"managed.sh", "managed.sh",
StorageType.config, with_sas,
read=True,
), ),
get_file_sas_url( config_url(
Container("tools"), Container("tools"),
"linux/azcopy", "linux/azcopy",
StorageType.config, with_sas,
read=True,
), ),
get_file_sas_url( config_url(
Container("tools"), Container("tools"),
"linux/setup.sh", "linux/setup.sh",
StorageType.config, with_sas,
read=True,
), ),
] ]
to_execute_cmd = "sh setup.sh %s" % (mode.name) to_execute_cmd = "sh setup.sh %s" % (mode.name)
@ -247,10 +247,15 @@ def agent_config(
"type": "CustomScript", "type": "CustomScript",
"typeHandlerVersion": "2.1", "typeHandlerVersion": "2.1",
"location": region, "location": region,
"autoUpgradeMinorVersion": True,
"force_update_tag": uuid4(), "force_update_tag": uuid4(),
"settings": {"commandToExecute": to_execute_cmd, "fileUris": urls}, "autoUpgradeMinorVersion": True,
"protectedSettings": {}, "settings": {
"commandToExecute": to_execute_cmd,
"fileUris": urls,
},
"protectedSettings": {
"managedIdentity": {},
},
} }
return extension return extension
@ -337,7 +342,9 @@ def repro_extensions(
), ),
] ]
base_extension = agent_config(region, repro_os, AgentMode.repro, urls=urls) base_extension = agent_config(
region, repro_os, AgentMode.repro, urls=urls, with_sas=True
)
extensions = generic_extensions(region, repro_os) extensions = generic_extensions(region, repro_os)
extensions += [base_extension] extensions += [base_extension]
return extensions return extensions
@ -359,7 +366,9 @@ def proxy_manager_extensions(region: Region, proxy_id: UUID) -> List[Extension]:
), ),
] ]
base_extension = agent_config(region, OS.linux, AgentMode.proxy, urls=urls) base_extension = agent_config(
region, OS.linux, AgentMode.proxy, urls=urls, with_sas=True
)
extensions = generic_extensions(region, OS.linux) extensions = generic_extensions(region, OS.linux)
extensions += [base_extension] extensions += [base_extension]
return extensions return extensions

View File

@ -66,6 +66,7 @@
"Network Contributor": "4d97b98b-1d4f-4787-a291-c67834d212e7", "Network Contributor": "4d97b98b-1d4f-4787-a291-c67834d212e7",
"Storage Account Contributor": "17d1049b-9a84-46fb-8f53-869881c3d3ab", "Storage Account Contributor": "17d1049b-9a84-46fb-8f53-869881c3d3ab",
"Virtual Machine Contributor": "9980e02c-c2be-4d73-94e8-173b1dc7cf3c", "Virtual Machine Contributor": "9980e02c-c2be-4d73-94e8-173b1dc7cf3c",
"Storage Blob Data Reader": "2a2b9908-6ea1-4ae2-8e65-a410df84e7d1",
"keyVaultName": "[concat('of-kv-', uniquestring(resourceGroup().id))]" "keyVaultName": "[concat('of-kv-', uniquestring(resourceGroup().id))]"
}, },
"functions": [ "functions": [
@ -744,6 +745,21 @@
"OWNER": "[parameters('owner')]" "OWNER": "[parameters('owner')]"
} }
}, },
{
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2018-07-01",
"name": "[guid(concat(resourceGroup().id, '-user_managed_idenity_read_blob'))]",
"properties": {
"roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('Storage Blob Data Reader'))]",
"principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('scaleset_identity')), '2018-11-30', 'Full').properties.principalId]"
},
"DependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]"
],
"tags": {
"OWNER": "[parameters('owner')]"
}
},
{ {
"type": "Microsoft.SignalRService/SignalR", "type": "Microsoft.SignalRService/SignalR",
"apiVersion": "2018-10-01", "apiVersion": "2018-10-01",