Azure CLI es la herramienta oficial de Microsoft para gestionar recursos de Azure desde la terminal con el comando az: suscripciones, grupos de recursos, máquinas virtuales, almacenamiento y el resto de servicios. En este tutorial instalarás Azure CLI en Ubuntu 24.04 desde el repositorio oficial de Microsoft, iniciarás sesión desde un servidor sin navegador, organizarás recursos en un grupo, subirás archivos a Blob Storage y crearás un service principal con permisos limitados para ejecutar tareas automáticas.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con arquitectura x86_64 o arm64.
- Un usuario no root con privilegios
sudo. - Una cuenta de Microsoft Azure con una suscripción activa y el rol Propietario (Owner) sobre ella o sobre un grupo de recursos, necesario para asignar roles en el paso 7.
Paso 1: Añadir el repositorio de Microsoft
Instalar desde el repositorio de Microsoft permite actualizar Azure CLI con apt. Instala las dependencias necesarias:
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
Descarga la clave de firma de Microsoft y guárdala en /etc/apt/keyrings:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | sudo tee /etc/apt/keyrings/microsoft.gpg > /dev/null
sudo chmod go+r /etc/apt/keyrings/microsoft.gpg
Crea el archivo del repositorio en formato deb822. El nombre en clave de la versión (noble en Ubuntu 24.04) y la arquitectura se obtienen automáticamente:
echo "Types: deb
URIs: https://packages.microsoft.com/repos/azure-cli/
Suites: $(lsb_release -cs)
Components: main
Architectures: $(dpkg --print-architecture)
Signed-by: /etc/apt/keyrings/microsoft.gpg" | sudo tee /etc/apt/sources.list.d/azure-cli.sources
Paso 2: Instalar Azure CLI
Actualiza el índice de paquetes e instala azure-cli:
sudo apt update
sudo apt install -y azure-cli
Comprueba que el comando funciona:
az version
{
"azure-cli": "2.xx.x",
"azure-cli-core": "2.xx.x",
"azure-cli-telemetry": "1.1.0",
"extensions": {}
}
NotaMicrosoft también ofrece el script
https://aka.ms/InstallAzureCLIDeb, que ejecuta estos mismos pasos. Hacerlos a mano, como aquí, te permite ver exactamente qué repositorio y qué clave se añaden al sistema.
Paso 3: Iniciar sesión sin navegador
az login intenta abrir un navegador, algo que no existe en un servidor remoto. Usa el flujo de código de dispositivo:
az login --use-device-code
El comando muestra un mensaje como este:
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code ABCD1234 to authenticate.
Abre esa página en el navegador de tu ordenador, introduce el código e inicia sesión con tu cuenta de Azure. Al terminar, la terminal muestra las suscripciones a las que tienes acceso y, si hay más de una, te pide que elijas la que se usará por defecto.
Los tokens se guardan en ~/.azure del usuario actual y se renuevan solos, así que no tendrás que repetir el inicio de sesión en cada comando.
Paso 4: Seleccionar la suscripción activa
Cada comando de az actúa sobre una suscripción. Lista las disponibles:
az account list --output table
Name CloudName SubscriptionId TenantId State IsDefault
-------------------- ----------- ------------------------------------ ------------------------------------ ------- -----------
Producción AzureCloud 11111111-1111-1111-1111-111111111111 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa Enabled True
Pruebas AzureCloud 22222222-2222-2222-2222-222222222222 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa Enabled False
Cambia la suscripción activa por nombre o por ID:
az account set --subscription "Pruebas"
Comprueba cuál está activa. --query filtra la respuesta con sintaxis JMESPath y --output elige el formato de la respuesta:
az account show --query "{nombre:name, id:id}" --output table
Paso 5: Configurar valores por defecto
Por defecto az responde en JSON. Si prefieres tablas para el trabajo interactivo, cambia el formato de salida global:
az config set core.output=table
También puedes fijar un grupo de recursos y una región por defecto para no repetirlos en cada comando. Hazlo después de crear el grupo en el paso siguiente:
az configure --defaults group=mi-grupo location=westeurope
Estos ajustes se guardan en ~/.azure/config. Consulta los valores por defecto activos con az configure --list-defaults.
Paso 6: Crear un grupo de recursos y una cuenta de almacenamiento
Un grupo de recursos es un contenedor lógico: todo lo que creas en Azure pertenece a uno, y borrar el grupo borra todo su contenido. Crea uno en la región de Europa Occidental:
az group create --name mi-grupo --location westeurope
Crea una cuenta de almacenamiento dentro del grupo. Su nombre es global en Azure, debe tener entre 3 y 24 caracteres y solo puede contener minúsculas y números:
az storage account create \
--name tualmacenamiento \
--resource-group mi-grupo \
--location westeurope \
--sku Standard_LRS \
--min-tls-version TLS1_2 \
--allow-blob-public-access false
Crea un contenedor de blobs para las copias de seguridad. --auth-mode login usa tu identidad de Azure en lugar de las claves de la cuenta de almacenamiento, pero requiere un rol de datos. Asígnate el rol Storage Blob Data Contributor sobre la cuenta:
az role assignment create \
--assignee "$(az ad signed-in-user show --query id --output tsv)" \
--role "Storage Blob Data Contributor" \
--scope "$(az storage account show --name tualmacenamiento --resource-group mi-grupo --query id --output tsv)"
La asignación puede tardar uno o dos minutos en aplicarse. Después, crea el contenedor y sube un archivo de prueba:
az storage container create --account-name tualmacenamiento --name backups --auth-mode login
echo "prueba" > /tmp/prueba.txt
az storage blob upload --account-name tualmacenamiento --container-name backups \
--name prueba.txt --file /tmp/prueba.txt --auth-mode login
Lista el contenido del contenedor para verificar la subida:
az storage blob list --account-name tualmacenamiento --container-name backups \
--auth-mode login --query "[].{nombre:name, bytes:properties.contentLength}" --output table
Nombre Bytes
---------- -------
prueba.txt 7
Paso 7: Crear un service principal para automatizar tareas
Para scripts que se ejecutan sin intervención, como una copia nocturna, no uses tu cuenta personal. Crea un service principal, una identidad de aplicación, y dale solo el rol que necesita sobre la cuenta de almacenamiento:
SCOPE=$(az storage account show --name tualmacenamiento --resource-group mi-grupo --query id --output tsv)
az ad sp create-for-rbac --name sp-backup-servidor --role "Storage Blob Data Contributor" --scopes "$SCOPE"
La salida contiene las credenciales:
{
"appId": "33333333-3333-3333-3333-333333333333",
"displayName": "sp-backup-servidor",
"password": "xxxx~xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tenant": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
}
AdvertenciaEl valor de
passwordsolo se muestra ahora. Guárdalo en un lugar seguro y no lo pongas nunca en scripts versionados ni en el historial de la shell. El secreto caduca por defecto al cabo de un año; renuévalo conaz ad sp credential reset --id <appId>.
En el servidor, crea un usuario de sistema para las copias y guarda el secreto en un archivo que solo él pueda leer. Sustituye el valor por el password real:
sudo useradd --system --create-home --home-dir /var/lib/azbackup --shell /usr/sbin/nologin azbackup
sudo install -d -m 700 -o azbackup -g azbackup /var/lib/azbackup/.secrets
sudo -u azbackup sh -c 'umask 077; cat > /var/lib/azbackup/.secrets/sp-secret' <<'EOF'
xxxx~xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
EOF
Inicia sesión como el service principal con ese usuario. Sustituye APP_ID y TENANT_ID por los valores de la salida anterior. --allow-no-subscriptions evita un error si el service principal no tiene roles a nivel de suscripción, como en este caso:
sudo -u azbackup -H sh -c 'az login --service-principal -u APP_ID -p "$(cat /var/lib/azbackup/.secrets/sp-secret)" --tenant TENANT_ID --allow-no-subscriptions --output none'
Comprueba que la sesión queda guardada y que el service principal puede escribir en el contenedor:
sudo -u azbackup -H az storage blob upload --account-name tualmacenamiento --container-name backups \
--name prueba-sp.txt --file /tmp/prueba.txt --auth-mode login --overwrite --output none
sudo -u azbackup -H az storage blob list --account-name tualmacenamiento --container-name backups \
--auth-mode login --query "[].name" --output tsv
prueba-sp.txt
prueba.txt
La sesión del service principal se guarda en /var/lib/azbackup/.azure y la CLI renueva el token automáticamente, así que los scripts que ejecute este usuario pueden llamar a az sin volver a iniciar sesión.
Paso 8: Programar una copia de seguridad diaria
Con el service principal configurado, un script corto basta para empaquetar un directorio y subirlo. Crea el script:
sudo nano /usr/local/bin/backup-azure.sh
#!/usr/bin/env bash
set -euo pipefail
ORIGEN="/var/www"
CUENTA="tualmacenamiento"
CONTENEDOR="backups"
ARCHIVO="www-$(hostname -s)-$(date +%F).tar.gz"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
tar -czf "$TMP/$ARCHIVO" -C "$(dirname "$ORIGEN")" "$(basename "$ORIGEN")"
az storage blob upload \
--account-name "$CUENTA" \
--container-name "$CONTENEDOR" \
--name "$ARCHIVO" \
--file "$TMP/$ARCHIVO" \
--auth-mode login \
--overwrite \
--output none
echo "Subido $ARCHIVO"
Hazlo ejecutable y pruébalo con el usuario azbackup, que necesita permiso de lectura sobre el directorio de origen:
sudo chmod 755 /usr/local/bin/backup-azure.sh
sudo -u azbackup -H /usr/local/bin/backup-azure.sh
Subido www-mi-servidor-2026-09-25.tar.gz
Programa su ejecución diaria a las 3:30 con un temporizador de systemd. Crea el servicio:
sudo nano /etc/systemd/system/backup-azure.service
[Unit]
Description=Copia de /var/www a Azure Blob Storage
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
User=azbackup
Environment=HOME=/var/lib/azbackup
ExecStart=/usr/local/bin/backup-azure.sh
Y el temporizador:
sudo nano /etc/systemd/system/backup-azure.timer
[Unit]
Description=Copia diaria a Azure Blob Storage
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
[Install]
WantedBy=timers.target
Activa el temporizador y comprueba la próxima ejecución:
sudo systemctl daemon-reload
sudo systemctl enable --now backup-azure.timer
systemctl list-timers backup-azure.timer
Para lanzarlo manualmente y ver el resultado, ejecuta sudo systemctl start backup-azure.service y después journalctl -u backup-azure.service -n 20.
Paso 9: Actualizar Azure CLI
Como la instalación viene del repositorio de Microsoft, Azure CLI se actualiza con el resto del sistema:
sudo apt update
sudo apt install --only-upgrade azure-cli
Solución de problemas
Please run 'az login' to setup account. El usuario que ejecuta el comando no tiene sesión iniciada. Recuerda que cada usuario del sistema tiene su propio ~/.azure: inicia sesión con el mismo usuario que ejecutará los comandos, por ejemplo azbackup.
AuthorizationPermissionMismatch o This request is not authorized to perform this operation al usar blobs. Con --auth-mode login hace falta un rol de datos, como Storage Blob Data Contributor; los roles Propietario o Colaborador no dan acceso a los datos por sí solos. Comprueba las asignaciones con az role assignment list --scope "$SCOPE" --output table y espera un par de minutos tras crear una.
AADSTS7000215: Invalid client secret provided. El secreto del service principal es incorrecto o ha caducado. Genera uno nuevo con az ad sp credential reset --id APP_ID, actualiza el archivo de secreto e inicia sesión de nuevo.
The subscription ... could not be found. La suscripción activa no es la que esperas. Revisa la lista con az account list --output table y cámbiala con az account set.
Conclusión
Has instalado Azure CLI en Ubuntu 24.04 desde el repositorio de Microsoft, has iniciado sesión con código de dispositivo, has creado un grupo de recursos y una cuenta de almacenamiento, y has automatizado una copia diaria con un service principal limitado a esa cuenta. Como siguientes pasos puedes añadir una política de administración del ciclo de vida a la cuenta de almacenamiento para borrar copias antiguas, crear máquinas virtuales con az vm create, o describir tus recursos con plantillas Bicep y desplegarlas con az deployment group create.
