From 367d30a30c50797c492599987ddfd408c18e89d0 Mon Sep 17 00:00:00 2001
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
Date: Tue, 15 Oct 2024 11:16:57 -0300
Subject: [PATCH] upstream CI: Simplify pipelines enviroment creation

Several optimizations have been done to the pipelines, to make them
closer to what can be reproduced, with the existing scripts, in a
development environment:

- Use start.sh and build.sh scripts to build and start containers
- Use variables to configure different stages instead of using separate
  files
- Use a commom 'prepare_environment' to create the environment for every
  pipeline
- Use a single file defining testing steps (run_tests.yml)
- Remove Centos 7 pipelines
- Reduce the number of pipelines in the test matrix due to the amount of
  time that tests were using
- Use Azure "loop" (each) to create test groups

The above changes make the pipelines easier to understand and modify.
---
 infra/azure/azure-pipelines.yml               |  32 +++--
 infra/azure/build-containers.yml              |  10 --
 infra/azure/nightly.yml                       | 119 +++++++-----------
 infra/azure/pr-pipeline.yml                   |  31 ++---
 infra/azure/templates/build_container.yml     |  11 +-
 infra/azure/templates/fast_tests.yml          |  31 -----
 .../azure/templates/galaxy_pytest_script.yml  |  65 ----------
 infra/azure/templates/galaxy_script.yml       |  86 -------------
 infra/azure/templates/galaxy_tests.yml        |  46 -------
 infra/azure/templates/group_tests.yml         |  52 +++-----
 infra/azure/templates/playbook_fast.yml       |  84 -------------
 infra/azure/templates/playbook_tests.yml      |  88 -------------
 .../azure/templates/prepare_environment.yaml  |  30 +++++
 infra/azure/templates/pytest_tests.yml        |  75 -----------
 infra/azure/templates/run_tests.yml           |  98 +++++++++++++++
 infra/image/build.sh                          |   3 +-
 16 files changed, 218 insertions(+), 643 deletions(-)
 delete mode 100644 infra/azure/templates/fast_tests.yml
 delete mode 100644 infra/azure/templates/galaxy_pytest_script.yml
 delete mode 100644 infra/azure/templates/galaxy_script.yml
 delete mode 100644 infra/azure/templates/galaxy_tests.yml
 delete mode 100644 infra/azure/templates/playbook_fast.yml
 delete mode 100644 infra/azure/templates/playbook_tests.yml
 create mode 100644 infra/azure/templates/prepare_environment.yaml
 delete mode 100644 infra/azure/templates/pytest_tests.yml
 create mode 100644 infra/azure/templates/run_tests.yml

diff --git a/infra/azure/azure-pipelines.yml b/infra/azure/azure-pipelines.yml
index ab28bb11..2043940a 100644
--- a/infra/azure/azure-pipelines.yml
+++ b/infra/azure/azure-pipelines.yml
@@ -15,8 +15,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core"
+      skip_git_test: true
 
 # Fedora
 
@@ -26,8 +27,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core <2.14"
+      skip_git_test: true
 
 # Fedora
 
@@ -37,19 +39,22 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core >=2.14,<2.15"
+      skip_git_test: true
 
 # Galaxy on Fedora
 
 - stage: Galaxy_Fedora_Latest
   dependsOn: []
   jobs:
-  - template: templates/galaxy_tests.yml
+  - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core >=2.14,<2.15"
+      skip_git_test: true
+      test_galaxy: true
 
 # CentOS 9 Stream
 
@@ -59,8 +64,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: c9s
+      distro: c9s
       ansible_version: "-core >=2.14,<2.15"
+      skip_git_test: true
 
 # CentOS 8 Stream
 
@@ -70,16 +76,6 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: c8s
-      ansible_version: "-core >=2.14,<2.15"
-
-# CentOS 7
-
-- stage: CentOS_7
-  dependsOn: []
-  jobs:
-  - template: templates/group_tests.yml
-    parameters:
-      build_number: $(Build.BuildNumber)
-      scenario: centos-7
+      distro: c8s
       ansible_version: "-core >=2.14,<2.15"
+      skip_git_test: true
diff --git a/infra/azure/build-containers.yml b/infra/azure/build-containers.yml
index 75c38539..d4b6b25a 100644
--- a/infra/azure/build-containers.yml
+++ b/infra/azure/build-containers.yml
@@ -15,16 +15,6 @@ pool:
 
 stages:
 
-# Currently, it's not possible to use CentOS container
-#
-# - stage: CentOS_7
-#   dependsOn: []
-#   jobs:
-#   - template: templates/build_container.yml
-#     parameters:
-#       job_name_suffix: Centos7
-#       distro: centos-7
-
 - stage: CentOS_8_Stream
   dependsOn: []
   jobs:
diff --git a/infra/azure/nightly.yml b/infra/azure/nightly.yml
index 89914f8e..cbbc9889 100644
--- a/infra/azure/nightly.yml
+++ b/infra/azure/nightly.yml
@@ -22,8 +22,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core >=2.13,<2.14"
+      skip_git_test: false
 
 - stage: FedoraLatest_Ansible_Core_2_14
   dependsOn: []
