Installing CDV on an Azure virtual machine (VM) - Adaptive Applications - BlueCat Gateway - 23.3.2

Cloud Discovery & Visibility Administration Guide

Product name
BlueCat Gateway

If you use Microsoft Azure as a resource provider, you can deploy Cloud Discovery & Visibility (CDV) on a virtual machine (VM) running in the Azure environment.

Note: Deployment of CDV is not supported on Azure Container Instances (ACIs).
  • Azure Container Instances are (by default) stateless. This means CDV can't access mounted database volumes while running on ACIs, which makes it impossible for CDV data to persist when the container is restarted.

  • CDV for Azure is designed for deployment on VMs. It can detect when it is running on a Cloud VM, but currently can't automatically detect when it is running on an ACI.

When deploying CDV on Azure infrastructure, BlueCat recommends doing so on Azure virtual machines (VMs) instead.

To set up CDV to run on a VM on Microsoft Azure:

  1. In Microsoft Azure, create a virtual machine (VM) that will host CDV. Typically, you can do so from the Azure portal.

    When configuring the new VM:
    1. Within the Management tab, under the Azure AD section, select the Login with Azure AD checkbox.

    2. Fill in the rest of the fields as needed for your system and organization.

    3. When you're done, click Review + create.

  2. Assign a role for the VM that allows access to all resources in its subscription:
    1. Go to the subscription page and click the subscription you want to use.

    2. In the navigator portion of the subscription detail page (on the left under the Search box), click Access Control (IAM).

    3. (Optional) If you want to use a custom role with a customized set of permissions, click Add, then select Add Custom Role. (If you don't create a custom role, you'll use standard Azure roles.)

      Add to the custom role the appropriate permissions needed for CDV to work with Azure environments. For a list of needed permissions, see Microsoft Azure environments .

    4. Click Add Role Assignment.
    5. Add the appropriate roles:

      • If you created a custom role, select it.

      • Otherwise, if you're using CDV for Discovery, select the Reader role. If you're also using CDV for Visibility, also select the Contributor role.

      When you've selected the roles, click Next.

    6. Click the Members tab, then in Assign access to, select Managed Identity.

    7. Click Select members, then select the VM that you just created.

    8. When you're done, click Review and assign.

      You can now continue with the standard procedure for setting up a CDV image. For more details, see Installing the Cloud Discovery & Visibility Docker image.

Testing your new VM

To test whether the VM and its roles were configured correctly, you can open an SSH client in the VM and run a script.

First, open an SSH client in the VM:

  1. If you haven't already done so, open Port 22 to make sure that SSH communications are allowed at the VM level.

    To do so:
    1. Sign in to your Azure Portal.

    2. In the navigator on the left, click Virtual Machines, then click on your virtual machine.

    3. In the Settings section, click Networking.

      You should see a list of existing inbound port rules (click the Inbound port rules tab if another list is displayed).

    4. Click Add inbound port rule. Configure the rule as follows:
      1. Typically, you can leave Source, Source port ranges, and Destination at their default values.

      2. For Service, choose SSH. The Destination port ranges and Protocol values should automatically change to 22 and TCP.

      3. For Action, choose Allow.

      4. For Priority, you can change the relative priority based on existing inbound rules. If you're not sure, use the default value.

      5. When you're done, click Add.

  2. Connect to the VM using an SSH client, such as PuTTY or OpenSSH.

Then, create the following test files requirements.txt and

The requirements.txt file:


The script file

