Recientemente he descubierto una herramienta que en diferentes escenarios, sobre todo en el inventariado, puede sernos útil. Se llama CloudQuery y te permite exportar los datos de los recursos de tus suscripciones, de los diferentes proveedores cloud, para poder ejecutar consultas sobre ello lanzando sentencias SQL, ya que el resultado se almacena en un Postgres. En este artículo te cuento cómo configurarlo para Microsoft Azure.
Instalar CloudQuery
Lo primero que necesitas hacer es instalar la herramienta de CloudQuery en tu máquina. En mi caso estoy utilizando Mac, por lo que he ejecutado el siguiente comando usando Homebrew:
brew install cloudquery/tap/cloudquery
Si utilizas otro sistema operativo puedes ver las diferentes releases aquí.
Iniciar CloudQuery
Ahora que ya tienes la herramienta de CloudQuery instalada en tu máquina, crea un directorio, yo lo he llamado cloudquery, e inicializa la configuración dentro de él, con el siguiente comando:
cloudquery init azure
Al hacer esto genera un archivo llamado config.hcl el cual podemos personalizar, indicando de qué suscripciones queremos traernos los datos, qué tipos de recursos, etcétera.
Si no modificamos nada se traerá todos los recursos de todas las suscripciones a las que se tengan acceso. Ahora ya tenemos nuestro proyecto listo para recuperar la información de nuestras suscripciones.
Crear una base de datos Postgres en Docker
Como ya te comenté al inicio de este artículo, la información recuperada se exporta a una base de datos de tipo Postgres, por lo que vamos a necesitar una. La forma sencilla es usando un contenedor de Docker:
#Create a database in Docker
docker run -d --name postgresdb \
-p 5432:5432 \
-e POSTGRES_PASSWORD=pass \
postgres
Crear un Service Principal
Ahora que ya sabemos que queremos recuperar la información de Azure, para poder hacerlo necesitamos crear un service principal que tenga acceso a las suscripciones que queremos exportar:
SUBSCRIPTION_ID=<YOUR_SUBSCRIPTION_ID>
az account set --subscription $SUBSCRIPTION_ID
#Need to register Microsoft.Security
az provider register --namespace 'Microsoft.Security'
#Create a service principal
az ad sp create-for-rbac --name cloudquery --scopes /subscriptions/$SUBSCRIPTION_ID > auth.json
Una vez creado, y almacenada la respuesta en el archivo auth.json, utilizo la herramienta jq para almacenar la información del service principal en estas variables de entorno:
#Set variables
export AZURE_TENANT_ID=$(jq -r '.tenant' auth.json)
export AZURE_CLIENT_ID=$(jq -r '.appId' auth.json)
export AZURE_CLIENT_SECRET=$(jq -r '.password' auth.json)
export AZURE_SUBSCRIPTION_ID=$(az account show --query id -o tsv)
Asignar el service principal al rol «Application Administrator» de Azure AD
Para finalizar la configuración, necesitamos que el service principal que acabamos de crear esté asociado a un rol de Azure Active Directory llamado Application administrator, que puedes encontrarlo en el recurso de Azure AD, en el apartado Roles and administrators:
Una vez en él, busca el service principal que hemos llamado cloudquery, a través del botón Add assignments, y asócialo de manera permanente.

Volcar la información en el Postgres con CloudQuery
Ahora, lo único que falta es recuperar la información con CloudQuery. Para ello sólo tienes que ejecutar un único comando:
#Fetch the information into the database
cloudquery fetch --dsn "postgres://postgres:pass@localhost:5432/postgres?sslmode=disable"
Este utiliza las variables de entorno que hemos configurado anteriormente, con la información de nuestro service principal, y el postgres que hemos generado en Docker. Una vez que el proceso finalice, verás que tienes un montón de tablas generadas (para este ejemplo he usado DataGrip como GUI):
Podrás hacer consultas como estas, simplemente para recuperar recursos de un tipo concreto:
SELECT * from azure_compute_virtual_machines;
SELECT * from azure_web_apps;
O ir más allá y consultar sobre estos aspectos que para ti pueden ser importante y necesitas validar o generar un informe sobre ellos. Como por ejemplo: «Dime qué cuentas de almacenamientos tienen habilitado el acceso público». Sería algo tan sencillo como esto:
SELECT * from azure_storage_accounts where allow_blob_public_access is null
¡Saludos!