@@ -31,8 +32,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core >=2.14,<2.15"
+      skip_git_test: false
 
 - stage: FedoraLatest_Ansible_Core_2_15
   dependsOn: []
@@ -40,8 +42,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core >=2.15,<2.16"
+      skip_git_test: true
 
 - stage: FedoraLatest_Ansible_latest
   dependsOn: []
@@ -49,46 +52,44 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: ""
+      skip_git_test: true
 
 # Galaxy on Fedora
 
 - stage: Galaxy_FedoraLatest_Ansible_Core_2_13
   dependsOn: []
   jobs:
-  - template: templates/galaxy_tests.yml
+  - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core >=2.13,<2.14"
+      skip_git_test: false
+      test_galaxy: true
 
 - stage: Galaxy_FedoraLatest_Ansible_Core_2_14
   dependsOn: []
   jobs:
-  - template: templates/galaxy_tests.yml
+  - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core >=2.14,<2.15"
+      skip_git_test: false
+      test_galaxy: true
 
 - stage: Galaxy_FedoraLatest_Ansible_Core_2_15
   dependsOn: []
   jobs:
-  - template: templates/galaxy_tests.yml
+  - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
+      distro: fedora-latest
       ansible_version: "-core >=2.15,<2.16"
-
-- stage: Galaxy_FedoraLatest_Ansible_latest
-  dependsOn: []
-  jobs:
-  - template: templates/galaxy_tests.yml
-    parameters:
-      build_number: $(Build.BuildNumber)
-      scenario: fedora-latest
-      ansible_version: ""
+      skip_git_test: true
+      test_galaxy: true
 
 # Fedora Rawhide
 
@@ -98,8 +99,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-rawhide
+      distro: fedora-rawhide
       ansible_version: "-core >=2.13,<2.14"
+      skip_git_test: false
 
 - stage: FedoraRawhide_Ansible_Core_2_14
   dependsOn: []
@@ -107,8 +109,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-rawhide
+      distro: fedora-rawhide
       ansible_version: "-core >=2.14,<2.15"
+      skip_git_test: false
 
 - stage: FedoraRawhide_Ansible_Core_2_15
   dependsOn: []
@@ -116,8 +119,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-rawhide
+      distro: fedora-rawhide
       ansible_version: "-core >=2.15,<2.16"
+      skip_git_test: true
 
 - stage: FedoraRawhide_Ansible_latest
   dependsOn: []
@@ -125,8 +129,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: fedora-rawhide
+      distro: fedora-rawhide
       ansible_version: ""
+      skip_git_test: true
 
 # CentoOS 9 Stream
 
@@ -136,8 +141,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: c9s
+      distro: c9s
       ansible_version: "-core >=2.13,<2.14"
+      skip_git_test: false
 
 - stage: c9s_Ansible_Core_2_14
   dependsOn: []
@@ -145,8 +151,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: c9s
+      distro: c9s
       ansible_version: "-core >=2.14,<2.15"
+      skip_git_test: false
 
 - stage: c9s_Ansible_Core_2_15
   dependsOn: []
@@ -154,8 +161,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: c9s
+      distro: c9s
       ansible_version: "-core >=2.15,<2.16"
+      skip_git_test: true
 
 - stage: c9s_Ansible_latest
   dependsOn: []
@@ -163,8 +171,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: c9s
+      distro: c9s
       ansible_version: ""
+      skip_git_test: true
 
 # CentOS 8 Stream
 
@@ -174,8 +183,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: c8s
+      distro: c8s
       ansible_version: "-core >=2.13,<2.14"
+      skip_git_test: true
 
 - stage: c8s_Ansible_Core_2_14
   dependsOn: []
@@ -183,8 +193,9 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: c8s
+      distro: c8s
       ansible_version: "-core >=2.14,<2.15"
+      skip_git_test: false
 
 - stage: c8s_Ansible_Core_2_15
   dependsOn: []
@@ -192,52 +203,6 @@ stages:
   - template: templates/group_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
-      scenario: c8s
+      distro: c8s
       ansible_version: "-core >=2.15,<2.16"
