--- - name: Deploy latest stable AWX using AWX Operator on Kubernetes hosts: localhost connection: local become: false gather_facts: false vars: # Основные параметры — переопределяй в Semaphore Variable Group awx_namespace: awx awx_instance_name: awx awx_service_type: NodePort # NodePort / ClusterIP / LoadBalancer awx_operator_version: 2.19.1 # Последняя стабильная на декабрь 2025 kubeconfig_path: "/home/semaphore/.kube/config" awx_storage_class: local-path # Предполагаем k3s или аналогичный кластер с local-path provisioner. Изменить на свой SC awx_projects_persistence: false # Отключаем persistence для projects для теста (чтобы избежать PVC проблем) awx_projects_storage_size: 8Gi # Если persistence: true tasks: - name: Fail if kubeconfig not found inside container ansible.builtin.stat: path: "{{ kubeconfig_path }}" register: kubeconfig_stat failed_when: not kubeconfig_stat.stat.exists delegate_to: localhost - name: Create namespace for AWX kubernetes.core.k8s: state: present kubeconfig: "{{ kubeconfig_path }}" definition: apiVersion: v1 kind: Namespace metadata: name: "{{ awx_namespace }}" - name: Apply AWX Operator from GitHub kustomize ansible.builtin.command: cmd: >- kubectl apply -k "github.com/ansible/awx-operator/config/default?ref={{ awx_operator_version }}" environment: KUBECONFIG: "{{ kubeconfig_path }}" changed_when: true register: operator_apply failed_when: operator_apply.rc != 0 and 'already exists' not in operator_apply.stderr | default('') - name: Wait for AWX Operator to be ready kubernetes.core.k8s_info: kubeconfig: "{{ kubeconfig_path }}" api_version: apps/v1 kind: Deployment name: awx-operator-controller-manager namespace: "{{ awx_namespace }}" register: operator_status until: >- operator_status.resources | length > 0 and operator_status.resources[0].status.readyReplicas is defined and operator_status.resources[0].status.readyReplicas >= 1 retries: 40 delay: 15 - name: Ensure default StorageClass for persistence (assume local-path for k3s-like clusters) kubernetes.core.k8s: state: present kubeconfig: "{{ kubeconfig_path }}" definition: apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: "{{ awx_storage_class }}" annotations: storageclass.kubernetes.io/is-default-class: "true" provisioner: rancher.io/local-path # Для k3s; изменить на свой provisioner (e.g., kubernetes.io/no-provisioner) reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer # Избежать immediate bind ошибок на multi-node - name: Deploy AWX instance kubernetes.core.k8s: state: present kubeconfig: "{{ kubeconfig_path }}" definition: apiVersion: awx.ansible.com/v1beta1 kind: AWX metadata: name: "{{ awx_instance_name }}" namespace: "{{ awx_namespace }}" spec: service_type: "{{ awx_service_type }}" postgres_storage_class: "{{ awx_storage_class }}" # Указываем SC для postgres PVC projects_persistence: "{{ awx_projects_persistence }}" # false для теста, чтобы избежать дополнительного PVC projects_storage_class: "{{ awx_storage_class }}" # Если persistence: true projects_storage_size: "{{ awx_projects_storage_size }}" - name: Wait for AWX pods to be running (increased retries for slow storage provisioning) kubernetes.core.k8s_info: kubeconfig: "{{ kubeconfig_path }}" kind: Pod namespace: "{{ awx_namespace }}" label_selectors: - "app.kubernetes.io/managed-by=awx-operator" register: awx_pods until: >- awx_pods.resources | selectattr('status.phase', 'equalto', 'Running') | list | length >= 2 retries: 90 # Увеличено для ожидания provisioning PVC/PV delay: 20 - name: Retrieve AWX admin password kubernetes.core.k8s_info: kubeconfig: "{{ kubeconfig_path }}" api_version: v1 kind: Secret name: "{{ awx_instance_name }}-admin-password" namespace: "{{ awx_namespace }}" register: awx_secret - name: Display AWX login information ansible.builtin.debug: msg: | AWX deployed successfully! Access URL: http://: (get port: kubectl get svc {{ awx_instance_name }}-service -n {{ awx_namespace }}) Username: admin Password: {{ awx_secret.resources[0].data.password | b64decode }} Note: If persistence issues persist, ensure your cluster has a working provisioner (e.g., local-path in k3s) and default StorageClass set.