# Buggy code
def get_vm_format_secret(cmd, secrets, certificate_store=None):
    from azure.mgmt.keyvault import KeyVaultManagementClient
    from azure.keyvault import KeyVaultId
    import re

    client = get_mgmt_service_client(cmd.cli_ctx, KeyVaultManagementClient).vaults
    grouped_secrets = {}

    merged_secrets = []
    for s in secrets:
        merged_secrets += s.splitlines()

    # group secrets by source vault
    for secret in merged_secrets:
        parsed = KeyVaultId.parse_secret_id(secret)
        match = re.search("://(.+?)\\.", parsed.vault)
        vault_name = match.group(1)
        if vault_name not in grouped_secrets:
            grouped_secrets[vault_name] = {
                "vaultCertificates": [],
                "id": _get_vault_id_from_name(cmd.cli_ctx, client, vault_name),
            }

        vault_cert = {"certificateUrl": secret}
        if certificate_store:
            vault_cert["certificateStore"] = certificate_store

        grouped_secrets[vault_name]["vaultCertificates"].append(vault_cert)

    # transform the reduced map to vm format
    formatted = [
        {
            "sourceVault": {"id": value["id"]},
            "vaultCertificates": value["vaultCertificates"],
        }
        for _, value in list(grouped_secrets.items())
    ]

    return formatted


# Traceback (msrest.exceptions.ValidationError)
I am following these steps to try to build a LINUX VM with SSL certificate.

https://docs.microsoft.com/en-us/azure/virtual-machines/linux/tutorial-secure-web-server

But I am failing at following step.

$ secret=$(az keyvault secret list-versions --vault-name WebSvrCert --name WebCert --query "[?attributes.enabled].id" --output tsv)

$ echo $secret
https://websvrcert.vault.azure.net/secrets/WebCert/d79e98486c5f42a6a12c863608b3a6e8

$ vm_secret=$(az vm secret format --secret "$secret")
Parameter 'resource_group_name' can not be None.
Traceback (most recent call last):
File "/opt/az/lib/python3.6/site-packages/knack/cli.py", line 194, in invoke
cmd_result = self.invocation.execute(args)
File "/opt/az/lib/python3.6/site-packages/azure/cli/core/commands/init.py", line 331, in execute
six.reraise(*sys.exc_info())
File "/opt/az/lib/python3.6/site-packages/six.py", line 693, in reraise
raise value
File "/opt/az/lib/python3.6/site-packages/azure/cli/core/commands/init.py", line 304, in execute
result = cmd(params)
File "/opt/az/lib/python3.6/site-packages/azure/cli/core/commands/init.py", line 168, in call
return super(AzCliCommand, self).call(*args, **kwargs)
File "/opt/az/lib/python3.6/site-packages/knack/commands.py", line 109, in call
return self.handler(*args, **kwargs)
File "/opt/az/lib/python3.6/site-packages/azure/cli/core/init.py", line 348, in default_command_handler
result = op(**command_args)
File "/opt/az/lib/python3.6/site-packages/azure/cli/command_modules/vm/custom.py", line 1429, in get_vm_format_secret
'id': _get_vault_id_from_name(cmd.cli_ctx, client, vault_name)
File "/opt/az/lib/python3.6/site-packages/azure/cli/command_modules/vm/custom.py", line 1406, in _get_vault_id_from_name
vault = client.get(group_name, vault_name)
File "/opt/az/lib/python3.6/site-packages/azure/mgmt/keyvault/operations/vaults_operations.py", line 193, in get
'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str'),
File "/opt/az/lib/python3.6/site-packages/msrest/serialization.py", line 488, in url
data = self.validate(data, name, required=True, **kwargs)
File "/opt/az/lib/python3.6/site-packages/msrest/serialization.py", line 558, in validate
raise ValidationError("required", name, True)
msrest.exceptions.ValidationError: Parameter 'resource_group_name' can not be None.
chi@Azure:~/clouddrive$

# Fixed code
def get_vm_format_secret(
    cmd, secrets, certificate_store=None, keyvault=None, resource_group_name=None
):
    from azure.mgmt.keyvault import KeyVaultManagementClient
    from azure.keyvault import KeyVaultId
    import re

    client = get_mgmt_service_client(cmd.cli_ctx, KeyVaultManagementClient).vaults
    grouped_secrets = {}

    merged_secrets = []
    for s in secrets:
        merged_secrets += s.splitlines()

    # group secrets by source vault
    for secret in merged_secrets:
        parsed = KeyVaultId.parse_secret_id(secret)
        match = re.search("://(.+?)\\.", parsed.vault)
        vault_name = match.group(1)
        if vault_name not in grouped_secrets:
            grouped_secrets[vault_name] = {
                "vaultCertificates": [],
                "id": keyvault
                or _get_vault_id_from_name(cmd.cli_ctx, client, vault_name),
            }

        vault_cert = {"certificateUrl": secret}
        if certificate_store:
            vault_cert["certificateStore"] = certificate_store

        grouped_secrets[vault_name]["vaultCertificates"].append(vault_cert)

    # transform the reduced map to vm format
    formatted = [
        {
            "sourceVault": {"id": value["id"]},
            "vaultCertificates": value["vaultCertificates"],
        }
        for _, value in list(grouped_secrets.items())
    ]

    return formatted