This is how we are starting to deploy using the pipelines. As you can see, the job is very small, and it also leaves little room for anyone to corrupt it.
But we have many things in the background that make it so that a developer only needs to specify this job, and it’s GitLab itself that decides:
Where it is deployed
In which cluster
And with what permissions
Now, let’s get to the important part: !Reference. This job is a matryoshka of jobs; it calls this job:
And here’s where the magic of !Reference comes in. We used to use the famous <<: *, but it’s a hassle and doesn’t merge arrays; it just overwrites. With !Reference, we can specify where we want to use those snippets, allowing anyone to reuse them wherever they wish.
Continuing with the example, let’s look at those two snippets we referenced:
.deployer_prepare: before_script: # Package installation -apt-getupdate&&apt-getinstall-y--no-install-recommendscurltarbashjqpython3python3-pipgitgccbuild-essential&&apt-getclean&&rm-rf/var/lib/apt/lists/* # HashiCorp packages cleanup -| if [ -f /etc/apt/sources.list.d/hashicorp.list ]; then echo "Cleaning up hashicorp.list..." rm /etc/apt/sources.list.d/hashicorp.list fi if [ -f /etc/apt/sources.list.d/archive_uri-https_apt_releases_hashicorp_com-bookworm.list ]; then echo "Cleaned up archive_uri-https_apt_releases_hashicorp_com-bookworm.list..." rm /etc/apt/sources.list.d/archive_uri-https_apt_releases_hashicorp_com-bookworm.list fi .oidc_authenticate: before_script: -!reference [.deployer_prepare, before_script] # Assume role using GitLab OIDC -pipinstallawscli--no-cache-dir--break-system-packages -echo"$GITLAB_OIDC_TOKEN">/tmp/gitlab-id-token -exportAWS_WEB_IDENTITY_TOKEN_FILE=/tmp/gitlab-id-token -| CREDS=$(aws sts assume-role-with-web-identity \ --role-arn "$(aws iam get-role --role-name $AWS_DEFAULT_GITLAB_RUNNER_ROLE --query 'Role.Arn' --output text)" \ --role-session-name "gitlab-ci-session" \ --web-identity-token file://$AWS_WEB_IDENTITY_TOKEN_FILE \ --duration-seconds 3600) exportAWS_ACCESS_KEY_ID=$(echo"$CREDS"|jq-r.Credentials.AccessKeyId) exportAWS_SECRET_ACCESS_KEY=$(echo"$CREDS"|jq-r.Credentials.SecretAccessKey) exportAWS_SESSION_TOKEN=$(echo"$CREDS"|jq-r.Credentials.SessionToken) -mkdir-p~/.aws -awseks --region$AWS_REGION update-kubeconfig --name$KUBE_CLUSTER --alias$KUBE_CLUSTER -| for repo in $(echo $HELM_REPOS | sed "s/,/ /g") do helm repo add $(echo $repo | sed "s/;/ /g") done -"helm repo update || :"
That’s where the magic lies: we have 3 levels of nested jobs called from wherever we want, so if someone wants to deploy, they only have to call the first job. And if we want to change something in the authentication, we only need to modify it in .oidc_authenticate, and that change will propagate.
This is code reuse, which (in addition to increasing the blast radius) allows developers to abstract away a lot of code that they neither want nor need to know.