Haz inventario de Microsoft Azure con CloudQuery

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.

cloudquery init genera el archivo config.hcl

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:

Azure AD – Roles and administrators – Application Administrator

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.

Agregar el service principal al rol Application Administrator

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):

92 tablas generadas CloudQuery en Postgres

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!