Skip to main content

On This Page

Implementing the Relay Race Pattern: Syncing Gradle and Ansible in Tekton Pipelines

3 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

The “Relay Race” Pattern: Syncing Gradle Builds with Ansible in Tekton

The Relay Race pattern provides a structured hand-off for dynamic version strings between ephemeral build and deployment containers in Tekton. If the version string baton is dropped between Gradle and Ansible, the entire CI/CD pipeline stops.

Why This Matters

In a modern CI/CD pipeline, technical reality often involves ephemeral containers where data vanishes post-execution. While ideal models suggest seamless integration, the lack of a structured hand-off leads to Ansible playbooks ‘guessing’ filenames or failing to find artifacts. Utilizing Tekton Results ensures a single source of truth and loose coupling, preventing the high cost of manual versioning errors and broken deployment audits.

Key Insights

  • Gradle metadata export: Implementing an ‘exportBuildMetadata’ task writes version strings to a workspace file to preserve build identity.
  • Tekton Results persistence: Mapping build metadata to $(results.rpm-version.path) allows ephemeral containers to store data for subsequent tasks.
  • Loose Coupling: Ansible playbooks use the ‘rpm_prefix’ and ‘build_number’ variables to construct paths, removing dependency on Gradle’s internal logic.
  • Audit Trail: Using Tekton Results allows operators to view exactly which version was passed between tasks via the Tekton Dashboard without parsing logs.

Working Examples

Gradle task to export build version to a file.

task exportBuildMetadata {
  doLast {
    def versionFile = new File(projectDir, "build_metadata.txt")
    versionFile.text = project.version.toString()
    println ">>> Exported Version: ${project.version}"
  }
}
buildRpm.finalizedBy exportBuildMetadata

Tekton Task definition utilizing results to store the version string.

spec:
  results:
    - name: rpm-version
      description: "The dynamic build number generated by Gradle"
  steps:
    - name: run-gradle-build
      image: gradle:jdk17
      script: |
        gradle buildRpm exportBuildMetadata
        cat build_metadata.txt > $(results.rpm-version.path)

Ansible Playbook consuming the dynamic version variable from Tekton.

- name: Deploy the COMET RPM
  hosts: target_servers
  vars:
    rpm_filename: "{{ rpm_prefix }}-{{ build_number }}.rpm"
    rpm_source_path: "/workspace/source/build/distributions/{{ rpm_filename }}"
  tasks:
    - name: Ensure RPM is present on the target
      ansible.builtin.copy:
        src: "{{ rpm_source_path }}"
        dest: "/tmp/{{ rpm_filename }}"
    - name: Install the specific build
      ansible.builtin.yum:
        name: "/tmp/{{ rpm_filename }}"
        state: present

Practical Applications

  • Use Case: Deploying COMET RPM packages where the version is dynamically generated during the build phase. Pitfall: Manually hardcoding versions in Ansible leads to deployment failures when the build increments.
  • Use Case: Using the Ansible ‘find’ module as a safety net to locate the newest RPM based on modification time. Pitfall: Relying on filesystem modification times can be unreliable if multiple builds overlap or are cached.

References:

Continue reading

Next article

How Chat Apps Send Messages Instantly (WebSockets Breakdown)

Related Content