Navigation
AnsibleUpdated July 3, 2026

AWX Installation Guide

ansibleawxinstallationkubernetesakshelmoperatordeploymentconfiguration

AWX Installation Guide

Overview

This guide covers the installation and configuration of AWX (Ansible AWX) for the Epic on Azure environment. AWX serves as our centralized automation platform for managing Ansible playbooks, inventories, and job execution across all Epic environments.

Prerequisites

System Requirements

  • Kubernetes Cluster: AKS cluster with minimum 3 nodes
  • Storage: Persistent volume support (Azure Disk or Azure Files)
  • Resources: Minimum 8GB RAM, 4 CPU cores per node
  • Network: Ingress controller configured
  • DNS: FQDN for AWX web interface

Required Tools

  • kubectl CLI configured for target cluster
  • helm v3.x or later
  • awx-operator deployment tools
  • Azure CLI with appropriate permissions

Installation Methods

Method 1: Kubernetes Operator (Recommended)

1. Install AWX Operator

# Create AWX namespace
kubectl create namespace awx

# Apply AWX Operator
kubectl apply -f https://raw.githubusercontent.com/ansible/awx-operator/devel/deploy/awx-operator.yaml -n awx

# Wait for operator to be ready
kubectl wait --for=condition=Available deployment/awx-operator -n awx --timeout=300s

2. Configure AWX Instance

# awx-instance.yaml
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: epic-awx
  namespace: awx
spec:
  # Epic-specific configuration
  service_type: ClusterIP
  ingress_type: ingress
  hostname: awx.epic.optum.com

  # Resource specifications
  web_replicas: 2
  task_replicas: 2

  # Storage configuration
  postgres_storage_class: managed-premium
  postgres_storage_requirements:
    requests:
      storage: 100Gi

  # Projects storage
  projects_persistence: true
  projects_storage_class: azurefile
  projects_storage_size: 50Gi

  # Epic-specific settings
  admin_user: epic-admin
  admin_email: [email protected]

  # Resource limits
  web_resource_requirements:
    requests:
      cpu: 1000m
      memory: 2Gi
    limits:
      cpu: 2000m
      memory: 4Gi

  task_resource_requirements:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 1000m
      memory: 2Gi

  # Extra settings for Epic compliance
  extra_settings: |
    LOGGING['handlers']['console'] = {
        'class': 'logging.StreamHandler',
        'formatter': 'simple',
        'level': 'INFO'
    }
    LOGGING['loggers']['awx'] = {
        'handlers': ['console'],
        'level': 'INFO',
        'propagate': False
    }

    # Epic-specific session timeout
    SESSION_COOKIE_AGE = 28800  # 8 hours

    # LDAP integration for Epic users
    AUTH_LDAP_SERVER_URI = "ldaps://ldap.optum.com:636"
    AUTH_LDAP_BIND_DN = "CN=epic-awx-service,OU=Service Accounts,DC=optum,DC=com"

    # Epic security settings
    CSRF_COOKIE_SECURE = True
    SESSION_COOKIE_SECURE = True
    SECURE_SSL_REDIRECT = True

3. Deploy AWX Instance

# Apply AWX configuration
kubectl apply -f awx-instance.yaml

# Monitor deployment
kubectl logs -f deployment/awx-operator -n awx

# Wait for AWX to be ready
kubectl wait --for=condition=Running pod -l app.kubernetes.io/name=epic-awx -n awx --timeout=600s

Method 2: Helm Chart (Alternative)

# Add AWX Helm repository
helm repo add awx-operator https://ansible.github.io/awx-operator/
helm repo update

# Create values file for Epic configuration
cat > epic-awx-values.yaml <<EOF
AWX:
  spec:
    hostname: awx.epic.optum.com
    admin_user: epic-admin
    admin_email: [email protected]

    # Epic resource requirements
    web_replicas: 2
    task_replicas: 2

    web_resource_requirements:
      requests:
        cpu: 1000m
        memory: 2Gi
      limits:
        cpu: 2000m
        memory: 4Gi

    # Storage for Epic environment
    postgres_storage_class: managed-premium
    postgres_storage_requirements:
      requests:
        storage: 100Gi

    projects_persistence: true
    projects_storage_class: azurefile
    projects_storage_size: 50Gi
EOF

# Install AWX using Helm
helm install epic-awx awx-operator/awx-operator \
  --namespace awx \
  --create-namespace \
  --values epic-awx-values.yaml

Deploy AWX

Configure Ingress

# awx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: epic-awx-ingress
  namespace: awx
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
  tls:
    - hosts:
        - awx.epic.optum.com
      secretName: epic-awx-tls
  rules:
    - host: awx.epic.optum.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: epic-awx-service
                port:
                  number: 80

Configure Network Policies

