Skip to content

Reproducible GitLab Runner ​

Creating GitLab runners on various executors using Ansible and Bash is fairly straightforward. The following Ansible playbook and startup script are a starting point for creating new GitLab runners with a single script.

ansible-play.yaml

yaml
---
- hosts: "{{ target }}"
  vars:
    gitlab_executor: "{{ executor }}"
    gitlab_tag_list: "{{ runner_tags }}"
    token: "TOKEN"
  vars_prompt:
    - name: user_email
      prompt: email
      private: false
    - name: user_password
      prompt: password (input hidden)
      private: true
  tasks:
    - name: Retrieve GitLab runner binary
      become: true
      ansible.builtin.get_url:
        url: https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
        dest: /usr/local/bin/gitlab-runner
        mode: 0777
    - name: Create GitLab runner user
      become: true
      ansible.builtin.user:
        name: gitlab-runner
        comment: "This GitLab Runner user was created automatically"
        shell: /bin/bash
    - name: Retrieve info for GitLab runner service file
      become: true
      ansible.builtin.stat:
        path: /etc/systemd/system/gitlab-runner.service
      register: gitlab_runner_service
    - name: Install GitLab runner
      become: true
      command: gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
      when: not gitlab_runner_service.stat.exists
    - name: Retrieve runner registration token
      shell: "bw get item {{ bw_registration_token_id }} --session {{ bw_session_token.stdout }} | jq .notes"
      register: gitlab_registration_token
    - name: Register GitLab runner
      become: true
      command: 'gitlab-runner register \
        --non-interactive \
        --url "https://gitlab.com/" \
        --registration-token "{{ gitlab_registration_token.stdout }}" \
        --executor "{{ gitlab_executor }}" \
        --description "Reproducible runner; uses executor: {{ gitlab_executor }}" \
        --maintenance-note "This runner was automatically created"
        --tag-list "{{ gitlab_tag_list }}" \
        --run-untagged="false" \
        --locked="false" \
        --access-level="not_protected"'
    - name: Finalize
      ansible.builtin.debug:
        msg: "GitLab runner was created. Go to the CI/CD runners to enable it."
---
- hosts: "{{ target }}"
  vars:
    gitlab_executor: "{{ executor }}"
    gitlab_tag_list: "{{ runner_tags }}"
    token: "TOKEN"
  vars_prompt:
    - name: user_email
      prompt: email
      private: false
    - name: user_password
      prompt: password (input hidden)
      private: true
  tasks:
    - name: Retrieve GitLab runner binary
      become: true
      ansible.builtin.get_url:
        url: https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
        dest: /usr/local/bin/gitlab-runner
        mode: 0777
    - name: Create GitLab runner user
      become: true
      ansible.builtin.user:
        name: gitlab-runner
        comment: "This GitLab Runner user was created automatically"
        shell: /bin/bash
    - name: Retrieve info for GitLab runner service file
      become: true
      ansible.builtin.stat:
        path: /etc/systemd/system/gitlab-runner.service
      register: gitlab_runner_service
    - name: Install GitLab runner
      become: true
      command: gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
      when: not gitlab_runner_service.stat.exists
    - name: Retrieve runner registration token
      shell: "bw get item {{ bw_registration_token_id }} --session {{ bw_session_token.stdout }} | jq .notes"
      register: gitlab_registration_token
    - name: Register GitLab runner
      become: true
      command: 'gitlab-runner register \
        --non-interactive \
        --url "https://gitlab.com/" \
        --registration-token "{{ gitlab_registration_token.stdout }}" \
        --executor "{{ gitlab_executor }}" \
        --description "Reproducible runner; uses executor: {{ gitlab_executor }}" \
        --maintenance-note "This runner was automatically created"
        --tag-list "{{ gitlab_tag_list }}" \
        --run-untagged="false" \
        --locked="false" \
        --access-level="not_protected"'
    - name: Finalize
      ansible.builtin.debug:
        msg: "GitLab runner was created. Go to the CI/CD runners to enable it."

start-script.sh

sh
#!/usr/bin/env bash
help () {
  echo "";
  echo "Usage: ./create --target <target> --executor <executor> --tags [tags]"
  echo "Options:"
  echo "  --target       Target to host GitLab runner as specified in the /etc/ansible/hosts file"
  echo "  --executor     Executor to use for the runner (shell/docker/kubernetes/custom)"
  echo "  --tags         (optional) Tags to add to the created runner"
  echo ""
  echo "Example:"
  echo "  ./create --target 'localhost' --tags 'arm64,staging' --executor 'shell'"
  echo ""
  echo "Additional Details:"
  echo "- For available executors visit https://docs.gitlab.com/runner/executors/"
}
valid_args=$(getopt -o t:e:g: --long target:,executor:,tags: -n "$0" -- "$@")
if [[ $? -ne 0 ]]; then
    help;
    exit 1;
fi
eval set -- "$valid_args"
target=
executor=
tags=''
color='\033[1;34m'
stop='\033[0m'
while true; do
  case "$1" in
    --target) target="$2"; shift 2 ;;
    --executor) executor="$2"; shift 2 ;;
    --tags) tags="$2"; shift 2 ;;
    -- ) shift; break ;;
    * ) break ;;
  esac
done
echo -e "$color"
echo "Issuing new GitLab runner on target: $target"
echo "  executor: $executor"
echo "  tags: $tags"
echo -e "$stop"
if [ -z $target ] || [ -z $executor ]; then
  echo "Some required options weren't provided"
  help;
  exit 1;
fi
ansible-playbook new-gitlab-runner.yml \
  --extra-vars "target=$target executor=$executor runner_tags=$tags" \
  --ask-become-pass
#!/usr/bin/env bash
help () {
  echo "";
  echo "Usage: ./create --target <target> --executor <executor> --tags [tags]"
  echo "Options:"
  echo "  --target       Target to host GitLab runner as specified in the /etc/ansible/hosts file"
  echo "  --executor     Executor to use for the runner (shell/docker/kubernetes/custom)"
  echo "  --tags         (optional) Tags to add to the created runner"
  echo ""
  echo "Example:"
  echo "  ./create --target 'localhost' --tags 'arm64,staging' --executor 'shell'"
  echo ""
  echo "Additional Details:"
  echo "- For available executors visit https://docs.gitlab.com/runner/executors/"
}
valid_args=$(getopt -o t:e:g: --long target:,executor:,tags: -n "$0" -- "$@")
if [[ $? -ne 0 ]]; then
    help;
    exit 1;
fi
eval set -- "$valid_args"
target=
executor=
tags=''
color='\033[1;34m'
stop='\033[0m'
while true; do
  case "$1" in
    --target) target="$2"; shift 2 ;;
    --executor) executor="$2"; shift 2 ;;
    --tags) tags="$2"; shift 2 ;;
    -- ) shift; break ;;
    * ) break ;;
  esac
done
echo -e "$color"
echo "Issuing new GitLab runner on target: $target"
echo "  executor: $executor"
echo "  tags: $tags"
echo -e "$stop"
if [ -z $target ] || [ -z $executor ]; then
  echo "Some required options weren't provided"
  help;
  exit 1;
fi
ansible-playbook new-gitlab-runner.yml \
  --extra-vars "target=$target executor=$executor runner_tags=$tags" \
  --ask-become-pass