Instalación y Configuración de Ansible AWX Tower

Ansible AWX es el proyecto ascendente de código abierto para Ansible Tower, proporcionando una interfaz de usuario basada en web, API REST y motor de orquestación multi-playbook para Ansible. AWX permite la administración centralizada de despliegues de Ansible, proporciona control de acceso basado en roles, administración de credenciales y capacidades de flujo de trabajo para orquestaciones complejas. Esta guía cubre la instalación en Kubernetes y Docker, la configuración de proyectos e inventarios, la administración de credenciales, la configuración de plantillas de trabajo, la implementación de RBAC y la creación de flujos de trabajo.

Tabla de Contenidos

  1. Descripción General y Arquitectura de AWX
  2. Instalación de Kubernetes
  3. Instalación de Docker Compose
  4. Configuración de Proyectos
  5. Administración de Inventarios
  6. Administración de Credenciales
  7. Creación de Plantillas de Trabajo
  8. Control de Acceso Basado en Roles
  9. Construcción de Flujos de Trabajo
  10. Conclusión

Descripción General y Arquitectura de AWX

Ansible AWX proporciona capacidades de automatización de nivel empresarial construidas sobre el motor de Ansible. Separa el plano de control (UI, API, base de datos) de los entornos de ejecución, permitiendo la automatización escalable en toda la infraestructura distribuida.

Componentes clave:

Web UI: Interfaz basada en navegador para administrar automatización, accesible en el puerto 80/443 API REST: Acceso programático completo a toda la funcionalidad de AWX PostgreSQL Database: Almacena configuración, credenciales, historial de trabajos y metadatos Redis Cache: Proporciona administración de colas de tareas y almacenamiento en caché Execution Environments: Entornos en contenedores donde se ejecutan los playbooks de Ansible

La arquitectura admite múltiples nodos de ejecución, permitiéndole escalar la ejecución de playbooks en sistemas distribuidos mientras mantiene el control centralizado y la visibilidad.

Instalación de Kubernetes

La instalación de AWX en Kubernetes requiere el Operador de AWX. Este enfoque se recomienda para despliegues de producción.

Requisitos previos:

# Verify Kubernetes cluster access
kubectl cluster-info
kubectl get nodes

# Ensure you have sufficient resources
# Recommended: 4 CPU, 4GB RAM minimum for AWX pod

Instale el Operador de AWX:

# Create namespace
kubectl create namespace awx

# Clone the AWX Operator repository
git clone https://github.com/ansible/awx-operator.git
cd awx-operator

# Check out a stable release
git checkout 2.8.0
# or latest: git checkout devel

# Install the operator
make deploy NAMESPACE=awx

Verifique la instalación del operador:

kubectl get deployments -n awx
kubectl get pods -n awx

# Watch operator logs
kubectl logs -n awx deployment/awx-operator-controller-manager -f

Cree una instancia de AWX usando un recurso personalizado:

cat > awx-instance.yml << 'EOF'
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: awx
  namespace: awx
spec:
  # Basic configuration
  admin_user: admin
  admin_password_secret: awx-admin-password
  
  # Database configuration (use external PostgreSQL in production)
  postgres_init_storage: 10Gi
  postgres_storage_class: standard
  
  # Image configuration
  image: quay.io/ansible/awx
  image_version: 24.2.0
  
  # Resource limits
  web_resource_limits:
    cpu: 1000m
    memory: 2Gi
  postgres_resource_limits:
    cpu: 500m
    memory: 1Gi
  redis_resource_limits:
    cpu: 500m
    memory: 1Gi
  
  # Network configuration
  service_type: LoadBalancer
  ingress_type: ingress
  ingress_tls_secret: awx-tls
  
  # Execution environment
  execution_environments:
    - name: default
      image: quay.io/ansible/creator-base:latest
EOF

# Create AWX admin secret
kubectl create secret generic awx-admin-password \
  --from-literal=password=YourSecurePassword123 \
  -n awx

