Table of Contents
Objectives of this Project Component
By the end of this part of the final project you should be able to:
- Design a simple but realistic CI/CD pipeline targeting OpenShift.
- Implement it using OpenShift Pipelines (Tekton) or an external CI tool (e.g. GitHub Actions, GitLab CI) integrated with OpenShift.
- Use OpenShift-native concepts (Builds, ImageStreams, Deployments/DeploymentConfigs, Routes) as part of the pipeline.
- Demonstrate automated build, test, and deployment on code changes.
- Capture basic logs and evidence that your pipeline works end‑to‑end.
This chapter is not a full re‑introduction to CI/CD or OpenShift Pipelines; instead it gives you a concrete recipe and patterns for your final project.
Scope and Scenario for the Final Project
To keep the focus on CI/CD rather than application complexity, the project assumes:
- A simple application:
- Containerized web app or API (e.g. a small Node.js, Python, or Go service).
- A Dockerfile or S2I-compatible source repository.
- A Git repository:
- Hosted on GitHub/GitLab/Bitbucket or an internal Git service.
- Includes application source, basic tests, and deployment manifests (e.g.
Deployment,Service,Route). - An OpenShift project/namespace dedicated to this app:
- Example names:
myapp-dev,myapp-prod(or a single namespace for smaller setups). - A container registry accessible by OpenShift:
- OpenShift internal registry (via ImageStreams) or external (Quay, Docker Hub, GitHub Container Registry).
Your task is to automate the path:
git commit → build → test → image push → deploy to OpenShift → verify
Designing the Pipeline for OpenShift
Choose Your CI/CD Implementation
For the purpose of this project, you should choose one primary implementation and (optionally) sketch the other as an extension:
- OpenShift Pipelines (Tekton):
- All pipeline logic runs inside the cluster.
- Uses
Pipeline,Task,PipelineRun,PipelineResource(or workspaces, params). - Good if you want a cluster-native solution.
- External CI (e.g. GitHub Actions / GitLab CI):
- Pipeline logic runs on external runners.
- Uses
ocCLI orkubectl-compatible tools to deploy to OpenShift. - Good if you already know such tools or want to integrate with common SaaS CI.
Design your project so that:
- Build and test are reproducible and scriptable (e.g.
make test,npm test,pytest, etc.). - Deployment is fully automated (no manual clicks in the console to deploy new versions).
- The steps can be triggered by Git events (push, PR, or manual dispatch).
Environments and Promotion Strategy
For a final‑project‑sized application, you can use one of:
- Single namespace, controlled by branch:
mainbranch → deploy tomyappnamespace.- Feature branches may only run build+test, no deployment.
- Two namespaces:
myapp-dev: continuous deployment frommain(ordevelop) branch.myapp-prod: deployment only after a manual approval step (e.g. manual Tekton task or CI pipeline job).
Clearly document:
- Which branches deploy where.
- Whether production deployments require manual approval.
- How rollbacks are handled (e.g.
oc rollout undoor redeploy previous image tag).
Implementing CI/CD with OpenShift Pipelines (Tekton)
This section walks through a minimum viable Tekton-based pipeline for the project.
Core Tekton Concepts You Will Use
You will use only a subset of Tekton:
Task: a reusable sequence of steps (build, test, deploy).Pipeline: orchestrates tasks and their ordering.PipelineRun: an execution of a pipeline (per Git commit/trigger).- Workspaces: for shared source code or artifacts.
- Params: to pass branch, Git URL, image name, environment, etc.
- Triggers (optional but recommended):
TriggerTemplate,TriggerBinding,EventListenerto react to webhooks.
You can rely on prebuilt tasks from the Tekton Catalog (e.g. git-clone, buildah, s2i) if available in your environment.
Step 1: Preparing Your OpenShift Project
In your chosen namespace(s):
- Create a service account for running pipelines:
- Bind it to roles that allow:
- Pulling/pushing images to the registry.
- Creating/patching
Deployment/DeploymentConfig. - Reading/writing
Pods,Services,Routes, etc. - Create Secrets required by the pipeline:
- Git access (if private repo).
- Registry credentials (if external registry).
- Optionally, database or API keys, referenced by the app’s deployment.
Reference these secrets in the pipeline service account using imagePullSecrets and appropriate annotations for Tekton tasks that need them.
Step 2: Defining the Pipeline Stages
Design your Tekton Pipeline with clear stages:
- Checkout:
- Task:
git-clone(or equivalent). - Inputs:
git-url,git-revision. - Output: source code in a shared workspace.
- Build Image:
- Options:
- S2I Build using OpenShift
BuildConfig, triggered viaoc start-buildin a task. - Docker/Buildah/Kaniko task building an image and pushing to the registry.
- Inputs: path to source, image name/tag.
- Output: a pushed container image (e.g.
quay.io/user/myapp:$(git-sha)). - Run Tests:
- Task: run unit/integration tests inside a container:
- Use your application’s base image or a dedicated test image.
- Fail fast if tests fail.
- Inputs: source code workspace and optionally the built image (if tests run against containerized app).
- Deploy:
- Task: update Kubernetes/OpenShift objects:
- Patch the image tag in a
DeploymentorDeploymentConfig. - Apply manifests (
oc apply -f k8s/) or usekustomize/helmif available. - Optionally, wait for rollout to complete:
- Use
oc rollout statusorkubectl rollout status. - Inputs: namespace/environment, image reference.
- Verify / Smoke Test (optional but recommended):
- Task: simple HTTP health check:
- Call the Route or Service and verify 2xx response.
- If it fails, mark pipeline as failed.
Your final project should at least implement checkout → build → test → deploy. Smoke test is a bonus that demonstrates good practice.
Step 3: Example Pipeline Structure
A high-level Pipeline YAML might look conceptually like:
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: myapp-ci-cd
spec:
params:
- name: git-url
- name: git-revision
- name: image-url
- name: namespace
workspaces:
- name: source
tasks:
- name: fetch-source
taskRef:
name: git-clone
params: [...]
workspaces: [...]
- name: build-image
runAfter: [fetch-source]
taskRef:
name: buildah # or custom build task
params: [...]
workspaces: [...]
- name: run-tests
runAfter: [build-image]
taskRef:
name: myapp-test
workspaces: [...]
- name: deploy
runAfter: [run-tests]
taskRef:
name: myapp-deploy
params: [...]Your project deliverable should include:
- Actual YAML files for the
TasksandPipeline. - A description of the parameters, workspaces, and how they map to your app.
Step 4: Triggering the Pipeline from Git
To integrate with Git for CI:
- Configure Tekton Triggers:
TriggerTemplate: describes how to instantiate aPipelineRun.TriggerBinding: extracts fields (e.g.repository.url,head_commit.id) from the webhook payload.EventListener: exposes an HTTP endpoint to receive webhooks from Git.- Set Up Webhook in Git:
- Point the repository webhook at the
EventListenerURL. - Configure events: push events or pull request events.
- Branch / Event Logic:
- Use
TriggerBinding+TriggerTemplateparams to: - Run CI (build+test only) for all branches.
- Deploy only on
mainbranch or tags.
If webhook integration is not possible, you can:
- Trigger
PipelineRuns manually viaoc create -f pipelinerun.yaml. - Use a scheduled or manual job in an external CI tool to invoke the OpenShift API.
Implementing CI/CD with External CI Tools
If you choose an external CI tool for the project, the focus shifts to:
- Running build and test in the external CI environment.
- Pushing images to a registry accessible by OpenShift.
- Calling
ocor using Kubernetes APIs to update OpenShift deployments.
Required Building Blocks
- CI Runner with Access to OpenShift:
- Install
ocCLI on the runner image. - Configure authentication (e.g. service account token from OpenShift, stored as CI secret).
oc login(orKUBECONFIG) in the pipeline steps.- Build and Push Image:
- Use standard CI steps:
docker build+docker push.- Or
buildah/kanikoon rootless runners. - Tag images with:
- Commit SHA (
myapp:${GIT_COMMIT}). - Or version numbers (
myapp:v1.2.3). - Deploy to OpenShift:
- Use
occommands: oc project myapp-devoc set image deployment/myapp myapp-container=${IMAGE_TAG}oc rollout status deployment/myapp- Optionally, apply YAML/Helm releases:
oc apply -f k8s/.- Environment Separation:
- In CI configuration, restrict which jobs run on which branches:
main→ deploy tomyapp-dev.tagorrelease/*→ deploy tomyapp-prodwith approval.
Your final project should include:
- CI configuration file (e.g.
.github/workflows/ci.yml,.gitlab-ci.yml). - Snippets showing build, test, image push, and deployment commands.
- Documentation on how secrets are stored and used.
Using OpenShift Resources Effectively in the Pipeline
While the details of Builds, ImageStreams, and Deployments are covered elsewhere, in this project:
- Prefer immutable image tags for each commit:
- e.g.
myapp:sha-<short-sha>. - Use ImageStreams when possible:
- CI pushes into an ImageStream.
- OpenShift deployments watch the ImageStream and roll out automatically on new image tags.
- Ensure your deployment is declarative:
- Keep
Deployment,Service,Route, and config in Git. - CI/CD pipeline applies manifests rather than editing resources by hand.
For rollbacks:
- Either:
- Re-deploy a previous image tag.
- Or:
- Use
oc rollout undo deployment/myappand document this in your project report.
Deliverables for the “Implementing CI/CD with OpenShift” Component
In your final submission, you should include:
- Pipeline Definition:
- Tekton YAMLs (
Task,Pipeline,Trigger) or* - External CI configuration (
.github/workflows/...,.gitlab-ci.yml, etc.). - Deployment Manifests:
- Kubernetes/OpenShift YAML files used by the pipeline:
Deployment/DeploymentConfigServiceRoute- Any
ConfigMap/Secretreferences required to run. - Short Design Document (1–3 pages):
- Pipeline stages and their purpose.
- How triggers work and which branches deploy where.
- How image tagging and rollbacks are handled.
- How secrets and sensitive data are managed in the CI/CD flow.
- Evidence of Execution:
- Logs or screenshots from a successful pipeline run.
- Example of a failed run (e.g., failing tests) and how it was surfaced.
- Verification that a new commit leads to a new deployment on OpenShift.
- Optional Extensions (bonus, not mandatory):
- Manual approval gate for production deployment.
- Canary or blue/green style deployment using OpenShift features.
- Integration with monitoring/logging: e.g. posting deployment status to a dashboard or chat system.
Practical Tips and Common Pitfalls
- Keep the pipeline fast:
- Cache dependencies where possible.
- Avoid rebuilding from scratch if unchanged.
- Avoid embedding secrets in Git:
- Use CI secret stores and OpenShift
Secretobjects. - Make tests fail the pipeline:
- Any test failure should stop deployment.
- Automate environment configuration as much as possible:
- Avoid manual changes to
Deploymentspecs in the web console. - Start simple:
- First implement:
manual PipelineRun + build + test + deploy. - Then add triggers and environment promotion.
This component of the final project is about demonstrating that you can reliably, repeatedly, and automatically move code from a Git repository into a running OpenShift workload with minimal manual steps.