Ansible AWX Tower Installation and Configuration
Ansible AWX is the open-source upstream project for Ansible Tower, providing a web-based user interface, REST API, and multi-playbook orchestration engine for Ansible. AWX enables centralized management of Ansible deployments, provides role-based access control, credential management, and workflow capabilities for complex orchestrations. This guide covers installation on Kubernetes and Docker, configuring projects and inventories, managing credentials, setting up job templates, implementing RBAC, and building workflows.
Table of Contents
- AWX Overview and Architecture
- Kubernetes Installation
- Docker Compose Installation
- Configuring Projects
- Managing Inventories
- Credential Management
- Creating Job Templates
- Role-Based Access Control
- Building Workflows
- Conclusion
AWX Overview and Architecture
Ansible AWX provides enterprise-grade automation capabilities built on the Ansible engine. It separates the control plane (UI, API, database) from execution environments, allowing scalable automation across distributed infrastructure.
Key components:
Web UI: Browser-based interface for managing automation, accessible on port 80/443 REST API: Complete programmatic access to all AWX functionality PostgreSQL Database: Stores configuration, credentials, job history, and metadata Redis Cache: Provides task queue management and caching Execution Environments: Containerized environments where Ansible playbooks execute
The architecture supports multiple execution nodes, allowing you to scale playbook execution across distributed systems while maintaining centralized control and visibility.
Kubernetes Installation
Installing AWX on Kubernetes requires the AWX Operator. This approach is recommended for production deployments.
Prerequisites:
# Verify Kubernetes cluster access
kubectl cluster-info
kubectl get nodes
# Ensure you have sufficient resources
# Recommended: 4 CPU, 4GB RAM minimum for AWX pod
Install the AWX Operator:
# 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
Verify operator installation:
kubectl get deployments -n awx
kubectl get pods -n awx
# Watch operator logs
kubectl logs -n awx deployment/awx-operator-controller-manager -f
Create an AWX instance using a custom resource:
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
Wait for AWX deployment to complete:
# 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'
Access 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
For production, set up proper ingress:
---
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
Docker Compose Installation
For development and testing, Docker Compose provides a simpler installation method.
Prerequisites:
# Install Docker and Docker Compose
docker --version
docker-compose --version
# System requirements
# Minimum: 2 CPU, 2GB RAM
# Recommended: 4+ CPU, 4+ GB RAM
Clone the AWX repository:
git clone https://github.com/ansible/awx.git
cd awx
# Check out a release
git checkout 24.2.0
Configure Docker Compose environment:
# 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
Monitor startup:
# View logs
docker-compose logs -f
# Wait for all services to start
docker-compose ps
# Check database initialization
docker-compose logs postgres
Access 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
For production Docker Compose deployments, use proper configuration:
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:
Configuring Projects
Projects connect AWX to your Ansible playbook repositories.
Create a project via the 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/
Or via the web UI:
- Navigate to Projects
- Click Create Project
- Enter name and description
- Select SCM type (Git, Subversion, etc.)
- Enter SCM URL and branch
- Optionally select credential for authentication
- Save
Project synchronization:
# 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/
Managing Inventories
Inventories define the hosts and groups that Ansible manages.
Create an inventory:
# 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/
Add hosts to inventory:
# 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/
Dynamic inventory from external sources:
# 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))
Credential Management
Credentials store authentication information securely.
Create SSH credentials:
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/
Create API token credentials:
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/
Creating Job Templates
Job templates are reusable configurations for running Ansible playbooks.
Create a job template:
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/
Launch a job:
# 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/
Role-Based Access Control
RBAC controls who can perform specific actions in AWX.
Create a custom role:
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/
Assign roles to users:
# 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/
Building Workflows
Workflows chain multiple job templates together with decision logic.
Create a workflow template:
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/
Add workflow nodes:
# 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/
Connect workflow nodes:
# 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/
Launch workflow:
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/
Conclusion
Ansible AWX transforms Ansible from a command-line tool into a comprehensive automation platform with web interface, API access, and enterprise features. Whether deploying on Kubernetes for production scale or Docker Compose for development, AWX provides the infrastructure for centralized automation management. By properly configuring projects, inventories, credentials, job templates, RBAC, and workflows, you create a robust automation platform that scales with your infrastructure needs while maintaining security and governance. Combine AWX with well-designed playbooks and you have a powerful system for managing complex infrastructure at scale.


