Registering Gitlab Runners programmatically with an Authentication Token: A Tutorial
Up till now, GitLab offered the ability to register Runners with registration tokens. However, GitLab has recently deprecated this method in favor of authentication tokens. This shift aims to maintain ownership records for Runners, while also allowing authentication tokens to be reused, thanks to the addition of a unique system ID on the Runners. For more context, check the issue.
The documentation on registering Runners with authentication tokens primarily directs users to use the UI, which is a valid approach. However, relying solely on the UI may impose limitations, particularly concerning automation. Navigating this process programmatically may also not be immediately intuitive due to the need to look through a few different documentation pages. Hence, this article aims to fill the gap by offering a tutorial on programmatically registering Runners, providing users with a clear path to automate the process and thereby enhance safety, consistency, and efficiency in their workflows.
There are various types of Runners in GitLab, but to maintain simplicity in this tutorial, we’ll focus on shared Runners (a.k.a., Instance Runners in certain documentation pages). Shared Runners enable each Runner to execute CI/CD jobs across all groups and projects, streamlining the process for broader adoption.
Deploy Gitlab and a Runner
To register the Runners, it’s essential to have GitLab operational alongside at least one Runner. For guidance on setting up GitLab and a Runner locally, you can refer to the provided docker-compose.yml as reference.
version: '3'
services:
gitlab:
image: gitlab/gitlab-ce:latest
container_name: gitlab
restart: always
ports:
- "10001:10001" # HTTP
- "10002:443" # HTTPS
- "10003:22" # SSH
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://localhost:10001' # Change this to your GitLab's URL
gitlab_rails['initial_root_password'] = 'medium123'
volumes:
- ~/medium/mounts-gitlab/config:/etc/gitlab
- ~/medium/mounts-gitlab/logs:/var/log/gitlab
- ~/medium/mounts-gitlab/data:/var/opt/gitlab
gitlab-runner:
image: gitlab/gitlab-runner:latest
container_name: gitlab-runner
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ~/medium/mounts-runners/gitlab-runner-X/config:/etc/gitlab-runner
Make sure to adjust values such as volumes to suit your specific environment. In order to run the docker compose you can use the following command in the directory of your docker-compose.yml.
bash$ docker-compose up -d
After this step your gitlab deployment will be available on localhost:10001. In order to login you must use the root user and the previously defined password.
Registering the Runners Programmatically
Now, let’s proceed to register the Runners. This involves following three steps:
Step #1: Creating a Personal Access Token (PAT)
The first step to is to create a PAT in case you don’t have one already. The PAT will be used to request a Runner Authentication Token associated with a user.
To create the PAT programmatically you can use the following command to generate the string:
bash$ echo $RANDOM | shasum | head -c 30
25502e3103cdc4e1cf92616def0c9d%
Make sure that you have the given hash algorithm installed. In this case, we’re using sha1 but you can also use others.
After having the string that will make up the token, one must register it to gitlab with create_runner permissions.
bash$ docker exec -it gitlab gitlab-rails runner "token = User.find_by_username('root').personal_access_tokens.create(scopes: ['create_runner'], name: 'create_runner_pat', expires_at: 1.days.from_now); token.set_token('25502e3103cdc4e1cf92616def0c9d'); token.save\!"
In this scenario, we’re linking the PAT with the root user, and running the command won’t produce any output.
It’s important to note 2 things:
1- Using the root user in the previous command isn’t the best practice. We’re only employing it in order to simplify the tutorial. In a real-world setting, it’s advisable to create a dedicated user instead of relying on root.
2- Additionally, it’s worth mentioning that registering a Shared Runner (a.k.a., Instance Runners, in some documentation pages) requires the user to have admin privileges. However, this requirement varies depending on the type of Runner. For further details, refer to Gitlab’s documentation on Runners.
Step #2: Getting a Runner Authentication Token
Upon having the personal access token, one can request a Runner Authentication Token with it.
bash$ curl --request POST --header "PRIVATE-TOKEN: 25502e3103cdc4e1cf92616def0c9d" --data "runner_type=instance_type" \
"http://localhost:10001/api/v4/user/runners"
The output of the command will be in JSON format. Something like:
{"id":1,"token":"glrt-gxqs_P3RxvBCkXeY-jjz","token_expires_at":null}
Step #3: Registering the Runner
Finally, we get to the part where we register the Runner. The following is the command that we must run in order to do so.
bash$ docker exec gitlab-runner gitlab-runner register --non-interactive \
--url "http://gitlab:10001" \
--token "glrt-gxqs_P3RxvBCkXeY-jjz" \
--executor "docker" \
--docker-image alpine:latest \
--description "docker-runner"
If you’ve followed the previous steps, you’ll receive a “Runner registered successfully” message similar to:
Runtime platform arch=arm64 os=linux pid=21 revision=782c6ecb version=16.9.1
Running in system-mode.
Verifying runner... is valid runner=pvruoo7qj
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
You can further confirm the success of the operation by navigating to the Runner section in the Admin Area (Search or go to.. > Admin Area > CI/CD > Runners) and ensuring that the new Runner is up and running (pun intended).
Conclusion
The goal of this tutorial is to provide you with the foundational knowledge needed to automate the registration process for your self-managed Runners. Now you can further leverage automation on your gitlab deployment making your life easier while benefiting from increased efficiency, scalability and safety.