# awx-network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: epic-awx-network-policy
  namespace: awx
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: epic-awx
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: ingress-nginx
      ports:
        - protocol: TCP
          port: 8052
  egress:
    - to: []
      ports:
        - protocol: TCP
          port: 443
        - protocol: TCP
          port: 22
        - protocol: UDP
          port: 53

Post-Installation Configuration

1. Initial Setup

# Get admin password
kubectl get secret epic-awx-admin-password -n awx -o jsonpath="{.data.password}" | base64 --decode

# Access AWX web interface
echo "AWX URL: https://awx.epic.optum.com"
echo "Username: epic-admin"
echo "Password: <from above command>"

2. Configure Authentication

LDAP Integration

# LDAP settings in AWX
AUTH_LDAP_SERVER_URI = "ldaps://ldap.optum.com:636"
AUTH_LDAP_BIND_DN = "CN=epic-awx-service,OU=Service Accounts,DC=optum,DC=com"
AUTH_LDAP_BIND_PASSWORD = "{{ awx_ldap_bind_password }}"

AUTH_LDAP_USER_SEARCH = LDAPSearch(
    "OU=Users,DC=optum,DC=com",
    ldap.SCOPE_SUBTREE,
    "(sAMAccountName=%(user)s)"
)

AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    "OU=Groups,DC=optum,DC=com",
    ldap.SCOPE_SUBTREE,
    "(objectClass=group)"
)

# Epic-specific LDAP group mappings
AUTH_LDAP_ORGANIZATION_MAP = {
    "Epic on Azure": {
        "admins": "CN=epic-awx-admins,OU=Groups,DC=optum,DC=com",
        "users": [
            "CN=epic-developers,OU=Groups,DC=optum,DC=com",
            "CN=epic-operators,OU=Groups,DC=optum,DC=com"
        ]
    }
}

AUTH_LDAP_TEAM_MAP = {
    "Epic Administrators": {
        "organization": "Epic on Azure",
        "users": "CN=epic-awx-admins,OU=Groups,DC=optum,DC=com"
    },
    "Epic Developers": {
        "organization": "Epic on Azure",
        "users": "CN=epic-developers,OU=Groups,DC=optum,DC=com"
    },
    "Epic Operations": {
        "organization": "Epic on Azure",
        "users": "CN=epic-operators,OU=Groups,DC=optum,DC=com"
    }
}

Note: The awx_ldap_bind_password should be stored securely in AWX credentials or Azure Key Vault, never hardcoded in configuration files.

3. Configure Projects

# Epic Projects setup via AWX CLI
awx projects create \
  --name "Epic Ansible Playbooks" \
  --organization "Epic on Azure" \
  --scm_type git \
  --scm_url "https://github.com/optum-tech-compute/ohemr-ansible-playbooks.git" \
  --scm_branch main \
  --scm_update_on_launch true

awx projects create \
  --name "Epic Ansible Roles" \
  --organization "Epic on Azure" \
  --scm_type git \
  --scm_url "https://github.com/optum-tech-compute/ansible-playbooks.git" \
  --scm_branch main \
  --scm_update_on_launch true

4. Configure Inventories

# Azure Dynamic Inventory
awx inventories create \
  --name "Epic Azure Dynamic Inventory" \
  --organization "Epic on Azure" \
  --description "Dynamic inventory from Azure subscription"

awx inventory_sources create \
  --name "Azure VMs" \
  --inventory "Epic Azure Dynamic Inventory" \
  --source azure_rm \
  --credential "Azure Service Principal" \
  --source_vars '{
    "plugin": "azure.azcollection.azure_rm",
    "include_vm_resource_groups": ["rg-epic-*"],
    "auth_source": "credential",
    "keyed_groups": [
      {
        "key": "tags",
        "prefix": "tag"
      },
      {
        "key": "azure_location",
        "prefix": "azure_location"
      }
    ]
  }'

5. Configure Credentials

Use the AWX web interface or CLI to configure the necessary credentials:

  • Azure Service Principal: For Azure resource management and dynamic inventory
  • Machine Credentials: For SSH access to Epic VMs
  • Vault Credentials: For Ansible Vault encrypted variables

Refer to the AWX Credentials Documentation for detailed credential configuration steps.

Epic-Specific Configuration

Job Templates

# Epic Application Deployment Job Template
awx job_templates create \
  --name "Epic Hyperspace Deployment" \
  --organization "Epic on Azure" \
  --project "Epic Ansible Playbooks" \
  --playbook "epic-hyperspace-deploy.yml" \
  --inventory "Epic Azure Dynamic Inventory" \
  --credential "Epic VM Admin" \
  --extra_vars '{
    "epic_application": "hyperspace",
    "epic_environment": "{{ epic_environment }}",
    "deployment_type": "rolling"
  }' \
  --ask_variables_on_launch true \
  --ask_limit_on_launch true

