main.yml

This is the playbook that manages it all.

---
- name: Deploy AAP Instance Group
  hosts: all
  become: true
  gather_facts: false

  tasks:
    - name: Get secrets
      ansible.builtin.include_role:
        name: wf_linux.vault.read_secret
      vars:
        vault_url: "{{ vault_url }}"
        vault_token: "{{ vault_token }}"
        vault_toplevel_name: "{{ branch_name }}"
        vault_org_name: "{{ org_name }}"
        vault_secret_name: "rhaap_admin"
      no_log: true

    - name: Set rhaap facts
      ansible.builtin.set_fact:
        controller_hostname: "{{ vault_secret_data['hostname'] }}"
        controller_username: "{{ vault_secret_data['username'] }}"
        controller_password: "{{ vault_secret_data['password'] }}"
        controller_validate_certs: "{{ vault_secret_data['validate_certs'] }}"

    - name: Set some facts
      ansible.builtin.set_fact:
        controller_api: "{{ controller_hostname }}/api/controller/v2"
        bundle_dir: "/tmp/{{ inventory_hostname }}_bundle"

    - name: Set second facts
      ansible.builtin.set_fact:
        bundle_tar: "{{ bundle_dir }}.tar.gz"

    - name: Check if the machine is present
      block:
        - name: Try to conect
          ansible.builtin.wait_for_connection:
            sleep: 1
            timeout: 5
      rescue:
        - name: Deploy machine
          ansible.controller.job_launch:
            controller_host: "{{ controller_hostname }}"
            controller_username: "{{ controller_username }}"
            controller_password: "{{ controller_password }}"
            validate_certs: "{{ controller_validate_certs }}"
            job_template: "{{ deploy_workflow }}"
            organization: "{{ deploy_organization }}"
            extra_vars:
              instances: "{{ inventory_hostname }}"
              infrastructure_proxmox_action: create
            wait: true
          register: job_status

        - name: Wait for job to finish
          ansible.controller.job_wait:
            job_id: "{{ job_status }}"
            timeout: 600

    - name: Get defined instance groups
      ansible.builtin.uri:
        url: "{{ controller_hostname }}/api/controller/v2/instance_groups"
        user: "{{ controller_username }}"
        password: "{{ controller_password }}"
        method: GET
        body_format: json
        force_basic_auth: true
        validate_certs: false
      register: _controller_instance_groups

    - name: Get the instance_groups list of dicts
      ansible.builtin.set_fact:
        _instance_groups: "{{ _controller_instance_groups.json.results }}"

    - name: Create Instance Group
      ansible.controller.instance_group:
        controller_host: "{{ controller_hostname }}"
        controller_username: "{{ controller_username }}"
        controller_password: "{{ controller_password }}"
        validate_certs: "{{ controller_validate_certs }}"
        name: "{{ instance_group_name }}"
        state: present
        max_concurrent_jobs: "{{ concurrent_jobs }}"
        max_forks: "{{ forks }}"
        policy_instance_percentage: "{{ policy_instance_percentage }}"
        policy_instance_minimum: "{{ policy_instance_minimum }}"
      delegate_to: localhost
      become: false
      register: ig_result
      when: instance_group_name not in _instance_groups

    - name: Show result of Instance Group creation
      ansible.builtin.debug:
        var: ig_result
      when: instance_group_name not in _instance_groups

    - name: check if the instance is defined and its status
      ansible.builtin.uri:
        url: "{{ controller_hostname }}/api/controller/v2/instances/?search={{ inventory_hostname }}"
        user: "{{ controller_username }}"
        password: "{{ controller_password }}"
        method: GET
        body_format: json
        force_basic_auth: true
        validate_certs: false
      register: _controller_instance

    - name: Get the instance list of dicts
      ansible.builtin.set_fact:
        _instance: "{{ _controller_instance.json.results }}"

    - name: Create Instance
      block:
        - name: Create instance on Openshift or Kubernetis
          ansible.controller.instance:
            controller_host: "{{ controller_hostname }}"
            controller_username: "{{ controller_username }}"
            controller_password: "{{ controller_password }}"
            validate_certs: "{{ controller_validate_certs }}"
            hostname: "{{ inventory_hostname }}"
            node_type: "execution"
            listener_port: 27199
            peers_from_control_nodes: true
            node_state: "installed"
            enabled: true
          delegate_to: localhost
          become: false
          register: instance_result
          when: _instance | length < 1

      rescue:
        - name: Create instance on containerized install (homelab)
          become_user: escape_admin
          become: true
          ansible.builtin.command:
            cmd: "podman exec automation-controller-task /usr/bin/awx-manage provision_instance --hostname {{ inventory_hostname|quote }} --node_type 'execution'"
          delegate_to: "{{ vault_secret_data['fqdn'] }}"
          register: instance_result

    - name: Show result of Instance creation
      ansible.builtin.debug:
        var: instance_result

    - name: Add Instance to Instance Group
      ansible.controller.instance_group:
        controller_host: "{{ controller_hostname }}"
        controller_username: "{{ controller_username }}"
        controller_password: "{{ controller_password }}"
        validate_certs: "{{ controller_validate_certs }}"
        name: "{{ instance_group_name }}"
        instances:
          - "{{ inventory_hostname }}"
        state: present
      become: false
      delegate_to: localhost
      when: _instance | length < 1

    - name: Show result of Instance addition to Instance Group
      ansible.builtin.debug:
        msg: "Instance {{ inventory_hostname }} created in {{ instance_group_name }}"
      when: _instance | length < 1

    - name: Ensure subscription and repo are active
      community.general.rhsm_repository:
        name: ansible-automation-platform-2.6-for-rhel-9-x86_64-rpms
        state: enabled

    - name: Upgrade all packages to the latest version
      ansible.builtin.dnf:
        name: "*"
        state: latest
        update_cache: yes

    - name: Install ansible-core
      ansible.builtin.dnf:
        name: ansible-core
        state: present

    - name: Ensure the Python firewalld library is present
      ansible.builtin.dnf:
        name: python3-firewall
        state: present

    - name: Get Instance ID using lookup
      set_fact:
        instance_id: "{{ lookup('ansible.controller.controller_api', 'instances', host=controller_hostname , username=controller_username, password=controller_password, verify_ssl=false, query_params={'hostname': inventory_hostname})['id'] }}"

    - name: Cleanup block
      when: >
        _instance.status is not defined or
        ( _instance | length > 0 ) and ( _instance.status != 'ready' )
      block:
        - name: Cleanup sensitive bundle files
          ansible.builtin.file:
            path: "{{ item }}"
            state: absent
          loop:
            - "{{ bundle_tar }}"
            - "{{ bundle_dir }}"

    - name: Install block
      when: >
        _instance.status is not defined or
        ( _instance | length > 0 ) and ( _instance.status != 'ready' )
      block:
        - name: Download Instance Install Bundle
          ansible.builtin.uri:
            url: "{{ controller_api }}/instances/{{ instance_id }}/install_bundle/"
            url_username: "{{ controller_username }}"
            url_password: "{{ controller_password }}"
            validate_certs: "{{ controller_validate_certs }}"
            method: GET
            force_basic_auth: yes
            dest: "{{ bundle_tar }}"
            status_code: 200
          register: bundle_download

        - name: Open Receptor port in firewalld
          ansible.posix.firewalld:
            port: 27199/tcp
            permanent: yes
            state: enabled
            immediate: yes

    - name: Install the mesh using the bundle      
      when:
        - _instance.status is not defined or
        - ( _instance | length > 0 ) and ( _instance.status != 'ready' )
      block:
        - name: Create extraction directory
          ansible.builtin.file:
            path: "{{ bundle_dir }}"
            state: directory
            mode: '0700'

        - name: Unarchive the bundle
          ansible.builtin.unarchive:
            src: "{{ bundle_tar }}"
            dest: "{{ bundle_dir }}"
            remote_src: yes
            extra_opts: ['--strip-components=1']

        - name: Install Ansible requirements from the bundle
          ansible.builtin.command:
            cmd: "ansible-galaxy install -r requirements.yml"
            chdir: "{{ bundle_dir }}"
          register: install_result

        - name: Show result of creation
          ansible.builtin.debug:
            var: install_result

        - name: Install the Mesh Node using the bundle playbook
          ansible.builtin.command:
            cmd: >
              ansible-playbook -i localhost, install_receptor.yml -c local 
              -e "ansible_python_interpreter=/usr/bin/python3"
              -e "ansible_host={{ inventory_hostname }}"
              -e "receptor_host_identifier={{ inventory_hostname }}"
              -e "routable_hostname={{ inventory_hostname }}"
            chdir: "{{ bundle_dir }}"
            # if this file already exists, this task will not be run
            creates: /etc/receptor/receptor.conf
          register: install_result

        - name: Show result of creation
          ansible.builtin.debug:
            var: install_result

      always:
        - name: Cleanup sensitive bundle files
          ansible.builtin.file:
            path: "{{ item }}"
            state: absent
          loop:
            - "{{ bundle_tar }}"
            - "{{ bundle_dir }}"

    - name: Verify Receptor Service is running
      ansible.builtin.systemd:
        name: receptor
        state: started
        enabled: yes