from azure.identity import ManagedIdentityCredential
from azure.mgmt.compute import ComputeManagementClient
from import NetworkManagementClient
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.subscription import SubscriptionClient
scope = ''
credential = ManagedIdentityCredential()
def subscriptions():
sub_client = SubscriptionClient(credential)
subs = sub_client.subscriptions.list()
return [{"id": sub.subscription_id, "name": sub.display_name} for sub in subs]
def resource_groups(sub_id):
group_client = ResourceManagementClient(credential, sub_id)
groups = list(group_client.resource_groups.list())
return [ for group in groups]
def vnets(sub_id, group):
vnet_client = NetworkManagementClient(credential, sub_id)
vnets = list(vnet_client.virtual_networks.list(group))
print("list of virtual networks: {}".format(vnets))
def vms(sub_id, group):
compute_client = ComputeManagementClient(credential, sub_id)
vms = list(compute_client.virtual_machines.list(group))
print("list of virtual machines: {}".format(vms))
if __name__ == '__main__':
subs = subscriptions()
for sub in subs:
sub_name = sub.get("name")
sub_id = sub.get("id")
print("Subscription: " + sub_name)
groups = resource_groups(sub_id)
for group in groups:
print("resource group: {}".format(group))
vnets(sub_id, group)
vms(sub_id, group)

Run the following commands to download the necessary Python library to run the script:

sudo apt update
sudo apt install python3-pip
pip3 install -r requirements.txt

Finally, you can run the test script using Python:


Assuming that the VM was configured correctly and the resource groups have both virtual machines and virtual networks, your results should look similar to the following:

Subscription: eng-sandbox-cloud-integration

resource group: rg-yk
list of virtual networks: [< object at 0x7f35160af7f0>]
list of virtual machines: [<azure.mgmt.compute.v2021_07_01.models._models_py3.VirtualMachine object at 0x7f35160b3160>]
resource group: n-test
list of virtual networks: [< object at 0x7f351612ab80>]
list of virtual machines: [<azure.mgmt.compute.v2021_07_01.models._models_py3.VirtualMachine object at 0x7f3516125af0>, <azure.mgmt.compute.v2021_07_01.models._models_py3.VirtualMachine object at 0x7f3516125880>]
resource group: tnguyen
list of virtual networks: [< object at 0x7f35160b64c0>]
list of virtual machines: [<azure.mgmt.compute.v2021_07_01.models._models_py3.VirtualMachine object at 0x7f35160b6cd0>]
resource group: ptstest
list of virtual networks: [< object at 0x7f3517855700>]
list of virtual machines: []

If the VM is incorrectly configured, your results will look similar to the following:

ImdsCredential.get_token failed: ManagedIdentityCredential authentication unavailable. No identity has been assigned to this resource.
ManagedIdentityCredential.get_token failed: ManagedIdentityCredential authentication unavailable. No identity has been assigned to this resource.
Traceback (most recent call last):
  File "/home/azureuser/.local/lib/python3.8/site-packages/azure/identity/_credentials/", line 97, in _request_token
    token = self._client.request_token(*scopes, headers={"Metadata": "true"})
  File "/home/azureuser/.local/lib/python3.8/site-packages/azure/identity/_internal/", line 124, in request_token
    token = self._process_response(response, request_time)
  File "/home/azureuser/.local/lib/python3.8/site-packages/azure/identity/_internal/", line 67, in _process_response
    raise ClientAuthenticationError(
azure.core.exceptions.ClientAuthenticationError: Unexpected response "{'error': 'invalid_request', 'error_description': 'Identity not found'}"
Content: {"error":"invalid_request","error_description":"Identity not found"}
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "", line 5, in <module>
    token = credential.get_token(scope)
  File "/home/azureuser/.local/lib/python3.8/site-packages/azure/identity/_internal/", line 30, in wrapper
    token = fn(*args, **kwargs)
  File "/home/azureuser/.local/lib/python3.8/site-packages/azure/identity/_credentials/", line 119, in get_token
    return self._credential.get_token(*scopes, **kwargs)
  File "/home/azureuser/.local/lib/python3.8/site-packages/azure/identity/_internal/", line 76, in get_token
    token = self._request_token(*scopes, **kwargs)
  File "/home/azureuser/.local/lib/python3.8/site-packages/azure/identity/_credentials/", line 108, in _request_token
    six.raise_from(CredentialUnavailableError(message=self._error_message), ex)
  File "<string>", line 3, in raise_from
azure.identity._exceptions.CredentialUnavailableError: ManagedIdentityCredential authentication unavailable. No identity has been assigned to this resource.