-
-- stage: c8s_Ansible_latest
-  dependsOn: []
-  jobs:
-  - template: templates/group_tests.yml
-    parameters:
-      build_number: $(Build.BuildNumber)
-      scenario: c8s
-      ansible_version: ""
-
-# CentOS 7
-
-- stage: CentOS7_Ansible_Core_2_13
-  dependsOn: []
-  jobs:
-  - template: templates/group_tests.yml
-    parameters:
-      build_number: $(Build.BuildNumber)
-      scenario: centos-7
-      ansible_version: "-core >=2.13,<2.14"
-
-- stage: CentOS7_Ansible_Core_2_14
-  dependsOn: []
-  jobs:
-  - template: templates/group_tests.yml
-    parameters:
-      build_number: $(Build.BuildNumber)
-      scenario: centos-7
-      ansible_version: "-core >=2.14,<2.15"
-
-- stage: CentOS7_Ansible_Core_2_15
-  dependsOn: []
-  jobs:
-  - template: templates/group_tests.yml
-    parameters:
-      build_number: $(Build.BuildNumber)
-      scenario: centos-7
-      ansible_version: "-core >=2.15,<2.16"
-
-- stage: CentOS7_Ansible_latest
-  dependsOn: []
-  jobs:
-  - template: templates/group_tests.yml
-    parameters:
-      build_number: $(Build.BuildNumber)
-      scenario: centos-7
-      ansible_version: ""
+      skip_git_test: true
diff --git a/infra/azure/pr-pipeline.yml b/infra/azure/pr-pipeline.yml
index 40d78a9b..bc6e0830 100644
--- a/infra/azure/pr-pipeline.yml
+++ b/infra/azure/pr-pipeline.yml
@@ -12,67 +12,58 @@ stages:
 - stage: Fedora_Latest
   dependsOn: []
   jobs:
-  - template: templates/fast_tests.yml
+  - template: templates/run_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
       distro: fedora-latest
       ansible_version: "-core >=2.15,<2.16"
+      skip_git_test: false
 
 # Galaxy on Fedora
 
 - stage: Galaxy_Fedora_Latest
   dependsOn: []
   jobs:
-  - template: templates/fast_tests.yml
+  - template: templates/run_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
       distro: fedora-latest
       ansible_version: "-core >=2.15,<2.16"
+      skip_git_test: false
+      test_galaxy: true
 
 # CentOS 9 Stream
 
 - stage: CentOS_9_Stream
   dependsOn: []
   jobs:
-  - template: templates/fast_tests.yml
+  - template: templates/run_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
       distro: c9s
       ansible_version: "-core >=2.15,<2.16"
+      skip_git_test: false
 
 # CentOS 8 Stream
 
 - stage: CentOS_8_Stream
   dependsOn: []
   jobs:
-  - template: templates/fast_tests.yml
+  - template: templates/run_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
       distro: c8s
       ansible_version: "-core >=2.15,<2.16"
-      target_python: "/usr/libexec/platform-python"
-
-# CentOS 7 cannot be used with current systemd
-#
-# CentOS 7
-#
-# - stage: CentOS_7
-#   dependsOn: []
-#   jobs:
-#   - template: templates/fast_tests.yml
-#     parameters:
-#       build_number: $(Build.BuildNumber)
-#       distro: centos-7
-#       ansible_version: "-core >=2.15,<2.16"
-#       target_python: "/usr/bin/python2"
+      skip_git_test: false
 
 # Rawhide
 
 - stage: Fedora_Rawhide
   dependsOn: []
   jobs:
-  - template: templates/fast_tests.yml
+  - template: templates/run_tests.yml
     parameters:
       build_number: $(Build.BuildNumber)
       distro: fedora-rawhide
       ansible_version: "-core >=2.15,<2.16"
+      skip_git_test: false
diff --git a/infra/azure/templates/build_container.yml b/infra/azure/templates/build_container.yml
index f93881ce..49d2f731 100644
--- a/infra/azure/templates/build_container.yml
+++ b/infra/azure/templates/build_container.yml
@@ -22,18 +22,15 @@ jobs:
     retryCountOnTaskFailure: 5
     displayName: Install tools
 
-  - script: |
-      rm -rf ~/.ansible
-      mkdir -p ~/.ansible
-      ln -snf $(readlink -f roles) ~/.ansible/roles
-      ln -snf $(readlink -f plugins) ~/.ansible/plugins
-    displayName: Setup ansible-freeipa using Git repository
-
   - script: ansible-galaxy collection install containers.podman
     displayName: Install Ansible Galaxy collections
 
   - script: infra/image/build.sh -s ${{ parameters.distro }}
     displayName: Build ${{ parameters.distro }} base image
+    env:
+      ANSIBLE_ROLES_PATH: "${PWD}/roles"
+      ANSIBLE_LIBRARY: "${PWD}/plugins/modules"
+      ANSIBLE_MODULE_UTILS: "${PWD}/plugins/module_utils"
 
   - script: podman login -u="$QUAY_ROBOT_USERNAME" -p="$QUAY_ROBOT_TOKEN" quay.io
     displayName: Registry login