# Epic Configuration Management Job Template
awx job_templates create \
  --name "Epic Configuration Management" \
  --organization "Epic on Azure" \
  --project "Epic Ansible Roles" \
  --playbook "site.yml" \
  --inventory "Epic Azure Dynamic Inventory" \
  --credential "Epic VM Admin" \
  --extra_vars '{
    "epic_environment": "{{ epic_environment }}"
  }' \
  --ask_variables_on_launch true \
  --ask_limit_on_launch true

Workflow Templates

# Epic Full Stack Deployment Workflow
awx workflow_job_templates create \
  --name "Epic Full Stack Deployment" \
  --organization "Epic on Azure" \
  --description "Complete Epic environment deployment"

# Add workflow nodes (simplified example)
awx workflow_job_template_nodes create \
  --workflow_job_template "Epic Full Stack Deployment" \
  --unified_job_template "Epic Infrastructure Provision" \
  --identifier "provision"

awx workflow_job_template_nodes create \
  --workflow_job_template "Epic Full Stack Deployment" \
  --unified_job_template "Epic Configuration Management" \
  --identifier "configure" \
  --success_nodes "provision"

awx workflow_job_template_nodes create \
  --workflow_job_template "Epic Full Stack Deployment" \
  --unified_job_template "Epic Application Deployment" \
  --identifier "deploy" \
  --success_nodes "configure"

Monitoring and Maintenance

Health Checks

# Check AWX pod status
kubectl get pods -n awx -l app.kubernetes.io/name=epic-awx

# Check AWX logs
kubectl logs -n awx deployment/epic-awx-web -c epic-awx-web

# Check database connectivity
kubectl exec -n awx deployment/epic-awx-web -c epic-awx-web -- \
  awx-manage check_db

# Check Redis connectivity
kubectl exec -n awx deployment/epic-awx-web -c epic-awx-web -- \
  awx-manage check_redis

Backup and Recovery

# Backup AWX database
kubectl exec -n awx deployment/epic-awx-postgres -- \
  pg_dump -U awx awx > awx-backup-$(date +%Y%m%d).sql

# Backup AWX configuration
awx export --all > awx-config-backup-$(date +%Y%m%d).json

Performance Tuning

# awx-performance-config.yaml
spec:
  # Increase web replicas for high availability
  web_replicas: 3

  # Increase task replicas for job concurrency
  task_replicas: 4

  # Optimize resource limits
  web_resource_requirements:
    requests:
      cpu: 2000m
      memory: 4Gi
    limits:
      cpu: 4000m
      memory: 8Gi

  task_resource_requirements:
    requests:
      cpu: 1000m
      memory: 2Gi
    limits:
      cpu: 2000m
      memory: 4Gi

  # PostgreSQL optimization
  postgres_resource_requirements:
    requests:
      cpu: 1000m
      memory: 4Gi
    limits:
      cpu: 2000m
      memory: 8Gi

Security Considerations

Network Security

  • Use network policies to restrict traffic
  • Enable TLS for all communications
  • Configure firewall rules for Epic network segments

Authentication Security

  • Integrate with Epic LDAP/Active Directory
  • Enable two-factor authentication
  • Regular credential rotation

Data Security

  • Encrypt databases and storage
  • Use Azure Key Vault for secrets
  • Enable audit logging

Troubleshooting

Common Issues

AWX Pods Not Starting

# Check events
kubectl describe pods -n awx

# Check resource constraints
kubectl top pods -n awx

# Check storage provisioning
kubectl get pvc -n awx

Database Connection Issues

# Check PostgreSQL logs
kubectl logs -n awx deployment/epic-awx-postgres

# Test database connectivity
kubectl exec -n awx deployment/epic-awx-web -c epic-awx-web -- \
  psql -h epic-awx-postgres -U awx -d awx -c "SELECT version();"

Job Execution Failures

# Check job logs in AWX UI
# Verify inventory connectivity
# Check credential permissions
# Review playbook syntax

Performance Issues

# Monitor resource usage
kubectl top pods -n awx

# Check job queue status
awx jobs list --status pending

# Review database performance
kubectl exec -n awx deployment/epic-awx-postgres -- \
  psql -U awx -d awx -c "SELECT * FROM pg_stat_activity;"

Integration with Epic Tools

Terraform Integration

  • Use AWX to run post-provisioning configuration
  • Trigger AWX jobs from Terraform provisioners
  • Pass Terraform outputs as AWX variables

GitHub Actions Integration

  • Trigger AWX jobs from CI/CD pipelines
  • Use AWX API for automated deployments
  • Integrate with Epic deployment workflows

Monitoring Integration

  • Send AWX job status to monitoring systems
  • Alert on job failures
  • Track deployment metrics

Related Documentation

Support

  • AWX Issues: Internal DevOps team
  • Infrastructure: Platform engineering team
  • Epic Integration: Epic automation team
  • Training: Regular AWX workshops and documentation