Working with AWX and Ansible Tower
1. Understanding AWX Architecture
| Component | Description | Role |
|---|---|---|
| AWX Server | Core application that manages jobs, inventories, and workflows. | Central control plane for automation tasks |
| PostgreSQL Database | Stores all AWX data including job history, credentials, and inventory. | Persistent storage for configuration and runtime state |
| Redis | In-memory data store used for job queuing and caching. | Job scheduling and real-time communication |
| Celery Workers | Processes jobs submitted to the queue. | Execute automation tasks asynchronously |
| Web UI | Browser-based interface for managing AWX. | User interaction and configuration |
| Job Events | Real-time event stream for job status updates. | Live monitoring and reporting |
Example: AWX Component Interaction
# AWX server receives a job request
awx-cli job launch --job-template "Deploy App"
# Job is queued in Redis
redis-cli lpush awx_queue "job_id:123"
# Celery worker picks up job
celery -A awx.celery worker --loglevel=info
# Job executes and updates PostgreSQL
ansible-playbook deploy.yml
Key Points
- AWX uses a distributed architecture for scalability and reliability.
- The server handles API requests, UI interactions, and job orchestration.
- PostgreSQL stores all persistent data like credentials, inventories, and job history.
- Redis manages job queuing and real-time communication between components.
- Celery workers execute automation tasks asynchronously to prevent blocking the server.
2. Installing AWX
Note: AWX requires a Linux-based system to run. This guide assumes a Red Hat Enterprise Linux (RHEL) or CentOS 8+ environment.
| Component | Description | Installation Method |
|---|---|---|
| Ansible Tower | Commercial version of AWX with additional features and support. | License required; available through Red Hat. |
| AWX | Open-source version of Ansible Tower. | Install via ansible-tower-setup or Docker. |
Example: Installing AWX using Docker
git clone https://github.com/ansible/awx.git
cd awx/installer
ansible-playbook -i inventory installer.yml
Installation Steps
- Ensure Docker and Docker Compose are installed.
- Clone the AWX repository from GitHub.
- Navigate to the installer directory.
- Run the Ansible playbook using
ansible-playbook -i inventory installer.yml.
Warning: AWX is not supported on Windows or macOS without Docker Desktop. Ensure sufficient system resources (minimum 4GB RAM) for stable operation.
3. Creating Organizations
| Field | Description | Example Value |
|---|---|---|
| name | Name of the organization | Production Org |
| description | Optional description of the organization | Production environment organization |
| custom_virtualenv | Path to custom virtual environment | /opt/ansible/venv |
| max_hosts | Maximum number of hosts allowed in this organization | 1000 |
Example: Creating an Organization via API
{
"name": "Production Org",
"description": "Production environment organization",
"custom_virtualenv": "/opt/ansible/venv"
}
Note: Organizations in AWX/Tower are used to group related resources such as projects, inventories, and job templates.
4. Managing Users and Teams
| Property | Description | Notes |
|---|---|---|
| user.name | admin |
Unique identifier for the user |
| user.email | admin@example.com |
Email address for notifications |
| user.is_superuser | true |
Grants full system access |
| user.is_system_auditor | false |
Allows viewing audit logs |
Example: Create a new user with admin privileges
---
- name: Create admin user
hosts: localhost
gather_facts: false
tasks:
- name: Create user
awx_collection.awx.user:
name: admin
email: admin@example.com
is_superuser: true
is_system_auditor: false
Example: Update user permissions
---
- name: Update user permissions
hosts: localhost
gather_facts: false
tasks:
- name: Grant admin access
awx_collection.awx.user:
name: johndoe
is_superuser: true
Example: Delete a user
---
- name: Delete user
hosts: localhost
gather_facts: false
tasks:
- name: Remove user from system
awx_collection.awx.user:
name: johndoe
state: absent
| Property | Description | Notes |
|---|---|---|
| team.name | DevOps |
Unique identifier for the team |
| team.organization | Default |
Organization the team belongs to |
| team.description | DevOps team managing infrastructure |
Short description of the team's purpose |
Example: Create a new team
---
- name: Create DevOps team
hosts: localhost
gather_facts: false
tasks:
- name: Create team in organization
awx_collection.awx.team:
name: DevOps
organization: Default
description: "DevOps team managing infrastructure"
Example: Add user to team
---
- name: Add user to team
hosts: localhost
gather_facts: false
tasks:
- name: Assign user to team
awx_collection.awx.team:
name: DevOps
users:
- johndoe
Example: Remove user from team
---
- name: Remove user from team
hosts: localhost
gather_facts: false
tasks:
- name: Unassign user from team
awx_collection.awx.team:
name: DevOps
users:
- johndoe
state: absent
5. Creating Inventories
| Field | Description | Example |
|---|---|---|
| name | Name of the inventory | Production Servers |
| description | Optional description of the inventory | Production web and database servers |
| organization | Organization to which the inventory belongs | Acme Corp |
| kind | Kind of inventory (e.g., smart, constructed) |
smart |
Example: Creating a Smart Inventory
---
name: "Production Web Servers"
description: "Web servers in production"
organization: "Acme Corp"
kind: "smart"
host_filter: "inventory_hostname.startswith('web')"
Example: Creating a Constructed Inventory
---
name: "Dynamic Inventory from API"
organization: "Acme Corp"
kind: "constructed"
source_vars:
- "api_url: https://example.com/api/inventory"
- "auth_token: <token>"
Note: Smart inventories use host filters to dynamically determine hosts, while constructed inventories are built from source data like external APIs or other inventories.
6. Creating Projects
| Field | Description | Example |
|---|---|---|
| name | Name of the project | my-project |
| description | Optional description of the project | Production infrastructure project |
| organization | Organization to which the project belongs | my-org |
| scm_type | Source control management type (git, hg, svn) | git |
| scm_url | URL to the source control repository | https://github.com/myorg/myproject.git |
| scm_branch | Branch to use from the repository | main |
| scm_credential | Credential for accessing the repository (optional) | my-git-cred |
| scm_update_on_launch | Whether to update the project on every launch | true |
Example: Creating a Project via API
{
"name": "my-project",
"description": "Production infrastructure project",
"organization": "my-org",
"scm_type": "git",
"scm_url": "https://github.com/myorg/myproject.git",
"scm_branch": "main",
"scm_credential": "my-git-cred",
"scm_update_on_launch": true
}
Note: The project must be associated with an organization. If
scm_update_on_launch is set to true, the project will be updated every time a job runs using this project.
7. Creating Job Templates
| Field | Description | Example Value |
|---|---|---|
| name | Name of the job template | deploy-app |
| job_type | Type of job to run (run or check) | run |
| inventory | Inventory to use for the job | production |
| project | Project to use for the job | my-app-project |
| playbook | Playbook file to execute | deploy.yml |
| credential | Credential to use for the job | ssh-credentials |
Example: Creating a Job Template via API
{
"name": "deploy-app",
"job_type": "run",
"inventory": 1,
"project": 2,
"playbook": "deploy.yml",
"credential": 3
}
8. Creating Workflows
Example: Basic Workflow Job Template
---
name: "Deploy Application"
job_type: workflow
workflow_nodes:
- name: "Clone Repository"
job_template: "clone-repo-template"
- name: "Run Tests"
job_template: "run-tests-template"
dependencies:
- "Clone Repository"
- name: "Deploy to Staging"
job_template: "deploy-staging-template"
dependencies:
- "Run Tests"
| Field | Description | Values |
|---|---|---|
| name | Name of the workflow job template | string |
| job_type | Must be workflow |
workflow |
| workflow_nodes | List of nodes in the workflow | list |
Steps to Create a Workflow
- Create job templates for each step (e.g., clone repo, run tests)
- Define dependencies between steps
- Create a workflow job template referencing these templates
- Execute or schedule the workflow job template
Workflow Job Template Components
- Nodes: Represent individual job templates in the workflow
- Dependencies: Define execution order between nodes
- Branches: Allow conditional execution paths (e.g., success/failure)
9. Managing Credentials
| Field | Description | Example |
|---|---|---|
| name | Name of the credential | my-credential |
| description | Optional description of the credential | Production database credentials |
| organization | Organization to associate with the credential | prod-org |
| credential_type | Type of credential (e.g., AWS, Azure, Vault) | AWS |
| inputs | Input fields specific to the credential type | |
Example: Creating an AWS Credential
---
name: "AWS Production"
description: "Production AWS credentials"
organization: "prod-org"
credential_type: "Amazon Web Services"
inputs:
username: "admin"
password: "secret"
Note: Ensure that sensitive data like passwords or keys are stored securely using Ansible Vault.
Warning: Do not store credentials in plain text files or version control systems.
10. Using Surveys
| Field | Description | Example |
|---|---|---|
| survey_enabled | Enables or disables the survey feature for a job template | true |
| survey_spec | JSON schema defining the survey questions and options | |
Example: Survey Configuration in Job Template
---
- name: Configure Job Template with Survey
hosts: localhost
tasks:
- name: Create job template with survey
awx.awx.job_template:
name: "Survey Job Template"
survey_enabled: true
survey_spec:
name: "User Input Survey"
questions:
- question_name: "What is your name?"
question_description: "Please enter your full name"
required: true
type: "text"
Note: Surveys are useful for collecting user input before running a job template. They can be used to gather information like environment names, application versions, or other runtime parameters.
11. Scheduling Jobs
| Property | Description | Values |
|---|---|---|
| job_template | The job template to schedule | string |
| enabled | Whether the schedule is active | true or false |
| rrule | Recurrence rule in iCalendar format | string |
| description | Optional description of the schedule | string |
Example: Create a Scheduled Job
---
- name: Schedule a job in AWX
hosts: localhost
gather_facts: false
tasks:
- name: Create a job schedule
awx.awx.job_schedule:
name: "Daily Backup Schedule"
job_template: "Backup Job Template"
rrule: "FREQ=DAILY;INTERVAL=1;BYHOUR=2"
enabled: true
Note: The
rrule uses iCalendar format. For example, FREQ=DAILY;INTERVAL=1;BYHOUR=2 schedules a job every day at 2 AM.
Warning: Ensure that the job template referenced in
job_template exists and is accessible to the user running the schedule.
12. Using AWX API
| Endpoint | Method | Description | Notes |
|---|---|---|---|
| /api/v2/projects/ | GET | Retrieve list of projects | Supports filtering and pagination |
| /api/v2/projects/{id}/ | GET | Retrieve specific project details | Includes job templates and inventory |
| /api/v2/job_templates/{id}/launch/ | POST | Launch a job template | Requires authentication and permissions |
| /api/v2/jobs/{id}/stdout/ | GET | Retrieve job output | Streaming response for long-running jobs |
Example: Launching a Job Template via API
curl -X POST \
"http://awx.example.com/api/v2/job_templates/123/launch/" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"extra_vars": {"host": "web01"}}'
Note: Ensure the user has appropriate permissions to launch job templates.
Warning: The
extra_vars field can execute arbitrary code if not sanitized.
| Field | Type | Description | Required |
|---|---|---|---|
| extra_vars | object | Variables to pass to the job | No |
| limit | string | Limit the hosts to run on | No |
| job_type | string | Type of job to run (run, check, dry-run) | No |