AWX und Ansible Tower stellen webbasierte Benutzeroberflächen für Ansible-Automatisierung bereit. Sie erweitern CLI-Ansible um zentrale Jobverwaltung, Rollenkontrolle, Auditierung und Skalierbarkeit für Teamumgebungen. Die Plattformen ermöglichen die Kapselung von Ansible-Expertise in benutzerfreundliche Schnittstellen für Nicht-Ansible-Experten.
AWX ist das Open-Source-Upstream-Projekt mit kontinuierlichen Releases und experimentellen Features. Ansible Tower basiert auf AWX-Snapshots mit Long-Term-Support, kommerziellem Support und zusätzlichen Enterprise-Features wie Smart Inventory und erweiterten Analytics.
Versionierungsunterschiede:
Feature-Divergenz:
Core-Komponenten:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Web UI │ │ REST API │ │ Scheduler │
│ (Django) │ │ (DRF) │ │ (Celery) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└────────────────────────┼────────────────────────┘
│
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Task Workers │ │ Message Queue │ │ Database │
│ (ansible- │◄───┤ (Redis/ │ │ (PostgreSQL) │
│ playbook) │ │ RabbitMQ) │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Storage-Layer: - PostgreSQL: Primäre Datenbank für Konfiguration, Benutzer, Job-Historie - Redis: Session-Store, Caching, Message-Broker (AWX 19+) - RabbitMQ: Message-Broker für Job-Queuing (Tower/ältere AWX-Versionen)
Execution-Layer: - Execution Nodes: Ansible-Playbook-Ausführung in isolierten Containern - Control Nodes: Job-Scheduling und UI-Services - Hybrid Nodes: Kombinierte Control/Execution-Funktionalität
Internet/Users
│
▼
┌─────────────────────────────────────────────────────────┐
│ Load Balancer │
│ (nginx/HAProxy) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ AWX Web Tier │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Web UI │ │ REST API │ │ WebSocket │ │
│ │ (Django) │ │ (DRF) │ │ Events │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ Message Queue Layer │
│ Redis Cluster / RabbitMQ Cluster │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Execution Tier │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Task Worker │ │ Task Worker │ │ Task Worker │ │
│ │ Node 1 │ │ Node 2 │ │ Node N │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Data Layer │
│ PostgreSQL Cluster │
│ (Primary + Read Replicas) │
└─────────────────────────────────────────────────────────┘
AWX Operator auf Kubernetes:
# awx-operator-deployment.yml
apiVersion: v1
kind: Namespace
metadata:
name: awx
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: awx-operator
namespace: awx
spec:
channel: release-21.x
name: awx-operator
source: operatorhubio-catalog
sourceNamespace: olm
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx-production
namespace: awx
spec:
service_type: LoadBalancer
ingress_type: ingress
hostname: awx.company.com
admin_user: admin
admin_password_secret: awx-admin-password
postgres_configuration_secret: awx-postgres-configuration
secret_key_secret: awx-secret-key
# Resource specifications
web_replicas: 2
task_replicas: 2
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
# Storage configuration
postgres_storage_class: fast-ssd
postgres_storage_requirements:
requests:
storage: 50Gi
# Security context
security_context_settings:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000Secrets für AWX-Operator:
# Admin-Passwort erstellen
kubectl create secret generic awx-admin-password \
--from-literal=password='SecureAdminPassword2023!' \
-n awx
# PostgreSQL-Konfiguration
kubectl create secret generic awx-postgres-configuration \
--from-literal=host=postgres.awx.svc.cluster.local \
--from-literal=port=5432 \
--from-literal=database=awx \
--from-literal=username=awx \
--from-literal=password='PostgresPassword2023!' \
--from-literal=sslmode=prefer \
--from-literal=type=managed \
-n awx
# Secret Key für Verschlüsselung
kubectl create secret generic awx-secret-key \
--from-literal=secret_key="$(openssl rand -base64 32)" \
-n awxHelm-Chart-Installation:
# AWX Helm Repository hinzufügen
helm repo add awx-operator https://ansible.github.io/awx-operator/
helm repo update
# Values-Datei erstellen
cat > awx-values.yml << 'EOF'
AWX:
enabled: true
name: awx-production
spec:
hostname: awx.company.com
service_type: ClusterIP
ingress_type: ingress
ingress_annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
ingress_tls_secret: awx-tls-secret
# High Availability
web_replicas: 3
task_replicas: 2
# External PostgreSQL
postgres_configuration_secret: awx-postgres-external
# Resource limits
web_resource_requirements:
requests:
cpu: "1"
memory: 2Gi
limits:
cpu: "2"
memory: 4Gi
# Backup configuration
backup_pvc: awx-backup-claim
backup_pvc_namespace: awx
EOF
# Installation
helm install awx-production awx-operator/awx-operator \
--namespace awx \
--create-namespace \
--values awx-values.ymlDocker Compose für Development:
# docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:13
environment:
POSTGRES_DB: awx
POSTGRES_USER: awx
POSTGRES_PASSWORD: awxpass
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
redis:
image: redis:7
restart: unless-stopped
awx_web:
image: quay.io/ansible/awx:21.x.x
depends_on:
- postgres
- redis
environment:
DATABASE_USER: awx
DATABASE_PASSWORD: awxpass
DATABASE_NAME: awx
DATABASE_PORT: 5432
DATABASE_HOST: postgres
REDIS_HOST: redis
SECRET_KEY: awxsecret
volumes:
- awx_projects:/var/lib/awx/projects
- awx_rsyslog:/var/log/rsyslog
ports:
- "8080:8052"
restart: unless-stopped
awx_task:
image: quay.io/ansible/awx:21.x.x
depends_on:
- postgres
- redis
environment:
DATABASE_USER: awx
DATABASE_PASSWORD: awxpass
DATABASE_NAME: awx
DATABASE_PORT: 5432
DATABASE_HOST: postgres
REDIS_HOST: redis
SECRET_KEY: awxsecret
volumes:
- awx_projects:/var/lib/awx/projects
- awx_rsyslog:/var/log/rsyslog
restart: unless-stopped
volumes:
postgres_data:
awx_projects:
awx_rsyslog:Organisationen gruppieren Benutzer, Teams und Ressourcen für Mandantentrennung:
# CLI-basierte Konfiguration mit awx-cli
awx organizations create \
--name "Production Infrastructure" \
--description "Production environment management"
awx organizations create \
--name "Development Team" \
--description "Development and staging environments"Projekte verknüpfen Git-Repositories mit AWX:
# Git-Projekt erstellen
awx projects create \
--name "Infrastructure Playbooks" \
--organization "Production Infrastructure" \
--scm_type git \
--scm_url "https://github.com/company/ansible-infrastructure.git" \
--scm_branch main \
--scm_credential "GitHub Deploy Key" \
--scm_update_on_launch true \
--scm_update_cache_timeout 300Inventories definieren Host-Gruppen und Variablen:
# Statisches Inventory
awx inventory create \
--name "Production Servers" \
--organization "Production Infrastructure" \
--variables @- << 'EOF'
{
"env": "production",
"backup_enabled": true,
"monitoring_enabled": true
}
EOF
# Inventory-Hosts hinzufügen
awx hosts create \
--name "web-01.company.com" \
--inventory "Production Servers" \
--variables '{"server_role": "web", "datacenter": "us-east-1"}'
awx hosts create \
--name "db-01.company.com" \
--inventory "Production Servers" \
--variables '{"server_role": "database", "datacenter": "us-east-1"}'Credential-Management:
# SSH-Credential für Server-Zugriff
awx credentials create \
--name "Production SSH Key" \
--organization "Production Infrastructure" \
--credential_type "Machine" \
--inputs @- << 'EOF'
{
"username": "ansible",
"ssh_key_data": "-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----",
"become_method": "sudo",
"become_username": "root"
}
EOF
# Git-Credential für private Repositories
awx credentials create \
--name "GitHub Deploy Key" \
--organization "Production Infrastructure" \
--credential_type "Source Control" \
--inputs @- << 'EOF'
{
"ssh_key_data": "-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----"
}
EOF
# Vault-Credential für verschlüsselte Daten
awx credentials create \
--name "Ansible Vault Production" \
--organization "Production Infrastructure" \
--credential_type "Vault" \
--inputs '{"vault_password": "ProductionVaultPassword2023!"}'Job Templates konfigurieren:
# Basis Job Template
awx job_templates create \
--name "Deploy Web Application" \
--organization "Production Infrastructure" \
--project "Infrastructure Playbooks" \
--playbook "playbooks/deploy_webapp.yml" \
--inventory "Production Servers" \
--credential "Production SSH Key" \
--vault_credential "Ansible Vault Production" \
--job_type run \
--verbosity 1 \
--limit "web_servers" \
--job_tags "deploy,config" \
--ask_variables_on_launch true \
--ask_limit_on_launch true
# Survey für Benutzerinteraktion
awx job_templates modify "Deploy Web Application" \
--survey_spec @- << 'EOF'
{
"name": "Deployment Survey",
"description": "Configure deployment parameters",
"spec": [
{
"question_name": "Application Version",
"question_description": "Version to deploy",
"variable": "app_version",
"type": "text",
"required": true,
"default": "latest"
},
{
"question_name": "Environment",
"question_description": "Target environment",
"variable": "target_env",
"type": "multiplechoice",
"choices": ["staging", "production"],
"required": true,
"default": "staging"
},
{
"question_name": "Backup Before Deploy",
"question_description": "Create backup before deployment",
"variable": "create_backup",
"type": "boolean",
"required": false,
"default": true
}
]
}
EOFTeam-basierte Rechteverwaltung:
# Teams erstellen
awx teams create \
--name "Infrastructure Team" \
--organization "Production Infrastructure" \
--description "Infrastructure administrators"
awx teams create \
--name "Developers" \
--organization "Production Infrastructure" \
--description "Application developers"
# Benutzer zu Teams hinzufügen
awx teams associate \
--team "Infrastructure Team" \
--user "alice" \
--user "bob"
awx teams associate \
--team "Developers" \
--user "charlie" \
--user "diana"
# Rollenbasierte Berechtigungen
awx role grant \
--team "Infrastructure Team" \
--type "admin" \
--target-team "Infrastructure Team"
awx role grant \
--team "Infrastructure Team" \
--type "execute" \
--target-job-template "Deploy Web Application"
awx role grant \
--team "Developers" \
--type "read" \
--target-inventory "Production Servers"
awx role grant \
--team "Developers" \
--type "execute" \
--target-job-template "Deploy Web Application"Git-Projekt mit Webhook-Integration:
# Erweiterte Git-Konfiguration
awx projects create \
--name "Microservices Deployment" \
--organization "Production Infrastructure" \
--scm_type git \
--scm_url "https://github.com/company/microservices-ansible.git" \
--scm_branch main \
--scm_credential "GitHub Deploy Key" \
--scm_update_on_launch true \
--scm_update_cache_timeout 0 \
--scm_clean true \
--scm_delete_on_update true \
--custom_virtualenv "/var/lib/awx/venv/custom-python"
# Webhook für automatische Updates
PROJECT_ID=$(awx projects list --name "Microservices Deployment" --format json | jq -r '.results[0].id')
awx projects update $PROJECT_IDSmart Inventory mit dynamischen Gruppen:
# Smart Inventory basierend auf Host-Variablen
awx inventory create \
--name "Production Web Servers" \
--organization "Production Infrastructure" \
--kind smart \
--host_filter 'server_role="web" and datacenter="us-east-1"'
# Inventory-Quellen für Cloud-Provider
awx inventory_sources create \
--name "AWS EC2 Source" \
--inventory "Production Servers" \
--source ec2 \
--credential "AWS Production Account" \
--source_regions "us-east-1,us-west-2" \
--instance_filters 'tag:Environment=production' \
--group_by 'tag_Name,tag_Environment,instance_type' \
--update_on_launch true \
--update_cache_timeout 1800Komplexes Job Template mit Notifications:
# Job Template mit erweiterten Optionen
awx job_templates create \
--name "Full Stack Deployment" \
--organization "Production Infrastructure" \
--project "Microservices Deployment" \
--playbook "site.yml" \
--inventory "Production Servers" \
--credential "Production SSH Key" \
--vault_credential "Ansible Vault Production" \
--cloud_credential "AWS Production Account" \
--job_type run \
--verbosity 2 \
--diff_mode true \
--concurrent_jobs_enabled false \
--ask_variables_on_launch true \
--ask_limit_on_launch true \
--ask_tags_on_launch true \
--webhook_service github \
--webhook_credential "GitHub Webhook Secret"
# Job ausführen mit Extra-Variablen
awx job_templates launch "Full Stack Deployment" \
--extra_vars @- << 'EOF'
{
"deployment_id": "deploy-2023-001",
"rollback_enabled": true,
"health_check_timeout": 300,
"notification_channels": ["slack", "email"]
}
EOF \
--limit "web_servers:&production" \
--tags "deploy,config,verify"Granulare RBAC-Konfiguration:
# Custom-Rollen für spezifische Aufgaben
awx role create \
--name "Deployment Manager" \
--description "Can execute deployment jobs but not modify templates"
# Objektspezifische Berechtigungen
awx role grant \
--user "deployment_user" \
--type "execute" \
--target-job-template "Deploy Web Application"
awx role grant \
--user "deployment_user" \
--type "read" \
--target-inventory "Production Servers"
# Team-hierarchien und Vererbung
awx teams create \
--name "Senior DevOps" \
--organization "Production Infrastructure"
awx teams associate \
--team "Senior DevOps" \
--parent-team "Infrastructure Team"
# Conditional-Access basierend auf Ressourcen
awx role grant \
--team "Developers" \
--type "execute" \
--target-job-template "Deploy to Staging" \
--condition "target_env != 'production'"LDAP-Konfiguration über Settings-API:
# LDAP-Settings konfigurieren
awx settings modify \
--setting AUTH_LDAP_SERVER_URI \
--value "ldaps://ldap.company.com:636"
awx settings modify \
--setting AUTH_LDAP_BIND_DN \
--value "cn=ansible,ou=service,dc=company,dc=com"
awx settings modify \
--setting AUTH_LDAP_USER_SEARCH \
--value '[
"ou=users,dc=company,dc=com",
"(uid=%(user)s)",
{
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
]'
# LDAP-Gruppen-Mapping
awx settings modify \
--setting AUTH_LDAP_GROUP_SEARCH \
--value '[
"ou=groups,dc=company,dc=com",
"(objectClass=groupOfNames)",
"cn"
]'
# Team-Mapping für LDAP-Gruppen
awx settings modify \
--setting AUTH_LDAP_ORGANIZATION_MAP \
--value '{
"Production Infrastructure": {
"users": ["cn=ansible-users,ou=groups,dc=company,dc=com"],
"admins": ["cn=ansible-admins,ou=groups,dc=company,dc=com"]
}
}'Activity Stream und Job-Ausgaben:
# Job-Logs abrufen
JOB_ID=$(awx jobs list --name "Deploy Web Application" --status successful --format json | jq -r '.results[0].id')
awx jobs stdout $JOB_ID
# Activity Stream für Audit-Trail
awx activity_stream list \
--object_type job_template \
--object_id 15 \
--format json | jq '.results[] | {timestamp, operation, actor, changes}'
# Event-basierte Logs
awx job_events list \
--job $JOB_ID \
--event task \
--format json | jq '.results[] | {task, host, status, created}'Notification Templates:
# Slack-Notification
awx notification_templates create \
--name "Slack Deployment Alerts" \
--organization "Production Infrastructure" \
--notification_type slack \
--notification_configuration @- << 'EOF'
{
"token": "xoxb-slack-bot-token",
"channels": ["#infrastructure", "#deployments"],
"username": "AWX Bot",
"icon_emoji": ":robot_face:",
"hex_color": "#FF0000"
}
EOF
# E-Mail-Notification
awx notification_templates create \
--name "Email Operations Team" \
--organization "Production Infrastructure" \
--notification_type email \
--notification_configuration @- << 'EOF'
{
"username": "awx@company.com",
"password": "smtp_password",
"sender": "awx@company.com",
"recipients": ["ops@company.com", "oncall@company.com"],
"host": "smtp.company.com",
"port": 587,
"use_tls": true,
"use_ssl": false
}
EOF
# Webhook für externe Systeme
awx notification_templates create \
--name "ServiceNow Integration" \
--organization "Production Infrastructure" \
--notification_type webhook \
--notification_configuration @- << 'EOF'
{
"url": "https://company.service-now.com/api/now/table/incident",
"http_method": "POST",
"headers": {
"Authorization": "Bearer servicenow_token",
"Content-Type": "application/json"
},
"username": "awx_integration",
"password": "servicenow_password"
}
EOF
# Notifications an Job Templates binden
awx job_templates associate \
--job_template "Deploy Web Application" \
--notification_template_started "Slack Deployment Alerts"
awx job_templates associate \
--job_template "Deploy Web Application" \
--notification_template_success "Email Operations Team"
awx job_templates associate \
--job_template "Deploy Web Application" \
--notification_template_error "ServiceNow Integration"REST-API-Integration mit curl:
# Token-basierte Authentifizierung
AWX_TOKEN="your_awx_api_token"
AWX_URL="https://awx.company.com"
# Job Template ausführen
curl -X POST \
-H "Authorization: Bearer $AWX_TOKEN" \
-H "Content-Type: application/json" \
"$AWX_URL/api/v2/job_templates/15/launch/" \
-d @- << 'EOF'
{
"extra_vars": {
"app_version": "v2.1.0",
"deployment_strategy": "blue_green",
"health_check_enabled": true
},
"limit": "web_servers",
"job_tags": "deploy,verify",
"inventory": 25
}
EOF
# Job-Status überwachen
JOB_ID=$(curl -s -H "Authorization: Bearer $AWX_TOKEN" \
"$AWX_URL/api/v2/jobs/?order_by=-id&page_size=1" | \
jq -r '.results[0].id')
# Polling für Job-Completion
while true; do
STATUS=$(curl -s -H "Authorization: Bearer $AWX_TOKEN" \
"$AWX_URL/api/v2/jobs/$JOB_ID/" | \
jq -r '.status')
echo "Job $JOB_ID status: $STATUS"
if [[ "$STATUS" == "successful" || "$STATUS" == "failed" || "$STATUS" == "canceled" ]]; then
break
fi
sleep 10
doneGitLab CI Pipeline mit AWX-Integration:
# .gitlab-ci.yml
stages:
- build
- test
- deploy
variables:
AWX_URL: "https://awx.company.com"
AWX_TOKEN: "$AWX_API_TOKEN" # GitLab CI Variable
build:
stage: build
script:
- docker build -t app:$CI_COMMIT_SHA .
- docker push registry.company.com/app:$CI_COMMIT_SHA
test:
stage: test
script:
- pytest tests/
- coverage report
deploy:staging:
stage: deploy
script:
- |
# AWX Job Template für Staging-Deployment
JOB_RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer $AWX_TOKEN" \
-H "Content-Type: application/json" \
"$AWX_URL/api/v2/job_templates/staging_deploy/launch/" \
-d "{
\"extra_vars\": {
\"app_version\": \"$CI_COMMIT_SHA\",
\"git_commit\": \"$CI_COMMIT_SHA\",
\"pipeline_id\": \"$CI_PIPELINE_ID\",
\"deployed_by\": \"$GITLAB_USER_NAME\"
}
}")
JOB_ID=$(echo $JOB_RESPONSE | jq -r '.id')
echo "AWX Job ID: $JOB_ID"
# Job-Status überwachen
bash scripts/wait_for_awx_job.sh $JOB_ID
environment:
name: staging
url: https://staging.company.com
only:
- develop
deploy:production:
stage: deploy
script:
- |
# Production Deployment mit Approval
JOB_RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer $AWX_TOKEN" \
-H "Content-Type: application/json" \
"$AWX_URL/api/v2/job_templates/production_deploy/launch/" \
-d "{
\"extra_vars\": {
\"app_version\": \"$CI_COMMIT_TAG\",
\"release_notes\": \"$CI_COMMIT_DESCRIPTION\",
\"rollback_version\": \"$(git describe --tags --abbrev=0 HEAD~1)\"
}
}")
JOB_ID=$(echo $JOB_RESPONSE | jq -r '.id')
bash scripts/wait_for_awx_job.sh $JOB_ID
environment:
name: production
url: https://production.company.com
when: manual
only:
- tagsJob-Monitoring-Skript:
#!/bin/bash
# scripts/wait_for_awx_job.sh
JOB_ID=$1
MAX_WAIT=1800 # 30 Minuten
WAIT_INTERVAL=30
start_time=$(date +%s)
while true; do
current_time=$(date +%s)
elapsed=$((current_time - start_time))
if [ $elapsed -gt $MAX_WAIT ]; then
echo "Job $JOB_ID timed out after $MAX_WAIT seconds"
exit 1
fi
JOB_STATUS=$(curl -s -H "Authorization: Bearer $AWX_TOKEN" \
"$AWX_URL/api/v2/jobs/$JOB_ID/" | jq -r '.status')
echo "$(date): Job $JOB_ID status: $JOB_STATUS"
case "$JOB_STATUS" in
"successful")
echo "Job completed successfully"
exit 0
;;
"failed"|"error"|"canceled")
echo "Job failed with status: $JOB_STATUS"
# Job-Logs ausgeben
curl -s -H "Authorization: Bearer $AWX_TOKEN" \
"$AWX_URL/api/v2/jobs/$JOB_ID/stdout/?format=txt_download"
exit 1
;;
"pending"|"waiting"|"running")
sleep $WAIT_INTERVAL
;;
*)
echo "Unknown job status: $JOB_STATUS"
exit 1
;;
esac
doneVollständige AWX-Backup-Konfiguration:
# PostgreSQL-Backup mit pg_dump
#!/bin/bash
# backup_awx.sh
BACKUP_DIR="/backup/awx/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
# Datenbank-Backup
pg_dump -h postgres.awx.svc.cluster.local \
-U awx \
-d awx \
--format=custom \
--file="$BACKUP_DIR/awx_database.backup"
# Projekt-Dateien sichern
kubectl exec -n awx deployment/awx-production-web \
-- tar czf - /var/lib/awx/projects | \
cat > "$BACKUP_DIR/awx_projects.tar.gz"
# Secret-Export für Disaster Recovery
kubectl get secrets -n awx -o yaml > "$BACKUP_DIR/awx_secrets.yaml"
# AWX-Konfiguration exportieren
awx export \
--organization "Production Infrastructure" \
--format json > "$BACKUP_DIR/awx_config.json"
# Backup-Verifikation
tar -tzf "$BACKUP_DIR/awx_projects.tar.gz" > /dev/null
pg_restore --list "$BACKUP_DIR/awx_database.backup" > /dev/null
echo "Backup completed: $BACKUP_DIR"Automatisierte Backup-Pipeline:
# backup-cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
name: awx-backup
namespace: awx
spec:
schedule: "0 2 * * *" # Täglich um 2:00 Uhr
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: postgres:13
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: awx-postgres-configuration
key: password
command:
- /bin/bash
- -c
- |
# Database backup
pg_dump -h $DATABASE_HOST -U $DATABASE_USER -d $DATABASE_NAME \
--format=custom \
--file=/backup/awx_$(date +%Y%m%d_%H%M%S).backup
# Upload to S3
aws s3 cp /backup/awx_$(date +%Y%m%d_%H%M%S).backup \
s3://company-awx-backups/database/
volumeMounts:
- name: backup-storage
mountPath: /backup
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: awx-backup-pvc
restartPolicy: OnFailureMulti-Tenant-Architektur:
# Umgebungsspezifische Organisationen
awx organizations create \
--name "Production" \
--description "Production environment only"
awx organizations create \
--name "Staging" \
--description "Staging and testing environments"
awx organizations create \
--name "Development" \
--description "Development environments"
# Isolierte Execution Environments
awx execution_environments create \
--name "Production EE" \
--image "registry.company.com/awx-ee:production" \
--organization "Production"
awx execution_environments create \
--name "Development EE" \
--image "registry.company.com/awx-ee:development" \
--organization "Development"
# Umgebungsspezifische Instance Groups
awx instance_groups create \
--name "production-workers" \
--instances "prod-worker-01,prod-worker-02,prod-worker-03"
awx instance_groups create \
--name "development-workers" \
--instances "dev-worker-01,dev-worker-02"
# Resource-Isolation
awx job_templates modify "Production Deployment" \
--instance_groups "production-workers" \
--execution_environment "Production EE"GitOps-Workflow für AWX-Konfiguration:
# awx-config-repo/environments/production/job_templates.yml
job_templates:
- name: "Deploy Web Application"
project: "Infrastructure Playbooks"
playbook: "playbooks/deploy_webapp.yml"
inventory: "Production Servers"
credentials:
- "Production SSH Key"
- "Ansible Vault Production"
execution_environment: "Production EE"
instance_groups:
- "production-workers"
extra_vars:
environment: production
backup_enabled: true
health_checks: true
survey_enabled: true
survey_spec:
name: "Deployment Parameters"
spec:
- question_name: "Application Version"
variable: "app_version"
type: "text"
required: true
default: "latest"
- question_name: "Rolling Deployment"
variable: "rolling_deployment"
type: "boolean"
required: false
default: true
- name: "Database Maintenance"
project: "Infrastructure Playbooks"
playbook: "playbooks/db_maintenance.yml"
inventory: "Production Database Servers"
credentials:
- "Production SSH Key"
- "Database Admin Credential"
schedule:
name: "Weekly DB Maintenance"
rrule: "DTSTART:20231201T020000Z RRULE:FREQ=WEEKLY;BYDAY=SU"
enabled: trueAutomated Configuration Deployment:
#!/bin/bash
# deploy_awx_config.sh
CONFIG_REPO="https://github.com/company/awx-configuration.git"
ENVIRONMENT=${1:-production}
# Repository klonen
git clone $CONFIG_REPO /tmp/awx-config
cd /tmp/awx-config
# Environment-spezifische Konfiguration anwenden
for config_file in environments/$ENVIRONMENT/*.yml; do
echo "Applying configuration from $config_file"
case $(basename $config_file) in
"organizations.yml")
yq eval '.organizations[]' $config_file | \
while IFS= read -r org; do
awx organizations create --name "$org.name" --description "$org.description"
done
;;
"job_templates.yml")
yq eval '.job_templates[]' $config_file | \
while IFS= read -r template; do
awx job_templates create \
--name "$template.name" \
--project "$template.project" \
--playbook "$template.playbook" \
--inventory "$template.inventory"
done
;;
"schedules.yml")
yq eval '.schedules[]' $config_file | \
while IFS= read -r schedule; do
awx schedules create \
--name "$schedule.name" \
--rrule "$schedule.rrule" \
--job-template "$schedule.job_template"
done
;;
esac
done
# Cleanup
rm -rf /tmp/awx-config