This content originally appeared on Level Up Coding - Medium and was authored by Ilan Pinto
As a developer who values convenience, I have long aspired to create a bot capable of initiating DevOps tasks on my behalf. Having to switch between multiple screens to carry out the build and deploy operations is a tedious task that I, being inherently lazy, wish to avoid. Given that I already use Slack, it seems logical to utilize it as a deployment tool instead of resorting to yet another application.
The practice of utilizing chat to conduct operations, commonly known as ChatOps, has existed for a considerable period.
Due to my lack of time and motivation to set up Jenkins, I decided to use the Tekton-based pipeline on OpenShift.
Understanding Tetkton
Once you understand the Tekton pipeline concept, it is relatively straightforward. Like any other Kubernetes resource, it can be broken down into smaller components that eventually link together.
Similarly, with Tekton, we have a series of resources that reference and form a pipeline of pods.
Tekton offers extensive documentation that covers all the available resources. Although, in this tutorial, I won’t attempt to explain all of the Tekton resources. Instead, I will focus on explaining the ones we will be utilizing.
Task and taskRuns — In Tekton, Tasks are the most fundamental resource within a pipeline, and they are responsible for defining atomic operations to be executed within a pod. For each Task, a pod is created. These operations include cloning Git repositories, building images, or sending emails. On the other hand, TaskRuns are responsible for converting the task definition into a running pod.
The exciting part about using Tekton is that you don’t have to write the code for every task. Tekton already provides pre-defined tasks in Tekton Hub, covering a wide range of CI/CD operations such as image building, integration with IM, static code analysis, and vulnerability checks. All of these tasks are fully open-source and can be downloaded and customized to suit your specific requirements.
Pipelines and PipeplineRuns — Similar to Task and TaskRun, a Pipeline is the definition resource, while a PipelineRun is responsible for initiating the execution of a pipeline. Pipelines are used to group together tasks and define the order in which they should be executed, along with any conditions that need to be met. They also define which parameters can be passed between tasks and provide more advanced configuration options.
EventListner and Trigger Template — The EventListener in Tekton is responsible for exposing a webhook and parsing any parameters to be utilized by the TriggerTemplate. Once the parameters have been parsed, the TriggerTemplate is triggered. The TriggerTemplate defines which pipeline or tasks should be executed and passes the parameters to the pipeline. The TriggerTemplate in Tekton includes the necessary bindings to pass parameters to the corresponding PipelineRun. It defines required parameters and how they should be mapped to the pipeline’s inputs. Defining these bindings in the TriggerTemplate makes it much easier to initiate the pipeline execution with the appropriate parameters.
Let's Start building the bot.
In this section, I will guide you on quickly creating a Slack app called Build Bot. This app can receive slash commands and initiate a Tekton Build task. After the task finishes, the bot will respond to the Slack channel. You can access the sample code for this tutorial here.
Workspace setup
Before we begin developing the bot, It is crucial to set up the environment and install necessary prerequisites..
To start, we should initialize a Kubernetes cluster. For local testing purposes, I suggest using Kind or Minkube.
Next, we need to install the following CLI tools Kubectl, and Tkn.
Lastly, if you don't already have one, you will need a Slack account to configure a Slack app.
Tekton Deployment
It's time to deploy Tekton services. We must deploy the latest version of the Tekton components: Tetkon pipelines, Tetkon triggers, and Tetkon interceptor.
//run this commands to deploy the Tetkon components
kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yam
Note: During the process of writing this article, I came across the realization that the Tekton Slack webhook is no longer functional. As a result, I have made a contribution by introducing the Slack Interceptors feature, which is accessible starting from Tekton Triggers version 0.24.0 .
Tekton Pipeline Configuration
tasks import
Tekton provides a set of pre-defined tasks that can be used in our workflows. We’ll need to import these tasks from the Tekton Hub. The following tasks will be imported from the hub:
git-clone, s2i — build and push an image to the image registry and send-to-webhook-slack
Use the below command to apply the resource to your Kubernetes cluster.
kubectl apply -f https://hub.tekton.dev/tekton/task/git-clone
kubectl apply -f https://hub.tekton.dev/tekton/task/s2i
kubectl apply -f https://hub.tekton.dev/tekton/task/send-to-webhook-slack
Alternatively, we could use the tkn CLI :
tkn hub install task [Task-name]
Pipeline configuration
Our build pipeline will execute the following tasks: clone the repository, build a container image, and push the image to the registry. Finally, it will send a notification to Slack.
Here is a sample YAML configuration for a Pipeline resource(comments in line) :
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: build-pipeline
namespace: sample-app
spec:
workspaces: # a shared, persistent volume that enables sharing storage between the pods like the cloned Git folder with the build task
- name: shared-workspace
params: # input parameters that identify the branch name and pushed image tag
- name: branch-name
type: string
description: The git branch to clone.
- name: image-tag
type: string
description: repo image tag
tasks: # ref to the pipeline tasks and
- name: clone
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-workspace
params:
- name: url
value: git@github.com:ilan-pinto/buildbot-tekton.git
- name: revision
value: "$(params.branch-name)"
- name: subdirectory
value: "sample-app"
- name: deleteExisting
value: "true"
- name: build
taskRef:
name: s2i
runAfter:
- clone
workspaces:
- name: source
workspace: shared-workspace
params:
- name: BUILDER_IMAGE
value: quay.io/centos7/python-38-centos7
- name: TLSVERIFY
value: "false"
- name: LOGLEVEL
value: "10"
- name: IMAGE_NAME
value: quay.io/[my image registry]/sample-app:"$(params.image-tag)"
finally: # tasks to be executed in any scenario, either a successful, partial, or failed pipeline run
- name: slack-final-notification
taskRef:
name: send-to-webhook-slack
when:
- input: "$(tasks.status)"
operator: in
values: ["Completed","Failed","Succeeded"]
params:
- name: webhook-secret
value: slack-webhook-secret
- name: message
value: "build bot pipeline *$(tasks.status)* for branch: $(params.branch-name)"
Secret managment
To ensure the privacy of your git and image repositories, it is necessary to include the appropriate secret resources. Additionally, if you intend to use the send-to-webhook-slack feature, you will need an additional secret containing the Slack generated webhook. These secrets should be associated with the serviceAccount resource and later assigned to the PipelineRun.
Pipeline execution
We will create a PipelineRun resource to trigger the pipeline for validation purposes.
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: sample-app-build-
namespace: sample-app
spec:
serviceAccountName: sample-app-sa # binding secrets to the pipeline.You dont need it if your git or image repo is public
pipelineRef:
name: build-pipeline
params:
- name: branch-name
value: "main"
- name: image-tag
value: "v1"
workspaces:
- name: shared-workspace
persistentVolumeClaim: # PipelineRun requires a PVC for the Workspace
claimName: sample-app-pvc
Event listener configuration
The Tekton pipeline will expose a webhook that parses and triggers a pipeline.
To do that, we will need to configure an EventLister, a TriggerTemplate, and a Webhook Interceptor for Slack.
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: build-pipeline-template
spec:
params:
- name: branch
- name: image
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: build-pipeline-from-slack-
namespace: sample-app
labels:
tekton.dev/pipeline: build-pipeline
spec:
params:
- name: branch-name
value: $(tt.params.branch)
- name: image-tag
value: $(tt.params.image)
pipelineRef:
name: build-pipeline
serviceAccountName: sample-app-sa
workspaces:
- name: shared-workspace
persistentVolumeClaim:
claimName: sample-app-pvc
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: slack-listener
annotations:
tekton.dev/payload-validation: "false"
spec:
serviceAccountName: tekton-triggers-example-sa
triggers:
- name: slack-trigger
interceptors:
- ref:
name: "slack" # refering the slack intercptor to parse incoming text
kind: ClusterInterceptor
params:
- name: requestedFields
value:
- text
- ref:
name: cel # refering cel interceptor
params:
- name: "overlays"
value:
- key: branch
expression: 'extensions.text[0].split(" ")[0]'
- key: image
expression: 'extensions.text[0].split(" ")[1]'
bindings:
- name: branch
value: $(extensions.branch)
- name: image
value: $(extensions.image)
template:
ref: build-pipeline-template
Efficiency Unleashed: A Guide to Building a ChatOps Bot for Slack with Tekton
As a developer who values convenience, I have long aspired to create a bot capable of initiating DevOps tasks on my behalf. Having to switch between multiple screens to carry out the build and deploy operations is a tedious task that I, being inherently lazy, wish to avoid. Given that I already use Slack, it seems logical to utilize it as a deployment tool instead of resorting to yet another application.
The practice of utilizing chat to conduct operations, commonly known as ChatOps, has existed for a considerable period.
Due to my lack of time and motivation to set up Jenkins, I opted to utilize the Tekton-based pipeline of my openshift cluster instead.
Understanding Tetkton
Once you understand the Tekton pipeline concept, it is relatively straightforward. Like any other Kubernetes resource, it can be broken down into smaller components that eventually link together.
Similarly, with Tekton, we have a series of resources that reference and form a pipeline of pods.
Tekton offers extensive documentation that covers all the available resources. Although, in this tutorial, I won’t attempt to explain all of the Tekton resources. Instead, I will focus on explaining the ones we will be utilizing.
Task and taskRuns — In Tekton, Tasks are the most fundamental resource within a pipeline, and they are responsible for defining atomic operations to be executed within a pod. For each Task, a pod is created. These operations include cloning Git repositories, building images, or sending emails. On the other hand, TaskRuns are responsible for converting the task definition into a running pod.
The exciting part about using Tekton is that you don’t have to write the code for every task. Tekton already provides pre-defined tasks in Tekton Hub, covering a wide range of CI/CD operations such as image building, integration with IM, static code analysis, and vulnerability checks. All of these tasks are fully open-source and can be downloaded and customized to suit your specific requirements.
Pipelines and PipeplineRuns — Similar to Task and TaskRun, a Pipeline is the definition resource, while a PipelineRun is responsible for initiating the execution of a pipeline. Pipelines are used to group together tasks and define the order in which they should be executed, along with any conditions that need to be met. They also define which parameters can be passed between tasks and provide more advanced configuration options.
EventListner and Trigger Template — The EventListener in Tekton is responsible for exposing a webhook and parsing any parameters to be utilized by the TriggerTemplate. Once the parameters have been parsed, the TriggerTemplate is triggered. The TriggerTemplate defines which pipeline or tasks should be executed and passes the parameters to the pipeline. The TriggerTemplate in Tekton includes the necessary bindings to pass parameters to the corresponding PipelineRun. It defines required parameters and how they should be mapped to the pipeline’s inputs. Defining these bindings in the TriggerTemplate makes it much easier to initiate the pipeline execution with the appropriate parameters.
Let’s Start building the bot.
In this section, I will guide you on quickly creating a Slack app called Build Bot. This app can receive slash commands and initiate a Tekton Build task. After the task finishes, the bot will respond to the Slack channel. You can access the sample code for this tutorial here. The diagram below illustrates the flow of our use case.
Workspace setup
It’s crucial to ensure that the environment is properly set up and all the necessary prerequisites are installed. This step can make all the difference in getting things up and running smoothly!.
To start, we should initialize a Kubernetes cluster. For local testing purposes, I suggest using Kind or Minkube.
Next, we need to install the following CLI tools Kubectl, and Tkn.
Lastly, if you don’t already have one, you will need a Slack account to configure a Slack app.
Tekton Deployment
It’s time to deploy Tekton services. We must deploy the latest version of the Tekton components: Tetkon pipelines, Tetkon triggers, and Tetkon interceptor.
//run this commands to deploy the Tetkon components
kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yam
Note: During the process of writing this article, I came across the realization that the Tekton Slack webhook is no longer functional. As a result, I have made a contribution by introducing the Slack Interceptors feature, which is accessible starting from Tekton Triggers version 0.24.0 .
Tekton Pipeline Configuration
tasks import
Tekton provides a set of pre-defined tasks that can be used in our workflows. We’ll need to import the following tasks from the Tekton Hub:
git-clone, s2i — build and push an image to the image registry and send-to-webhook-slack
Use the below command to apply the resource to your Kubernetes cluster.
kubectl apply -f https://hub.tekton.dev/tekton/task/git-clone
kubectl apply -f https://hub.tekton.dev/tekton/task/s2i
kubectl apply -f https://hub.tekton.dev/tekton/task/send-to-webhook-slack
Alternatively, we could use the tkn CLI :
tkn hub install task [Task-name]
Pipeline configuration
Our pipeline will execute the following tasks: clone the repository, build a container image, and push the image to the registry. Finally, it will send a notification to Slack.
Here is a sample YAML configuration for a Pipeline resource(comments in line) :
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: build-pipeline
namespace: sample-app
spec:
workspaces: # a shared, persistent volume that enables sharing storage between the pods like the cloned Git folder with the build task
- name: shared-workspace
params: # input parameters
- name: branch-name
type: string
description: The git branch to clone.
- name: image-tag
type: string
description: repo image tag
tasks: # ref to the pipeline tasks
- name: clone
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-workspace
params:
- name: url
value: git@github.com:ilan-pinto/buildbot-tekton.git
- name: revision
value: "$(params.branch-name)"
- name: subdirectory
value: "sample-app"
- name: deleteExisting
value: "true"
- name: build
taskRef:
name: s2i
runAfter:
- clone
workspaces:
- name: source
workspace: shared-workspace
params:
- name: BUILDER_IMAGE
value: quay.io/centos7/python-38-centos7
- name: TLSVERIFY
value: "false"
- name: LOGLEVEL
value: "10"
- name: IMAGE_NAME
value: quay.io/[my image registry]/sample-app:"$(params.image-tag)"
finally: # tasks to be executed in any scenario, either a successful, partial, or failed pipeline run
- name: slack-final-notification
taskRef:
name: send-to-webhook-slack # triggers notifition to slack chanel
when:
- input: "$(tasks.status)"
operator: in
values: ["Completed","Failed","Succeeded"]
params:
- name: webhook-secret
value: slack-webhook-secret
- name: message
value: "build bot pipeline *$(tasks.status)* for branch: $(params.branch-name)"
Secret managment
To ensure the privacy of your git and image repositories, it is necessary to include the appropriate secret resources. Additionally, if you intend to use the send-to-webhook-slack feature, you will need an additional secret containing the Slack generated webhook. These secrets should be associated with the serviceAccount resource and later assigned to the PipelineRun.
Pipeline execution
We will create a PipelineRun resource to trigger the pipeline only for validation purposes.
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: sample-app-build-
namespace: sample-app
spec:
serviceAccountName: sample-app-sa # binding secrets to the pipeline.You dont need it if your git or image repo is public
pipelineRef:
name: build-pipeline
params:
- name: branch-name
value: "main"
- name: image-tag
value: "v1"
workspaces:
- name: shared-workspace
persistentVolumeClaim: # PipelineRun requires a PVC for the Workspace
claimName: sample-app-pvc
Event listener configuration
The Tekton pipeline will expose a webhook that parses and triggers a pipeline.
For that purpose, we will need to configure a TriggerTemplate and an EventLister with Slack Interceptor.
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: build-pipeline-template
spec:
params: # input params
- name: branch
- name: image
resourcetemplates: # definition of triggerd resource
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: build-pipeline-from-slack-
namespace: sample-app
labels:
tekton.dev/pipeline: build-pipeline
spec:
params:
- name: branch-name
value: $(tt.params.branch)
- name: image-tag
value: $(tt.params.image)
pipelineRef:
name: build-pipeline
serviceAccountName: sample-app-sa
workspaces:
- name: shared-workspace
persistentVolumeClaim:
claimName: sample-app-pvc
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: builder-bot-listener-interceptor
annotations:
tekton.dev/payload-validation: "false"
spec:
serviceAccountName: sample-app-sa
triggers:
- name: slack-bot-build-trigger
interceptors:
- ref:
name: "slack" # refering the slack intercptor to parse incoming text
kind: ClusterInterceptor
params:
- name: requestedFields
value:
- text
- ref:
name: cel # refering cel interceptor
params:
- name: "overlays"
value:
- key: branch
expression: 'extensions.text.split(" ")[0]'
- key: image
expression: 'extensions.text.split(" ")[1]'
bindings:
- name: branch
value: $(extensions.branch)
- name: image
value: $(extensions.image)
template:
ref: build-pipeline-template # ref to the trigger template defined in previous step
Once the resources are applied, Tekton will proceed to deploy a new service resource called el-builder-bot-listener-interceptor. In a production environment, we must expose this service. However, for testing purposes, the kubectl port-forward command can be used.
kubectl port-forward svc/el-builder-bot-listener-interceptor 8080
To expose a port-forwarded service publicly, I recommend using ngrok. Ngrok is a popular tool that creates secure tunnels to expose local servers to the internet
Now, our Tekton Pipeline is fully configured, and we have successfully exposed the webhook to receive incoming messages from Slack.
Final Step: Configuring Slack app
Slack incoming webhook configuration
Please follow these steps to activate the incoming webhook for your Slack app.
- Select your desired Slack app from the list of apps you have created or click on “Create an app” to create a new one.
- In the left-hand sidebar, click on “Incoming Webhooks” under the “Features” section.
- Toggle the switch to enable incoming webhooks.
- Scroll down to the section titled “Webhook URLs for Your Workspace.”
- Click on the “Add New Webhook to Workspace” button.
- Select the channel where you want the incoming webhook messages to be posted.
- Click on the “Allow” button to authorize the incoming webhook.
- Once the webhook is created, you will see the webhook URL displayed. Take note of this URL, as it will be needed for sending messages to Slack using the webhook.
- Add the URL to Kubernetes by applying a secret.
kind: Secret
apiVersion: v1
metadata:
name: slack-webhook-secret #
stringData:
url: https://hooks.slack.com/services/XXXXXXX/YYYYYYYYY/TTTTTT #here you should add ther real one
make sure that the name of the incoming webhook in Slack is identical to the secret name specified in the pipeline configuration for the send-to-webhook-slack the webhook-secret parameter value.
....
....
finally:
- name: slack-final-notification
taskRef:
name: send-to-webhook-slack
when:
- input: "$(tasks.status)"
operator: in
values: ["Completed","Failed","Succeeded"]
params:
- name: webhook-secret
value: slack-webhook-secret # put here the slack secret in which contains the webhook
- name: message
value: "build bot pipeline *$(tasks.status)* for branch: $(params.branch-name)"
Slack Slash command configuration
- In the left-hand sidebar, click on “Slash Commands” under the “Features” section.
- Click on the “Create New Command” button.
- Fill in the following details for your slash command:
- Command: Enter the command you want to use (e.g., /mycommand).
- Request URL: Specify the URL you have generated for the event listener
- Short Description: Provide a brief description of what the command does.
- Usage Hint: Optionally, add a usage hint or example for users.
Once you have completed these steps, your slash command will be configured for your Slack app. Users in the specified workspace will be able to trigger the command by typing it in Slack and invoking its functionality.
Wrap-up
In conclusion, we have successfully configured a Tekton Pipeline with an exposed webhook to receive incoming messages from Slack. By following the steps outlined in this article, you can ensure that your git and image repositories are private by adding the necessary secret resources.
With this setup, you have a powerful system in place for automating your CI/CD workflows using Tekton and integrating with Slack for seamless communication and collaboration. By leveraging the webhook capabilities, you can receive real-time updates and notifications from your pipeline directly in your Slack channels.
As always, it’s important to adapt these configurations and practices to suit the specific needs of your project.
Happy automating and collaborating!
Level Up Coding
Thanks for being a part of our community! Before you go:
- 👏 Clap for the story and follow the author 👉
- 📰 View more content in the Level Up Coding publication
- 💰 Free coding interview course ⇒ View Course
- 🔔 Follow us: Twitter | LinkedIn | Newsletter
🚀👉 Join the Level Up talent collective and find an amazing job
Efficiency Unleashed: A Guide to Building a ChatOps Bot for Slack with Tekton was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Ilan Pinto
Ilan Pinto | Sciencx (2023-05-21T19:05:58+00:00) Efficiency Unleashed: A Guide to Building a ChatOps Bot for Slack with Tekton. Retrieved from https://www.scien.cx/2023/05/21/efficiency-unleashed-a-guide-to-building-a-chatops-bot-for-slack-with-tekton/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.