diff --git a/infra/azure/templates/fast_tests.yml b/infra/azure/templates/fast_tests.yml
deleted file mode 100644
index ac26ce8f..00000000
--- a/infra/azure/templates/fast_tests.yml
+++ /dev/null
@@ -1,31 +0,0 @@
----
-parameters:
-  - name: distro
-    type: string
-    default: fedora-latest
-  - name: build_number
-    type: string
-  - name: ansible_version
-    type: string
-    default: ""
-  - name: target_python
-    type: string
-    default: "/usr/bin/python3"
-
-jobs:
-- template: playbook_fast.yml
-  parameters:
-    group_number: 1
-    number_of_groups: 1
-    build_number: ${{ parameters.build_number }}
-    distro: ${{ parameters.distro }}
-    ansible_version: ${{ parameters.ansible_version }}
-    python_version: '< 3.12'
-    target_python: ${{ parameters.target_python }}
-
-# - template: pytest_tests.yml
-#   parameters:
-#     build_number: ${{ parameters.build_number }}
-#     distro: ${{ parameters.distro }}
-#     ansible_version: ${{ parameters.ansible_version }}
-#     python_version: '< 3.12'
diff --git a/infra/azure/templates/galaxy_pytest_script.yml b/infra/azure/templates/galaxy_pytest_script.yml
deleted file mode 100644
index 3b164169..00000000
--- a/infra/azure/templates/galaxy_pytest_script.yml
+++ /dev/null
@@ -1,65 +0,0 @@
----
-parameters:
-  - name: build_number
-    type: string
-  - name: scenario
-    type: string
-    default: fedora-latest
-  - name: ansible_version
-    type: string
-    default: ""
-  - name: python_version
-    type: string
-    default: 3.x
-
-jobs:
-- job: Test_PyTests
-  displayName: Run pytests on ${{ parameters.scenario }}
-  timeoutInMinutes: 240
-  steps:
-  - task: UsePythonVersion@0
-    inputs:
-      versionSpec: '${{ parameters.python_version }}'
-
-  - script: |
-      pip install \
-        "molecule-plugins[docker]" \
-        "requests<2.29" \
-        "ansible${{ parameters.ansible_version }}"
-    retryCountOnTaskFailure: 5
-    displayName: Install molecule and Ansible
-
-  - script: ansible-galaxy collection install community.docker ansible.posix
-    retryCountOnTaskFailure: 5
-    displayName: Install Ansible collections
-
-  - script: pip install -r requirements-tests.txt
-    retryCountOnTaskFailure: 5
-    displayName: Install dependencies
-
-  - script: |
-      utils/build-galaxy-release.sh -i
-      molecule create -s ${{ parameters.scenario }}
-    retryCountOnTaskFailure: 5
-    displayName: Setup test container
-    env:
-      ANSIBLE_LIBRARY: ./molecule
-
-  - script: |
-      cd ~/.ansible/collections/ansible_collections/freeipa/ansible_freeipa
-      pytest \
-        -m "not playbook" \
-        --verbose \
-        --color=yes \
-        --junit-xml=TEST-results-pytests.xml
-    displayName: Run tests
-    env:
-      IPA_SERVER_HOST: ${{ parameters.scenario }}
-      RUN_TESTS_IN_DOCKER: true
-      IPA_VERBOSITY: "-vvv"
-
-  - task: PublishTestResults@2
-    inputs:
-      mergeTestResults: true
-      testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
-    condition: succeededOrFailed()
diff --git a/infra/azure/templates/galaxy_script.yml b/infra/azure/templates/galaxy_script.yml
deleted file mode 100644
index a00dd0a5..00000000
--- a/infra/azure/templates/galaxy_script.yml
+++ /dev/null
@@ -1,86 +0,0 @@
----
-parameters:
-  - name: group_number
-    type: number
-    default: 1
-  - name: number_of_groups
-    type: number
-    default: 1
-  - name: scenario
-    type: string
-    default: fedora-latest
-  - name: ansible_version
-    type: string
-    default: ""
-  - name: python_version
-    type: string
-    default: 3.x
-  - name: build_number
-    type: string
-
-
-jobs:
-- job: Test_Group${{ parameters.group_number }}
-  displayName: Run playbook tests ${{ parameters.scenario }} (${{ parameters.group_number }}/${{ parameters.number_of_groups }})
-  timeoutInMinutes: 240
-  variables:
-  - template: variables.yaml
-  - template: variables_${{ parameters.scenario }}.yaml
-  steps:
-  - task: UsePythonVersion@0
-    inputs:
-      versionSpec: '${{ parameters.python_version }}'
-
-  - script: |
-      pip install \
-        "molecule-plugins[docker]" \
-        "requests<2.29" \
-        "ansible${{ parameters.ansible_version }}"
-    retryCountOnTaskFailure: 5
-    displayName: Install molecule and Ansible
-
-  - script: ansible-galaxy collection install community.docker ansible.posix
-    retryCountOnTaskFailure: 5
-    displayName: Install Ansible collections
-
-  - script: pip install -r requirements-tests.txt
-    retryCountOnTaskFailure: 5
-    displayName: Install dependencies
-
-  - script: |
-      utils/build-galaxy-release.sh -i
-      molecule create -s ${{ parameters.scenario }}
-    retryCountOnTaskFailure: 5
-    displayName: Setup test container
-    env:
-      ANSIBLE_LIBRARY: ./molecule
-
-  - script: |
-      python utils/check_test_configuration.py ${{ parameters.scenario }}
-    displayName: Check scenario test configuration
-
-  - script: |
-      cd ~/.ansible/collections/ansible_collections/freeipa/ansible_freeipa
-      pytest \
-        -m "playbook" \
-        --verbose \
-        --color=yes \
-        --splits=${{ parameters.number_of_groups }} \
-        --group=${{ parameters.group_number }} \
-        --randomly-seed=$(date "+%Y%m%d") \
-        --junit-xml=TEST-results-group-${{ parameters.group_number }}.xml
-    displayName: Run playbook tests
-    env:
-      IPA_SERVER_HOST: ${{ parameters.scenario }}
-      RUN_TESTS_IN_DOCKER: true
-      IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
-      IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
-      IPA_ENABLED_MODULES: ${{ variables.ipa_enabled_modules }}
-      IPA_ENABLED_TESTS: ${{ variables.ipa_enabled_tests }}
-      IPA_VERBOSITY: "-vvv"
-
-  - task: PublishTestResults@2
-    inputs:
-      mergeTestResults: true
-      testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
-    condition: succeededOrFailed()
diff --git a/infra/azure/templates/galaxy_tests.yml b/infra/azure/templates/galaxy_tests.yml
deleted file mode 100644
index 465097de..00000000
--- a/infra/azure/templates/galaxy_tests.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-parameters:
-  - name: scenario
-    type: string
-    default: fedora-latest
-  - name: build_number
-    type: string
-  - name: ansible_version
-    type: string
-    default: ""
-
-jobs:
-- template: galaxy_script.yml
-  parameters:
-    group_number: 1
-    number_of_groups: 3
-    build_number: ${{ parameters.build_number }}
-    scenario: ${{ parameters.scenario }}
-    ansible_version: ${{ parameters.ansible_version }}
-    python_version: '< 3.12'
-
-- template: galaxy_script.yml
-  parameters:
-    group_number: 2
-    number_of_groups: 3
-    build_number: ${{ parameters.build_number }}
-    scenario: ${{ parameters.scenario }}
-    ansible_version: ${{ parameters.ansible_version }}
-    python_version: '< 3.12'
-
-- template: galaxy_script.yml
-  parameters:
-    group_number: 3
-    number_of_groups: 3
-    build_number: ${{ parameters.build_number }}
-    scenario: ${{ parameters.scenario }}
-    ansible_version: ${{ parameters.ansible_version }}
-    python_version: '< 3.12'
-
-# Temporarily disable due to issues with ansible docker plugin.
-#- template: galaxy_pytest_script.yml
-#  parameters:
-#    build_number: ${{ parameters.build_number }}
-#    scenario: ${{ parameters.scenario }}
-#    ansible_version: ${{ parameters.ansible_version }}
-#    python_version: '< 3.12'
diff --git a/infra/azure/templates/group_tests.yml b/infra/azure/templates/group_tests.yml
index 38f183dd..da18c2e3 100644
--- a/infra/azure/templates/group_tests.yml
+++ b/infra/azure/templates/group_tests.yml
@@ -1,6 +1,6 @@
 ---
 parameters:
