diff --git a/ansible/deploy_awx_k8s.yml b/ansible/deploy_awx_k8s.yml index ce04eb3..d5eb61f 100644 --- a/ansible/deploy_awx_k8s.yml +++ b/ansible/deploy_awx_k8s.yml @@ -1,92 +1,127 @@ --- -- name: Deploy latest AWX on Kubernetes using AWX Operator +- name: Deploy latest stable AWX using AWX Operator on Kubernetes hosts: localhost connection: local become: false gather_facts: false vars: - awx_namespace: awx - awx_operator_version: 2.19.1 # Latest as of available releases; corresponds to AWX 24.6.1 - awx_instance_name: awx-demo - awx_service_type: nodeport # Change to 'clusterip' if using ingress or on OpenShift + # Основные параметры — лучше переопределять в Semaphore Variable Group + awx_namespace: "{{ awx_namespace | default('awx') }}" + awx_instance_name: "{{ awx_instance_name | default('awx') }}" + awx_service_type: "{{ awx_service_type | default('NodePort') }}" # NodePort / ClusterIP / LoadBalancer + awx_operator_version: "{{ awx_operator_version | default('2.19.1') }}" # 2.19.1 → AWX 24.6.x (последняя стабильная на конец 2025) - collections: - - kubernetes.core + # Путь к kubeconfig внутри контейнера Semaphore + kubeconfig_path: "/home/semaphore/.kube/config" tasks: - - name: Ensure kubernetes.core collection is installed - command: ansible-galaxy collection install kubernetes.core - changed_when: false - ignore_errors: true # In case already installed + - name: Fail if kubeconfig not found + ansible.builtin.stat: + path: "{{ kubeconfig_path }}" + register: kubeconfig_stat + failed_when: not kubeconfig_stat.stat.exists + delegate_to: localhost - - name: Create AWX namespace - k8s: + - name: Install kubernetes python library (fallback) + ansible.builtin.pip: + name: kubernetes>=25.3.0 state: present + delegate_to: localhost + ignore_errors: true # если уже стоит через /etc/semaphore/requirements.txt + + - name: Create namespace for AWX + kubernetes.core.k8s: + state: present + kubeconfig: "{{ kubeconfig_path }}" definition: apiVersion: v1 kind: Namespace metadata: name: "{{ awx_namespace }}" - kubeconfig: /home/semaphore/.kube/config - - name: Set current namespace context (optional, for convenience) - command: kubectl config set-context --current --namespace={{ awx_namespace }} - changed_when: false - - - name: Install AWX Operator using kustomize - command: >- - kubectl apply -k "github.com/ansible/awx-operator/config/default?ref={{ awx_operator_version }}" + - name: Apply AWX Operator (via kustomize from github) + ansible.builtin.command: + cmd: >- + kubectl apply -k "github.com/ansible/awx-operator/config/default?ref={{ awx_operator_version }}" + creates: "{{ kubeconfig_path }}" # dummy — чтобы не повторять каждый раз environment: - KUBECONFIG: /home/semaphore/.kube/config - changed_when: false + KUBECONFIG: "{{ kubeconfig_path }}" + changed_when: true + register: operator_apply + failed_when: operator_apply.rc != 0 and 'already exists' not in operator_apply.stderr - - name: Wait for AWX Operator to be ready - k8s_info: + - name: Wait for AWX Operator deployment to be ready + kubernetes.core.k8s_info: + kubeconfig: "{{ kubeconfig_path }}" api_version: apps/v1 kind: Deployment - namespace: "{{ awx_namespace }}" name: awx-operator-controller-manager - register: operator_deployment - until: operator_deployment.resources[0].status.readyReplicas == operator_deployment.resources[0].status.replicas - retries: 30 - delay: 10 - - - name: Create AWX instance - k8s: - state: present namespace: "{{ awx_namespace }}" + register: operator_status + until: >- + operator_status.resources[0].status.readyReplicas is defined and + operator_status.resources[0].status.readyReplicas == operator_status.resources[0].status.replicas + retries: 40 + delay: 15 + + - 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 }}" + # Можно добавить/раскомментировать по необходимости: + # ingress_type: Ingress + # ingress_hostname: awx.your-domain.com + # ingress_class_name: nginx + # replicas: 1 + # projects_persistence: true + # projects_storage_class: standard + # projects_storage_size: 10Gi - - name: Wait for AWX pods to be ready - k8s_info: + - name: Wait for AWX pods to become ready (up to ~10–15 minutes) + kubernetes.core.k8s_info: + kubeconfig: "{{ kubeconfig_path }}" kind: Pod namespace: "{{ awx_namespace }}" label_selectors: - "app.kubernetes.io/managed-by=awx-operator" + - "app.kubernetes.io/name={{ awx_instance_name }}" register: awx_pods until: >- - awx_pods.resources | selectattr('status.phase', 'equalto', 'Running') | length == awx_pods.resources | length + awx_pods.resources | selectattr('status.phase', 'equalto', 'Running') | list | length >= 2 and + (awx_pods.resources | selectattr('status.conditions', 'search', 'type: Ready, status: True') | list | length >= 2) retries: 60 - delay: 10 + delay: 20 - - name: Get AWX admin password - k8s_info: + - name: Get AWX admin password from secret + kubernetes.core.k8s_info: + kubeconfig: "{{ kubeconfig_path }}" api_version: v1 kind: Secret - namespace: "{{ awx_namespace }}" name: "{{ awx_instance_name }}-admin-password" - register: awx_secret + namespace: "{{ awx_namespace }}" + register: awx_admin_secret - - name: Display AWX access information - debug: - msg: >- - AWX is deployed. Access it at the NodePort service (use 'kubectl get svc {{ awx_instance_name }}-service -n {{ awx_namespace }}' to find the port). - Default username: admin - Password: {{ awx_secret.resources[0].data.password | b64decode }} \ No newline at end of file + - name: Show AWX access information + ansible.builtin.debug: + msg: | + AWX успешно развёрнут! + Namespace: {{ awx_namespace }} + Instance name: {{ awx_instance_name }} + Service type: {{ awx_service_type }} + + Получите NodePort для доступа: + kubectl get svc {{ awx_instance_name }}-service -n {{ awx_namespace }} + + Логин: admin + Пароль: {{ awx_admin_secret.resources[0].data.password | b64decode }} + + Если используете Ingress — настройте его отдельно в spec AWX ресурса. \ No newline at end of file