How to get Gitlab runner registration token from command line?

Viewed 5711

I'm trying to deploy a Gitlab instance and runners ready with Terraform. The script creates both Gitlab and runners without any problem, but I don't know how to register the runners automatically after the creation.

Is there any way to get the registration token from command line? If it's possible I can register just calling external data source using Terraform.

4 Answers

The projects API endpoint response contains the runners_token key. You can use this to automatically fetch the runner tokens for any project.

You can then use that in a few ways. One way would be to have your runner registration script fetch the runner token itself such as with this example:

curl --fail --silent --header "Private-Token: ${GITLAB_API_TOKEN}" "https://$GITLAB_URL/api/v4/projects/${PROJECT}"

Or you could use the Gitlab Terraform provider's gitlab_project data source to fetch this from whatever is running Terraform and then inject it into the thing that runs the registration script such as a templated file:

data "gitlab_project" "example" {
  id = 30
}

locals {
  runner_config = {
    runner_token = data.gitlab_project.example.runners_token
  }
}

output "example" {
  value = templatefile("${path.module}/register-runners.sh.tpl", local.runner_config)
}

Yes, you can.

The command has to be run on the server hosting your Gitlab instance. The line below will output the current shared runner token.

sudo gitlab-rails runner -e production "puts Gitlab::CurrentSettings.current_application_settings.runners_registration_token"

As others have mentioned, there is not API endpoint that currently allows this (there has been discussion over this for quite some time here. However, I find this solution satisfactory for my needs.

Credits for this answer go to MxNxPx. This script used to work (for me) two days ago:

GITUSER="root"
GITURL="http://127.0.0.1"
GITROOTPWD="mysupersecretgitlabrootuserpassword"

# 1. curl for the login page to get a session cookie and the sources with the auth tokens
body_header=$(curl -k -c gitlab-cookies.txt -i "${GITURL}/users/sign_in" -sS)

# grep the auth token for the user login for
#   not sure whether another token on the page will work, too - there are 3 of them
csrf_token=$(echo $body_header | perl -ne 'print "$1\n" if /new_user.*?authenticity_token"[[:blank:]]value="(.+?)"/' | sed -n 1p)

# 2. send login credentials with curl, using cookies and token from previous request
curl -sS -k -b gitlab-cookies.txt -c gitlab-cookies.txt "${GITURL}/users/sign_in" \
    --data "user[login]=${GITUSER}&user[password]=${GITROOTPWD}" \
    --data-urlencode "authenticity_token=${csrf_token}"  -o /dev/null

# 3. send curl GET request to gitlab runners page to get registration token
body_header=$(curl -sS -k -H 'user-agent: curl' -b gitlab-cookies.txt "${GITURL}/admin/runners" -o gitlab-header.txt)
reg_token=$(cat gitlab-header.txt | perl -ne 'print "$1\n" if /code id="registration_token">(.+?)</' | sed -n 1p)
echo $reg_token

However, as of today it stopped working. I noticed the second body_header variable is empty. Upon inspecting the gitlab-header.txt file, I noticed it contained:

You are being redirected.

Whereas I would expect it to be signed in at that point, with a gitlab-header.txt file that contains the respective runner registration token. I expect I am doing something wrong, however, perhaps there has been an update to the gitlab/gitlab-ce:latest package such that a change to the script is required.

Disclaimer, I am involved in creating that code Here is a horrible but working Python boiler plate code that gets the runner token and exports it to a parent repository: https://github.com/a-t-0/get-gitlab-runner-registration-token.

Independent usage

It requires a few manual steps to set up, and then gets the GitLab runner registration token automatically (from the CLI with:). It requires Conda and Python however, and downloads a browser controller. So it is most likely wiser to look a bit better into the curl commands instead.

Integrated in parent [bash] repository

First install the conda environment, then activate it. After that, you can execute the function below automatically from the CLI (if you put that function in a file at path parent_repo/src/get_gitlab_server_runner_token.sh, assuming you have the credentials etc as specified in the Readme), with:

cd parent_repo
source src/get_gitlab_server_runner_token.sh && get_registration_token_with_python

This bash function gets the token:

get_registration_token_with_python() {
    # delete the runner registration token file if it exist
    if [ -f "$RUNNER_REGISTRATION_TOKEN_FILEPATH" ] ; then
        rm "$RUNNER_REGISTRATION_TOKEN_FILEPATH"
    fi
    
    
    git clone https://github.com/a-t-0/get-gitlab-runner-registration-token.git &&
    set +e
    cd get-gitlab-runner-registration-token && python -m code.project1.src
    cd ..
}

And here is a BATS test that verifies the token is retrieved:

#!./test/libs/bats/bin/bats

load 'libs/bats-support/load'
load 'libs/bats-assert/load'
load 'libs/bats-file/load'

source src/get_gitlab_server_runner_token.sh
source src/hardcoded_variables.txt

@test "Checking if the gitlab runner registration token is obtained correctly." {
    
    get_registration_token_with_python
    actual_result=$(cat $RUNNER_REGISTRATION_TOKEN_FILEPATH)
    EXPECTED_OUTPUT="somecode"

    assert_file_exist $RUNNER_REGISTRATION_TOKEN_FILEPATH
    assert_equal ${#actual_result}   20
}
Related