Build on a runner but publish on an other?

Hi,

you can use runner tags to assign specific CI/CD jobs to tags. Runners registered and configured with these tags will be able to pick up the jobs, ensuring that scenarios with different networks and DMZs work using GitLab. I don’t think you missed something obvious, this is an advanced topic and needs some explanation and examples.

Let’s try to model the rpm build and upload pipeline

There will be 2 jobs, build and upload, assigned to different stages, and using different runner tags.

For debugging purposes, I have added the echo statements that will print the runner ID and its configured tags from predefined CI/CD variables. Will make it easier to verify that the runners are configured properly i.e. when they do not pick up the job.

The build job needs to generate a dummy artifact (using Linux dd command to generate 1MB file chunk here) which is inherited using !reference (extends would override the script section). Both jobs need to know where the artifacts are stored and consumed from - to avoid duplication, the job template .rpm-tmpl provides the artifact attributes. This also answers your question in

what to put in the .gitlab-ci.yml file to make the 2nd runner download the artifacts produced by the 1st

but also needs the runner tags to avoid both runners picking up the jobs at random, resulting in weird behavior.

Last but not least, the ls command lists the rpm files in the directory to verify that the artifacts have been exchanged - and can be processed properly.

stages:
  - build
  - upload 

variables:
  MB_COUNT: 1 

.gen-tmpl:
  script:
    - dd if=/dev/urandom of=$MB_COUNT.rpm bs=1048576 count=$MB_COUNT

.rpm-tmpl:
  artifacts:
    paths: 
      - '*.rpm'

build-rpm:
  extends: .rpm-tmpl
  stage: build
  tags: 
    - build-rpm 
  script:
    - !reference [.gen-tmpl,script]
    - echo "Build rpm job executed on runner ID $CI_RUNNER_ID with tags $CI_RUNNER_TAGS"
    - ls -la *.rpm 

upload-rpm:
  extends: .rpm-tmpl
  stage: upload 
  tags:
    - upload-rpm
  script:
    - echo "Upload rpm job executed on runner ID $CI_RUNNER_ID with tags $CI_RUNNER_TAGS"
    - ls -la *.rpm 

Tip: The Pipeline Editor in the CI/CD menu helps with live linting.

Does it work?

To test my theory, I’ve spun up 2 VMs in Hetzner Cloud (no ads, I just love the fast VM spin-up), installed GitLab runner, and registered them into my GitLab.com SaaS project (did that on the CLI manually, for larger setups I’d recommend Terraform).

Build-rpm runner 1

hcloud server create --image ubuntu-22.04 --type cx11 --name gl-u22-runner-1

ssh -4 root@... 

curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash 
sudo apt-get install gitlab-runner

sudo gitlab-runner register --url https://gitlab.com/ --registration-token XXX --tag-list build-rpm --executor shell --non-interactive

systemctl restart gitlab-runner

upload-rpm runner 2

hcloud server create --image ubuntu-22.04 --type cx11 --name gl-u22-runner-2

ssh -4 root@... 

curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash 
sudo apt-get install gitlab-runner

sudo gitlab-runner register --url https://gitlab.com/ --registration-token XXX --tag-list upload-rpm --executor shell --non-interactive

systemctl restart gitlab-runner

Verify them in the CI/CD Runner settings.

image

That also shows the assigned runner tags.

Trigger a CI/CD pipeline

build-rpm - build-rpm (#3544242121) · Jobs · Michael Friedrich / ci-cd-playground · GitLab

upload-rpm - upload-rpm (#3544242122) · Jobs · Michael Friedrich / ci-cd-playground · GitLab

Cleanup

hcloud server delete gl-u22-runner-1

hcloud server delete gl-u22-runner-2

GitLab Project Settings > CI/CD > Runners - remove the registered runners.

Conclusion

:white_check_mark: Verifies my theory and shows that both runners exchange artifacts, while the jobs are only picked up by assigned runner tags. You should be able to clone/copy the basic structure from my comment. I’ve never done this specific use case before, learned something new myself. :slight_smile:

Pipeline and MR are in Create runner tag pipeline (!21) · Merge requests · Michael Friedrich / ci-cd-playground · GitLab (that’s my playground project for wider community questions). Please share whether this example worked for you, and maybe write a blog post too :slight_smile:

Cheers,
Michael

3 Likes