blog_image.png

Creating Group Webhooks with Templates for Gitlab CI

1 month ago

3 min read

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:

Slack message

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.


Similar Blogs