--- title: "Cómo instalar Ansible AWX en Ubuntu 24.04 con k3s" description: "Instala Ansible AWX con AWX Operator sobre k3s en Ubuntu 24.04, publícalo con HTTPS de Let's Encrypt y lanza tu primer playbook desde la interfaz web." category: "Automatización e IaC" language: es source: https://cubepath.com/es/docs/automatización-e-iac/instalacion-de-ansible-awx-tower updated: 2026-09-25 --- # Cómo instalar Ansible AWX en Ubuntu 24.04 con k3s AWX es el proyecto de código abierto del que deriva Red Hat Ansible Automation Platform (antes Ansible Tower). Añade a Ansible una interfaz web, una API REST, gestión centralizada de credenciales, inventarios, permisos por usuario y equipo, y un historial de todas las ejecuciones. La única forma de instalación soportada es **AWX Operator** sobre Kubernetes, así que en este tutorial montarás un Kubernetes ligero de un solo nodo con k3s en Ubuntu 24.04, desplegarás AWX con el operador, lo publicarás con HTTPS y ejecutarás tu primer playbook desde la interfaz. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS dedicado a AWX, por ejemplo un VPS de CubePath, con al menos 4 vCPU, 8 GB de RAM y 40 GB de disco. AWX ejecuta PostgreSQL, la web, el planificador de tareas y los contenedores de cada ejecución, y con menos memoria los pods se quedan en `Pending` o se reinician. - Un usuario no root con privilegios `sudo`. - Un dominio con un registro DNS de tipo A (`awx.your_domain`) apuntando a la IP pública del servidor, para el certificado HTTPS. - Una dirección de correo para el registro en Let's Encrypt. > Nota: el proyecto AWX está en pausa de nuevas versiones mientras se reestructura; la última versión publicada es AWX 24.6.1, que instala AWX Operator 2.19.1. Consulta la página de versiones de `ansible/awx-operator` en GitHub antes de empezar y, si hay una más reciente, usa esa etiqueta en el paso 5. ## Paso 1: Preparar el servidor y el cortafuegos Actualiza el sistema e instala `git`, que `kubectl` necesita para descargar los manifiestos del operador desde GitHub: ```bash sudo apt update && sudo apt upgrade -y sudo apt install git curl ``` Configura UFW. Además de SSH, HTTP y HTTPS, k3s necesita que se permita el tráfico de las redes internas de pods (`10.42.0.0/16`) y servicios (`10.43.0.0/16`); sin estas reglas, los pods no pueden comunicarse entre sí: ```bash sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw allow from 10.42.0.0/16 to any sudo ufw allow from 10.43.0.0/16 to any sudo ufw enable ``` Comprueba las reglas: ```bash sudo ufw status ``` ```output Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere Anywhere ALLOW 10.42.0.0/16 Anywhere ALLOW 10.43.0.0/16 ... ``` No abras el puerto 6443 (API de Kubernetes) a Internet: en este tutorial solo usarás `kubectl` desde el propio servidor. ## Paso 2: Instalar k3s k3s es una distribución de Kubernetes certificada que se instala como un único binario e incluye Traefik como controlador de Ingress, que usarás para publicar AWX. Descarga el script de instalación oficial y revísalo antes de ejecutarlo: ```bash curl -sfL https://get.k3s.io -o k3s-install.sh less k3s-install.sh ``` Ejecútalo. Instala la última versión estable de k3s como servicio systemd: ```bash sudo sh k3s-install.sh ``` Comprueba que el servicio está activo y que el nodo está listo (puede tardar unos 30 segundos): ```bash sudo systemctl status k3s --no-pager | head -3 sudo k3s kubectl get nodes ``` ```output ● k3s.service - Lightweight Kubernetes Loaded: loaded (/etc/systemd/system/k3s.service; enabled; preset: enabled) Active: active (running) since ... NAME STATUS ROLES AGE VERSION awx Ready control-plane,master 45s v1.33.4+k3s1 ``` ## Paso 3: Configurar kubectl para tu usuario El archivo de acceso de k3s, `/etc/rancher/k3s/k3s.yaml`, solo lo puede leer root. Copia una versión para tu usuario con permisos restringidos, en lugar de hacer el original legible por todos: ```bash mkdir -p ~/.kube sudo k3s kubectl config view --raw > ~/.kube/config chmod 600 ~/.kube/config echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc source ~/.bashrc ``` k3s instala `kubectl` en `/usr/local/bin`. Comprueba que funciona sin `sudo`: ```bash kubectl get pods -A ``` ```output NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-... 1/1 Running 0 2m kube-system local-path-provisioner-... 1/1 Running 0 2m kube-system metrics-server-... 1/1 Running 0 2m kube-system svclb-traefik-... 2/2 Running 0 1m kube-system traefik-... 1/1 Running 0 1m ... ``` El `local-path-provisioner` es el que dará almacenamiento persistente a la base de datos de AWX. ## Paso 4: Instalar cert-manager para los certificados HTTPS cert-manager obtiene y renueva certificados de Let's Encrypt automáticamente para los Ingress de Kubernetes. Instálalo con el manifiesto de su última versión publicada: ```bash kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml ``` Espera a que sus tres pods estén en `Running`: ```bash kubectl get pods -n cert-manager ``` ```output NAME READY STATUS RESTARTS AGE cert-manager-... 1/1 Running 0 60s cert-manager-cainjector-... 1/1 Running 0 60s cert-manager-webhook-... 1/1 Running 0 60s ``` Crea un emisor (`ClusterIssuer`) que pida certificados a Let's Encrypt validando por HTTP a través de Traefik: ```bash mkdir -p ~/awx && cd ~/awx nano cluster-issuer.yaml ``` Sustituye `your_email` por tu dirección de correo: ```yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: your_email privateKeySecretRef: name: letsencrypt-prod-account-key solvers: - http01: ingress: ingressClassName: traefik ``` Aplícalo y comprueba que está listo: ```bash kubectl apply -f cluster-issuer.yaml kubectl get clusterissuer ``` ```output NAME READY AGE letsencrypt-prod True 10s ``` ## Paso 5: Instalar AWX Operator El operador es un controlador que vigila los recursos de tipo `AWX` y crea todo lo necesario (base de datos, despliegues, servicios, Ingress). Se instala con Kustomize, que ya viene integrado en `kubectl`. Crea el archivo de Kustomize en `~/awx`: ```bash nano kustomization.yaml ``` ```yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - github.com/ansible/awx-operator/config/default?ref=2.19.1 images: - name: quay.io/ansible/awx-operator newTag: 2.19.1 namespace: awx ``` La versión aparece dos veces (en la URL y en `newTag`) y debe ser la misma. Aplica el manifiesto: ```bash kubectl apply -k . ``` Comprueba que el operador está en marcha: ```bash kubectl get pods -n awx ``` ```output NAME READY STATUS RESTARTS AGE awx-operator-controller-manager-6c9b8d7f5d-x2k8p 2/2 Running 0 50s ``` ## Paso 6: Desplegar la instancia de AWX Describe la instancia de AWX en un recurso propio. Sustituye `awx.your_domain` por el nombre DNS que creaste: ```bash nano awx.yaml ``` ```yaml apiVersion: awx.ansible.com/v1beta1 kind: AWX metadata: name: awx spec: service_type: clusterip ingress_type: ingress ingress_class_name: traefik ingress_hosts: - hostname: awx.your_domain tls_secret: awx-tls ingress_annotations: | cert-manager.io/cluster-issuer: letsencrypt-prod ``` - `service_type: clusterip` deja el servicio accesible solo dentro del clúster; el acceso externo pasa por Traefik. - `ingress_hosts` crea el Ingress con tu dominio y guarda el certificado en el secreto `awx-tls`. - La anotación `cert-manager.io/cluster-issuer` indica a cert-manager que emita ese certificado con Let's Encrypt. Añade el archivo a la lista de recursos de `kustomization.yaml`: ```bash nano kustomization.yaml ``` ```yaml resources: - github.com/ansible/awx-operator/config/default?ref=2.19.1 - awx.yaml ``` Aplica de nuevo: ```bash kubectl apply -k . ``` El operador tarda entre 5 y 10 minutos en crear PostgreSQL, migrar la base de datos y arrancar AWX. Sigue su progreso en el log: ```bash kubectl logs -f deployments/awx-operator-controller-manager -c awx-manager -n awx ``` Cuando termine verás un resumen de Ansible sin fallos (`failed=0`). Pulsa `Ctrl+C` y revisa los pods: ```bash kubectl get pods -n awx ``` ```output NAME READY STATUS RESTARTS AGE awx-migration-24.6.1-7fk2q 0/1 Completed 0 6m awx-operator-controller-manager-6c9b8d7f5d-x2k8p 2/2 Running 0 12m awx-postgres-15-0 1/1 Running 0 7m awx-task-7d4b9c6f8-mz5tq 4/4 Running 0 6m awx-web-5f8c7d9b4-pl2rv 3/3 Running 0 6m ``` Comprueba que el certificado se ha emitido: ```bash kubectl get certificate -n awx ``` ```output NAME READY SECRET AGE awx-tls True awx-tls 5m ``` ## Paso 7: Acceder a la interfaz web El operador genera una contraseña aleatoria para el usuario `admin` y la guarda en un secreto. Recupérala: ```bash kubectl get secret awx-admin-password -n awx -o jsonpath="{.data.password}" | base64 --decode; echo ``` Abre `https://awx.your_domain` en el navegador e inicia sesión con el usuario `admin` y esa contraseña. Deberías ver el panel de AWX con la organización `Default` y unos recursos de demostración (`Demo Project`, `Demo Inventory`, `Demo Job Template`). Crea un usuario personal en **Access > Users** y usa `admin` solo para tareas de administración. ## Paso 8: Ejecutar tu primer playbook AWX organiza la automatización en cuatro piezas: una **credencial** para conectarse a los servidores, un **inventario** con los servidores, un **proyecto** con los playbooks (normalmente un repositorio Git) y una **plantilla de trabajo** que une las tres. Vas a crear cada una para ejecutar un playbook de ejemplo contra un servidor. ### Crear la credencial En **Resources > Credentials**, pulsa **Add**: - **Name**: `ssh-servidores` - **Organization**: `Default` - **Credential Type**: `Machine` - **Username**: el usuario remoto (`your_user`) - **SSH Private Key**: pega la clave privada cuya pública está en `~/.ssh/authorized_keys` del servidor de destino - **Privilege Escalation Method**: `sudo`, y la contraseña de sudo si tu usuario la necesita Guarda. AWX cifra las credenciales en su base de datos y no vuelve a mostrar los secretos. ### Crear el inventario En **Resources > Inventories**, pulsa **Add > Add inventory**, llámalo `produccion` y guarda. En la pestaña **Hosts**, añade un host con el nombre del servidor (`web1`) y, en **Variables**: ```yaml ansible_host: your_server_ip ``` ### Crear el proyecto En **Resources > Projects**, pulsa **Add**: - **Name**: `ejemplos` - **Organization**: `Default` - **Source Control Type**: `Git` - **Source Control URL**: `https://github.com/ansible/ansible-tower-samples` - Marca **Update Revision on Launch** para que AWX descargue la última versión del repositorio en cada ejecución. Guarda. AWX clona el repositorio; el estado del proyecto pasa a **Successful** en unos segundos. Para tus propios playbooks usa tu repositorio y, si es privado, una credencial de tipo `Source Control`. ### Crear y lanzar la plantilla de trabajo En **Resources > Templates**, pulsa **Add > Add job template**: - **Name**: `hola-mundo` - **Inventory**: `produccion` - **Project**: `ejemplos` - **Playbook**: `hello_world.yml` - **Credentials**: `ssh-servidores` Guarda y pulsa **Launch**. AWX abre la salida de la ejecución en directo: ```output PLAY [Hello World Sample] ****************************************************** TASK [Gathering Facts] ********************************************************* ok: [web1] TASK [Hello Message] *********************************************************** ok: [web1] => { "msg": "Hello World!" } PLAY RECAP ********************************************************************* web1 : ok=2 changed=0 unreachable=0 failed=0 ``` Si ves `unreachable`, el pod de ejecución no llega al servidor por SSH: comprueba la IP, el puerto 22 del destino y que la clave de la credencial es la correcta. Desde la misma plantilla puedes programar ejecuciones periódicas (pestaña **Schedules**) y dar permiso de ejecución a otros usuarios o equipos (pestaña **Access**) sin darles acceso a las credenciales. ## Paso 9: Hacer copias de seguridad de AWX Toda la configuración de AWX (credenciales, inventarios, historial) vive en PostgreSQL. El operador incluye un recurso `AWXBackup` que vuelca la base de datos y los secretos a un volumen persistente: ```bash nano ~/awx/backup.yaml ``` ```yaml apiVersion: awx.ansible.com/v1beta1 kind: AWXBackup metadata: name: awx-backup-inicial namespace: awx spec: deployment_name: awx ``` ```bash kubectl apply -f ~/awx/backup.yaml kubectl get awxbackup -n awx ``` Revisa el log del operador hasta que la copia termine. Guarda también una copia del secreto `awx-secret-key`, sin el cual no se pueden descifrar las credenciales al restaurar: ```bash kubectl get secret awx-secret-key -n awx -o yaml > ~/awx-secret-key.yaml chmod 600 ~/awx-secret-key.yaml ``` Esa copia queda en el mismo servidor; muévela a un almacenamiento externo seguro. ## Solución de problemas **Los pods de AWX se quedan en `Pending`.** Normalmente falta memoria o CPU. `kubectl describe pod -n awx` muestra el motivo en la sección `Events` (`Insufficient memory`, `Insufficient cpu`). **El certificado no pasa a `READY True`.** Comprueba que el registro DNS apunta a la IP del servidor y que el puerto 80 está abierto: Let's Encrypt valida por HTTP. `kubectl describe certificate awx-tls -n awx` y `kubectl get challenges -n awx` muestran el error concreto. **`kubectl apply -k .` falla al descargar los manifiestos.** Falta `git` en el servidor o la etiqueta de `ref=` no existe. Comprueba la etiqueta en la página de versiones del operador. **El operador repite errores en su log.** Busca la primera tarea con `fatal` en `kubectl logs deployments/awx-operator-controller-manager -c awx-manager -n awx`; suele indicar un campo mal escrito en `awx.yaml`. ## Conclusión Tienes AWX funcionando sobre k3s en Ubuntu 24.04, publicado con HTTPS de Let's Encrypt, con una primera plantilla de trabajo ejecutada contra un servidor real y una copia de seguridad inicial. Como siguientes pasos, conecta AWX a tus repositorios de playbooks con credenciales de tipo `Source Control`, crea equipos con permisos por inventario y plantilla, y programa `AWXBackup` de forma periódica junto con una copia externa del secreto de cifrado.