-  - name: scenario
+  - name: distro
     type: string
     default: fedora-latest
   - name: build_number
@@ -8,39 +8,23 @@ parameters:
   - name: ansible_version
     type: string
     default: ""
+  - name: skip_git_test
+    type: boolean
+    default: false
+  - name: test_galaxy
+    type: boolean
+    default: false
 
 jobs:
-- template: playbook_tests.yml
-  parameters:
-    group_number: 1
-    number_of_groups: 3
-    build_number: ${{ parameters.build_number }}
-    scenario: ${{ parameters.scenario }}
-    ansible_version: ${{ parameters.ansible_version }}
-    python_version: '< 3.12'
 
-- template: playbook_tests.yml
-  parameters:
-    group_number: 2
-    number_of_groups: 3
-    build_number: ${{ parameters.build_number }}
-    scenario: ${{ parameters.scenario }}
-    ansible_version: ${{ parameters.ansible_version }}
-    python_version: '< 3.12'
-
-- template: playbook_tests.yml
-  parameters:
-    group_number: 3
-    number_of_groups: 3
-    build_number: ${{ parameters.build_number }}
-    scenario: ${{ parameters.scenario }}
-    ansible_version: ${{ parameters.ansible_version }}
-    python_version: '< 3.12'
-
-# Temporarily disabled due to ansible docker plugin issue.
-#- template: pytest_tests.yml
-#  parameters:
-#    build_number: ${{ parameters.build_number }}
-#    scenario: ${{ parameters.scenario }}
-#    ansible_version: ${{ parameters.ansible_version }}
-#    python_version: '< 3.12'
+- ${{ each group in split('1,2,3', ',') }}:
+  - template: run_tests.yml
+    parameters:
+      group_number: ${{ group }}
+      number_of_groups: 3
+      build_number: ${{ parameters.build_number }}
+      distro: ${{ parameters.distro }}
+      ansible_version: ${{ parameters.ansible_version }}
+      python_version: '< 3.12'
+      skip_git_test: ${{ parameters.skip_git_test }}
+      test_galaxy: ${{ parameters.test_galaxy }}
diff --git a/infra/azure/templates/playbook_fast.yml b/infra/azure/templates/playbook_fast.yml
deleted file mode 100644
index a00a7875..00000000
--- a/infra/azure/templates/playbook_fast.yml
+++ /dev/null
@@ -1,84 +0,0 @@
----
-parameters:
-  - name: group_number
-    type: number
-    default: 1
-  - name: number_of_groups
-    type: number
-    default: 1
-  - name: distro
-    type: string
-    default: fedora-latest
-  - name: ansible_version
-    type: string
-    default: ""
-  - name: python_version
-    type: string
-    default: 3.x
-  - name: build_number
-    type: string
-  - name: target_python
-    type: string
-    default: "/usr/bin/python3"
-
-jobs:
-- job: Test_Group${{ parameters.group_number }}
-  displayName: Run playbook tests ${{ parameters.distro }} (${{ parameters.group_number }}/${{ parameters.number_of_groups }})
-  timeoutInMinutes: 360
-  variables:
-  - template: variables.yaml
-  - template: variables_${{ parameters.distro }}.yaml
-  steps:
-  - task: UsePythonVersion@0
-    inputs:
-      versionSpec: '${{ parameters.python_version }}'
-
-  - script: |
-      pip install "ansible${{ parameters.ansible_version }}"
-    retryCountOnTaskFailure: 5
-    displayName: Install Ansible
-
-  - script: ansible-galaxy collection install containers.podman
-    retryCountOnTaskFailure: 5
-    displayName: Install Ansible collections
-
-  - script: pip install -r requirements-tests.txt
-    retryCountOnTaskFailure: 5
-    displayName: Install dependencies
-
-  - script: |
-      . utils/set_test_modules
-      python3 utils/check_test_configuration.py ${{ parameters.distro }}
-    displayName: Check test configuration
-
-  - script: |
-      utils/setup_test_container.sh \
-        -e podman \
-        -a \
-        -m 4 \
-        -n "ipaserver.test.local" \
-        -p ${{ parameters.target_python }} \
-        -i ${{ parameters.distro }}-server \
-        ${{ parameters.distro }}-test
-    displayName: Setup target container
-
-  - script: |
-      . utils/set_test_modules
-      pytest -m "playbook" --verbose --color=yes --suppress-no-test-exit-code --junit-xml=TEST-results-pr-check.xml
-    displayName: Run playbook tests
-    env:
-      ANSIBLE_ROLES_PATH: "${PWD}/roles"
-      ANSIBLE_LIBRARY: "${PWD}/plugins"
-      ANSIBLE_MODULE_UTILS: "${PWD}/plugins/module_utils"
-      IPA_SERVER_HOST: ${{ parameters.distro }}-test
-      RUN_TESTS_IN_DOCKER: podman
-      IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
-      IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
-      IPA_VERBOSITY: "-vvv"
-      IPA_PYTHON_PATH: ${{ parameters.target_python }}
-
-  - task: PublishTestResults@2
-    inputs:
-      mergeTestResults: true
-      testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
-    condition: succeededOrFailed()
diff --git a/infra/azure/templates/playbook_tests.yml b/infra/azure/templates/playbook_tests.yml
deleted file mode 100644
index c65c955f..00000000
--- a/infra/azure/templates/playbook_tests.yml
+++ /dev/null
@@ -1,88 +0,0 @@
----
-parameters:
-  - name: group_number
-    type: number
-    default: 1
-  - name: number_of_groups
-    type: number
-    default: 1
-  - name: scenario
-    type: string
-    default: fedora-latest
-  - name: ansible_version
-    type: string
-    default: ""
-  - name: python_version
-    type: string
-    default: 3.x
-  - name: build_number
-    type: string
-
-jobs:
-- job: Test_Group${{ parameters.group_number }}
-  displayName: Run playbook tests ${{ parameters.scenario }} (${{ parameters.group_number }}/${{ parameters.number_of_groups }})
-  timeoutInMinutes: 240
-  variables:
-  - template: variables.yaml
-  - template: variables_${{ parameters.scenario }}.yaml
-  steps:
-  - task: UsePythonVersion@0
-    inputs:
-      versionSpec: '${{ parameters.python_version }}'
-
-  - script: |
-      pip install \
-        "molecule-plugins[docker]" \
-        "requests<2.29" \
-        "ansible${{ parameters.ansible_version }}"
-    retryCountOnTaskFailure: 5
-    displayName: Install molecule and Ansible
-
-  - script: ansible-galaxy collection install community.docker ansible.posix
-    retryCountOnTaskFailure: 5
-    displayName: Install Ansible collections
-
-  - script: pip install -r requirements-tests.txt
-    retryCountOnTaskFailure: 5
-    displayName: Install dependencies
-
-  - script: |
-      rm -rf ~/ansible
-      mkdir -p ~/.ansible/roles ~/.ansible/library ~/.ansible/module_utils
-      cp -a roles/* ~/.ansible/roles
-      cp -a plugins/modules/* ~/.ansible/library
-      cp -a plugins/module_utils/* ~/.ansible/module_utils
-      molecule create -s ${{ parameters.scenario }}
-    retryCountOnTaskFailure: 5
-    displayName: Setup test container
-    env:
-      ANSIBLE_LIBRARY: ./molecule
-
-  - script: |
-      python utils/check_test_configuration.py ${{ parameters.scenario }}
-    displayName: Check scenario test configuration
-
-  - script: |
-      pytest \
-        -m "playbook" \
-        --verbose \
-        --color=yes \
-        --splits=${{ parameters.number_of_groups }} \
-        --group=${{ parameters.group_number }} \
-        --randomly-seed=$(date "+%Y%m%d") \
-        --junit-xml=TEST-results-group-${{ parameters.group_number }}.xml
-    displayName: Run playbook tests
-    env:
-      IPA_SERVER_HOST: ${{ parameters.scenario }}
-      RUN_TESTS_IN_DOCKER: true
-      IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
-      IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
-      IPA_ENABLED_MODULES: ${{ variables.ipa_enabled_modules }}
-      IPA_ENABLED_TESTS: ${{ variables.ipa_enabled_tests }}
-      IPA_VERBOSITY: "-vvv"
-
-  - task: PublishTestResults@2
-    inputs:
-      mergeTestResults: true
-      testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
-    condition: succeededOrFailed()
diff --git a/infra/azure/templates/prepare_environment.yaml b/infra/azure/templates/prepare_environment.yaml
new file mode 100644
index 00000000..077d4052
--- /dev/null
+++ b/infra/azure/templates/prepare_environment.yaml
@@ -0,0 +1,30 @@
+---
+parameters:
+  - name: distro
+    type: string
+    default: fedora-latest
+  - name: ansible_version
+    type: string
+    default: ""
+  - name: python_version
+    type: string
+    default: 3.x
+  - name: build_number
+    type: string
+
+steps:
+  - task: UsePythonVersion@0
+    inputs:
+      versionSpec: '${{ parameters.python_version }}'
+
+  - script: |
+      pip install "ansible${{ parameters.ansible_version }}" -r requirements-tests.txt
+    retryCountOnTaskFailure: 5
+    displayName: Install test dependencies
+
+  - script: ansible-galaxy collection install -r requirements-podman.yml
+    retryCountOnTaskFailure: 5
+    displayName: Install Ansible collections
+
+  - script: infra/image/start.sh ${{ parameters.distro }}-server
+    displayName: Setup target container for ${{ parameters.distro }}
diff --git a/infra/azure/templates/pytest_tests.yml b/infra/azure/templates/pytest_tests.yml
deleted file mode 100644
index a7b12110..00000000
--- a/infra/azure/templates/pytest_tests.yml
+++ /dev/null
@@ -1,75 +0,0 @@
----
-parameters:
-  - name: build_number
-    type: string
-  - name: scenario
-    type: string
-    default: fedora-latest
-  - name: ansible_version
-    type: string
-    default: ""
-  - name: python_version
-    type: string
-    default: 3.x
-
-jobs:
-- job: Test_PyTests
-  displayName: Run pytests on ${{ parameters.scenario }}
-  timeoutInMinutes: 240
-  variables:
-  - template: variables.yaml
-  - template: variables_${{ parameters.scenario }}.yaml
-  steps:
-  - task: UsePythonVersion@0
-    inputs:
-      versionSpec: '${{ parameters.python_version }}'
-
-  - script: |
-      pip install \
-        "molecule-plugins[docker]" \
-        "requests<2.29" \
-        "ansible${{ parameters.ansible_version }}"
-    retryCountOnTaskFailure: 5
-    displayName: Install molecule and Ansible
-
-  - script: ansible-galaxy collection install community.docker ansible.posix
-    retryCountOnTaskFailure: 5
-    displayName: Install Ansible collections
-
-  - script: pip install -r requirements-tests.txt
-    retryCountOnTaskFailure: 5
-    displayName: Install dependencies
-
-  - script: |
-      rm -rf ~/.ansible
-      mkdir -p ~/.ansible/roles ~/.ansible/library ~/.ansible/module_utils
-      cp -a roles/* ~/.ansible/roles
-      cp -a plugins/modules/* ~/.ansible/library
-      cp -a plugins/module_utils/* ~/.ansible/module_utils
-      molecule create -s ${{ parameters.scenario }}
-    retryCountOnTaskFailure: 5
-    displayName: Setup test container
-    env:
-      ANSIBLE_LIBRARY: ./molecule
-
-  - script: |
-      pytest \
-        -m "not playbook" \
-        --verbose \
-        --color=yes \
-        --junit-xml=TEST-results-pytests.xml
-    displayName: Run tests
-    env:
-      IPA_SERVER_HOST: ${{ parameters.scenario }}
-      RUN_TESTS_IN_DOCKER: true
-      IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
-      IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
-      IPA_ENABLED_MODULES: ${{ variables.ipa_enabled_modules }}
-      IPA_ENABLED_TESTS: ${{ variables.ipa_enabled_tests }}
-      IPA_VERBOSITY: "-vvv"
-
-  - task: PublishTestResults@2
-    inputs:
-      mergeTestResults: true
-      testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
-    condition: succeededOrFailed()
diff --git a/infra/azure/templates/run_tests.yml b/infra/azure/templates/run_tests.yml
new file mode 100644
index 00000000..1cc00030
--- /dev/null
+++ b/infra/azure/templates/run_tests.yml
@@ -0,0 +1,98 @@
+---
+parameters:
+  - name: group_number
+    type: number
+    default: 1
+  - name: number_of_groups
+    type: number
+    default: 1
+  - name: distro
+    type: string
+    default: fedora-latest
+  - name: ansible_version
+    type: string
+    default: ""
+  - name: python_version
+    type: string
+    default: 3.x
+  - name: build_number
+    type: string
+  - name: skip_git_test
+    type: boolean
+    default: true
+  - name: test_type
+    type: string
+    default: "playbook"
+  - name: test_galaxy
+    type: boolean
+    default: false
+
+jobs:
+- job: Test_Group${{ parameters.group_number }}
+  displayName: Run playbook tests ${{ parameters.distro }} (${{ parameters.group_number }}/${{ parameters.number_of_groups }})
+  timeoutInMinutes: 360
+  variables:
+  - template: variables.yaml
+  - template: variables_${{ parameters.distro }}.yaml
+  steps:
+  - template: prepare_environment.yaml
+    parameters:
+      build_number: ${{ parameters.build_number }}
+      distro: ${{ parameters.distro }}
+      ansible_version: ${{ parameters.ansible_version }}
+      python_version: ${{ parameters.python_version }}
+
+  - bash: echo "##vso[task.setvariable variable=TOPDIR]${PWD}"
+    displayName: Set repo rootdir
+
+  - script: |
+      . "${TOPDIR}/utils/set_test_modules"
+      python3 utils/check_test_configuration.py ${{ parameters.distro }}
+    displayName: Check test configuration
+    env:
+       SKIP_GIT_TEST: ${{ parameters.skip_git_test }}
+
+  - script: |
+      git fetch --unshallow
+      utils/build-galaxy-release.sh -i
+    retryCountOnTaskFailure: 5
+    displayName: Build Galaxy release
+    condition: ${{ parameters.test_galaxy }}
+
+  - script: |
+      echo "PWD: ${PWD}"
+      echo "TOPDIR: ${TOPDIR}"
+      echo "ROLES: ${ANSIBLE_ROLES_PATH}"
+      echo "LIBRARY: ${ANSIBLE_LIBRARY}"
+      echo "MODULE_UTILS: ${ANSIBLE_MODULE_UTILS}"
+      . "${TOPDIR}/utils/set_test_modules"
+      [ "${{ parameters.test_galaxy }}" == "True"  ] && cd ~/.ansible/collections/ansible_collections/freeipa/ansible_freeipa
+      pytest \
+          -m "${{ parameters.test_type }}" \
+          --verbose \
+          --color=yes \
+          --splits=${{ parameters.number_of_groups }} \
+          --group=${{ parameters.group_number }} \
+          --randomly-seed=$(date "+%Y%m%d") \
+          --suppress-no-test-exit-code \
+          --junit-xml=TEST-results-pr-check.xml
+    displayName: Run playbook tests
+    env:
+      SKIP_GIT_TEST: ${{ parameters.skip_git_test }}
+      ${{ if not(parameters.test_galaxy)  }}:
+        ANSIBLE_ROLES_PATH: "${PWD}/roles"
+        ANSIBLE_LIBRARY: "${PWD}/plugins"
+        ANSIBLE_MODULE_UTILS: "${PWD}/plugins/module_utils"
+      IPA_SERVER_HOST: ansible-freeipa-tests
+      RUN_TESTS_IN_DOCKER: podman
+      IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
+      IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
+      IPA_ENABLED_MODULES: ${{ variables.ipa_enabled_modules }}
+      IPA_ENABLED_TESTS: ${{ variables.ipa_enabled_tests }}
+      IPA_VERBOSITY: "-vvv"
+
+  - task: PublishTestResults@2
+    inputs:
+      mergeTestResults: true
+      testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
+    condition: succeededOrFailed()
diff --git a/infra/image/build.sh b/infra/image/build.sh
index 3220ecce..8a2491c8 100755
--- a/infra/image/build.sh
+++ b/infra/image/build.sh
@@ -37,8 +37,7 @@ EOF
 
 name="ansible-freeipa-image-builder"
 hostname="ipaserver.test.local"
-# Number of cpus is not available in usptream CI (Ubuntu 22.04).
-# cpus="2"
+cpus="2"
 memory="3g"
 quayname="quay.io/ansible-freeipa/upstream-tests"
 deploy_server="N"
-- 
GitLab