# Create TLS certificate (optional, for HTTPS)
kubectl create secret tls awx-tls \
  --cert=path/to/cert.pem \
  --key=path/to/key.pem \
  -n awx

# Deploy AWX instance
kubectl apply -f awx-instance.yml

Espere a que se complete el despliegue de AWX:

# Monitor pod creation
kubectl get pods -n awx -w

# Check AWX status
kubectl get awx -n awx
kubectl describe awx awx -n awx

# Wait until status shows 'Successful'

Acceda a AWX:

# Get service details
kubectl get svc -n awx

# Port forward for local access
kubectl port-forward -n awx svc/awx-service 8080:80

# Then access http://localhost:8080
# Default username: admin
# Password: from awx-admin-password secret

Para producción, configure la ingresión apropiada:

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: awx-ingress
  namespace: awx
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - awx.example.com
      secretName: awx-tls
  rules:
    - host: awx.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: awx-service
                port:
                  number: 80

Instalación de Docker Compose

Para desarrollo y pruebas, Docker Compose proporciona un método de instalación más simple.

Requisitos previos:

# Install Docker and Docker Compose
docker --version
docker-compose --version

# System requirements
# Minimum: 2 CPU, 2GB RAM
# Recommended: 4+ CPU, 4+ GB RAM

Clone el repositorio de AWX:

git clone https://github.com/ansible/awx.git
cd awx

# Check out a release
git checkout 24.2.0

Configure el entorno de Docker Compose:

# Navigate to installer directory
cd installer

# Edit inventory file
cat > inventory << 'EOF'
localhost ansible_connection=local

[all:vars]
# Admin user configuration
admin_user=admin
admin_password=your_secure_password

# Docker configuration
awx_container_init_command=""
awx_image=quay.io/ansible/awx
awx_version=24.2.0
docker_registry_username=
docker_registry_password=

# Database
postgres_init_storage=10Gi
postgres_container=awx_postgres
postgres_db_name=awx
postgres_db_user=awx
postgres_db_password=awx_password

# Redis
redis_container=awx_redis
redis_image=redis:latest

# Port configuration
host_port=80

# Secret key
secret_key=aabbccdd1234567890abcdefghijklmnop

# Broadcast websocket configuration
broadcast_websocket_secret=broadcast_secret_key_123456789
EOF

# Run the installer
./docker-compose up -d

# Or use the Python installer
python3 ./tools/docker-compose/_docker-compose.py

Monitoree el inicio:

# View logs
docker-compose logs -f

# Wait for all services to start
docker-compose ps

# Check database initialization
docker-compose logs postgres

Acceda a AWX:

# AWX is available at http://localhost:80
# Default credentials:
# Username: admin
# Password: your_secure_password

# View running containers
docker-compose ps

# Execute commands in container
docker-compose exec awx_web awx-manage createsuperuser

Para despliegues de Docker Compose en producción, use la configuración apropiada:

version: '3'
services:
  postgres:
    image: postgres:13
    environment:
      POSTGRES_DB: awx
      POSTGRES_USER: awx
      POSTGRES_PASSWORD: securepass123
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  redis:
    image: redis:6
    ports:
      - "6379:6379"

  awx_web:
    image: quay.io/ansible/awx:24.2.0
    ports:
      - "80:8052"
      - "443:8053"
    depends_on:
      - postgres
      - redis
    environment:
      DATABASE_USER: awx
      DATABASE_PASSWORD: securepass123
      DATABASE_HOST: postgres
      DATABASE_PORT: 5432
      DATABASE_NAME: awx
      REDIS_HOST: redis
      REDIS_PORT: 6379
      SECRET_KEY: "your-secret-key-here"
      BROADCAST_WEBSOCKET_SECRET: "broadcast-secret"
    volumes:
      - ./settings.py:/etc/tower/settings.py

volumes:
  postgres_data:

Configuración de Proyectos

Los proyectos conectan AWX a sus repositorios de playbooks de Ansible.

Cree un proyecto a través de la API:

