Currently Gitlab stores a vast majority of their functionality into their paid packages. Group webhooks is one of them and if your using a group runner, the group webhook becomes sought after. This is easily achievable without using a paid plan by creating reusable templates. Gitlab offers great functionality for configuring your CI with include and exclude functions. These can be reused to create a base template for all your CI jobs.
Setting up a default CI template
We'll create first a default template which we'll extend when creating a deploy stage.
gitlab-ci-defaults.yml
image: docker:stable
services:
- docker:dind
# Default Stages
stages:
- deploy
# Default runner tag
.default_vars:
tags:
- shared_aws_spot_runner
You can store your webhook in the default template but I'll create a separate yaml file.
First, create a slack bot and add an incoming webhook. We can use the webhook URL to send a curl request to the Slack API. We'll use Gitlab CI's after_script
which runs both if the CI fails or succeeds, which will send the curl request.
gitlab-ci-webhooks.yml
.default_webhooks:
after_script:
- >
curl -X POST -H 'Content-type: application/json' --data '{"text":"*'"$GITLAB_USER_NAME $(cat .job_status) $CI_COMMIT_SHORT_SHA to $CI_COMMIT_REF_NAME"'*\n```'"Docker Image deployed: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA\nPrevious Docker Image: $CI_REGISTRY_IMAGE:${CI_COMMIT_BEFORE_SHA:0:8}\nCommit Title: $CI_COMMIT_TITLE\nCommit Description: $CI_COMMIT_DESCRIPTION\nMerge Request: ${CI_MERGE_REQUEST_PROJECT_URL:-No Merge Request}\nPipeline Details:$CI_PIPELINE_URL\nJob Detail:$CI_JOB_URL\n"'```\n>'"$CI_PROJECT_URL"'"}' https://hooks.slack.com/services/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
Include the webhooks in the default template.
gitlab-ci-defaults.yml
image: docker:stable
services:
- docker:dind
# Add webhooks
include:
- project: 'honeylogic/gitlab-ci-templates'
ref: master
file: 'gitlab-ci-webhooks.yml'
# Default Stages
stages:
- deploy
# Default runner tag
.default_vars:
tags:
- shared_aws_spot_runner
Now you can include the default template and extend the default variables. I have a separate project for gitlab-ci templates but Gitlab supports local templates as well. We use before_script
to add by default a failed message which is used in the Slack message. In the script we echo deployed and replace the failed message as the last step, which indicates that CI passed since we reached the last step(Gitlab has currently no cleaner way of doing this, where CI status is accessible). By extending the default_webhooks
variable we'll add all the default webhooks that exist as after_script
(s).
.gitlab-ci.yml
include:
- project: 'honeylogic/gitlab-ci-templates'
ref: master
file: 'gitlab-ci-defaults.yml'
deploy:
extends:
- .default_vars
- .default_webhooks
before_script:
- echo "failed to deploy" > .job_status
script:
- ansible-playbook ansible/deploy_xyz_app.yml -i -i environments/prod -e app_image=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- echo "deployed" > .job_status
Summary
The Slack template will output a message that fully utilizes Gitlab's predefined environment variables:
The solution is still not as clean as having Gitlab's UI where you can add a group webhook through the UI. But I find this method great for smaller teams that do not pay for Gitlab's enterprise features. Plus, a big upside is that the code is infrastructure/CI as code which I prefer way more than any UI. Using base templates can cover extremely much and you can generalize language specific deployment pipelines.
I've written a blog post that goes into details on creating templates for your Gitlab CI Jobs.