# Define project details
TOWER_HOST="https://awx.example.com"
TOWER_USER="admin"
TOWER_PASS="password"

# Create project
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Playbooks",
    "description": "Main production automation",
    "scm_type": "git",
    "scm_url": "https://github.com/company/playbooks.git",
    "scm_branch": "main",
    "scm_clean": true,
    "scm_delete_on_update": false,
    "scm_update_on_launch": true,
    "credential": 1
  }' \
  $TOWER_HOST/api/v2/projects/

O a través de la interfaz web:

  1. Navegue a Proyectos
  2. Haga clic en Crear Proyecto
  3. Ingrese el nombre y la descripción
  4. Seleccione el tipo de SCM (Git, Subversion, etc.)
  5. Ingrese la URL de SCM y la rama
  6. Opcionalmente seleccione una credencial para autenticación
  7. Guardar

Sincronización de proyectos:

# Manual project sync via API
curl -u $TOWER_USER:$TOWER_PASS \
  -X POST \
  $TOWER_HOST/api/v2/projects/5/update/

# Check project sync status
curl -u $TOWER_USER:$TOWER_PASS \
  $TOWER_HOST/api/v2/projects/5/

Administración de Inventarios

Los inventarios definen los hosts y grupos que administra Ansible.

Cree un inventario:

# Simple inventory creation
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Servers",
    "description": "Production infrastructure",
    "organization": 1
  }' \
  $TOWER_HOST/api/v2/inventories/

Agregue hosts al inventario:

# Add host
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "web01.example.com",
    "inventory": 3,
    "variables": "ansible_host: 192.168.1.10"
  }' \
  $TOWER_HOST/api/v2/hosts/

# Add host group
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "webservers",
    "inventory": 3
  }' \
  $TOWER_HOST/api/v2/groups/

# Add host to group
curl -u $TOWER_USER:$TOWER_PASS \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "id": 5
  }' \
  $TOWER_HOST/api/v2/groups/7/hosts/

Inventario dinámico desde fuentes externas:

# Create custom inventory script
#!/usr/bin/env python3
import json
import sys

inventory = {
    "webservers": {
        "hosts": ["web01.example.com", "web02.example.com"],
        "vars": {"environment": "production"}
    },
    "databases": {
        "hosts": ["db01.example.com"],
        "vars": {"environment": "production"}
    },
    "_meta": {
        "hostvars": {
            "web01.example.com": {"http_port": 80},
            "web02.example.com": {"http_port": 80}
        }
    }
}

print(json.dumps(inventory))

Administración de Credenciales

Las credenciales almacenan información de autenticación de forma segura.

Cree credenciales SSH:

curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "SSH Credentials",
    "credential_type": 1,
    "organization": 1,
    "inputs": {
      "username": "ansible",
      "password": "secure_password",
      "become_password": "sudo_password"
    }
  }' \
  $TOWER_HOST/api/v2/credentials/

Cree credenciales de token de API:

curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "API Token",
    "credential_type": 23,
    "organization": 1,
    "inputs": {
      "host": "api.example.com",
      "bearer_token": "token_value"
    }
  }' \
  $TOWER_HOST/api/v2/credentials/

Creación de Plantillas de Trabajo

Las plantillas de trabajo son configuraciones reutilizables para ejecutar playbooks de Ansible.

Cree una plantilla de trabajo:

curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Deploy Web Application",
    "project": 5,
    "playbook": "deploy.yml",
    "inventory": 3,
    "credential": 7,
    "ask_limit_on_launch": true,
    "ask_tags_on_launch": true,
    "ask_variables_on_launch": true,
    "extra_vars": "environment: production\nversion: latest",
    "verbosity": 1,
    "job_type": "run"
  }' \
  $TOWER_HOST/api/v2/job_templates/

Inicie un trabajo:

# Simple launch
curl -u $TOWER_USER:$TOWER_PASS \
  -X POST \
  $TOWER_HOST/api/v2/job_templates/8/launch/

# Launch with extra variables
curl -u $TOWER_USER:$TOWER_PASS \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "extra_vars": "{\"target_hosts\": \"webservers\", \"action\": \"restart\"}"
  }' \
  $TOWER_HOST/api/v2/job_templates/8/launch/

# Check job status
curl -u $TOWER_USER:$TOWER_PASS \
  $TOWER_HOST/api/v2/jobs/15/

Control de Acceso Basado en Roles

RBAC controla quién puede realizar acciones específicas en AWX.

Cree un rol personalizado:

curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "DevOps Team Lead",
    "description": "Can manage all automation resources",
    "permissions": [
      "add_project",
      "change_project",
      "delete_project",
      "view_project",
      "add_jobtemplate",
      "change_jobtemplate",
      "delete_jobtemplate",
      "execute_jobtemplate"
    ]
  }' \
  $TOWER_HOST/api/v2/roles/

Asigne roles a usuarios:

# Create team
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "DevOps",
    "description": "DevOps engineering team",
    "organization": 1
  }' \
  $TOWER_HOST/api/v2/teams/

# Add member to team
curl -u $TOWER_USER:$TOWER_PASS \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "id": 3
  }' \
  $TOWER_HOST/api/v2/teams/2/members/

# Assign role to team
curl -u $TOWER_USER:$TOWER_PASS \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "role_definition": 4,
    "content_type": "project",
    "object_id": 5
  }' \
  $TOWER_HOST/api/v2/role_bindings/

Construcción de Flujos de Trabajo

Los flujos de trabajo encadenan múltiples plantillas de trabajo juntas con lógica de decisión.

Cree una plantilla de flujo de trabajo:

curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Application Deployment Pipeline",
    "description": "Deploy app with pre/post checks",
    "organization": 1,
    "webhook_service": "github",
    "webhook_credential": null
  }' \
  $TOWER_HOST/api/v2/workflow_job_templates/

Agregue nodos de flujo de trabajo:

# Syntax check node
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_job_template": 3,
    "unified_job_template": 5,
    "identifier": "syntax_check"
  }' \
  $TOWER_HOST/api/v2/workflow_job_template_nodes/

# Deploy node
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_job_template": 3,
    "unified_job_template": 8,
    "identifier": "deploy"
  }' \
  $TOWER_HOST/api/v2/workflow_job_template_nodes/

# Validation node
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_job_template": 3,
    "unified_job_template": 12,
    "identifier": "validate"
  }' \
  $TOWER_HOST/api/v2/workflow_job_template_nodes/

Conecte nodos de flujo de trabajo:

# Add edge from syntax_check to deploy
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_job_template_node": 1,
    "child_node": 2,
    "edge_type": "success"
  }' \
  $TOWER_HOST/api/v2/workflow_job_template_node_edges/

# Add edge from deploy to validate
curl -u $TOWER_USER:$TOWER_PASS \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_job_template_node": 2,
    "child_node": 3,
    "edge_type": "success"
  }' \
  $TOWER_HOST/api/v2/workflow_job_template_node_edges/

Inicie el flujo de trabajo:

curl -u $TOWER_USER:$TOWER_PASS \
  -X POST \
  $TOWER_HOST/api/v2/workflow_job_templates/3/launch/

# Monitor workflow execution
curl -u $TOWER_USER:$TOWER_PASS \
  $TOWER_HOST/api/v2/workflow_jobs/7/

Conclusión

Ansible AWX transforma Ansible de una herramienta de línea de comandos a una plataforma de automatización completa con interfaz web, acceso a API y características empresariales. Ya sea implementando en Kubernetes para escala de producción o Docker Compose para desarrollo, AWX proporciona la infraestructura para la administración centralizada de automatización. Configurando correctamente proyectos, inventarios, credenciales, plantillas de trabajo, RBAC y flujos de trabajo, crea una plataforma de automatización robusta que escala con las necesidades de su infraestructura mientras mantiene la seguridad y el control. Combine AWX con playbooks bien diseñados y tendrá un poderoso sistema para administrar infraestructura compleja a escala.