CodeWithAbdessamad

Ci Cd Pipelines

CI/CD Pipelines

In the world of cloud-native development, CI/CD pipelines are the lifeblood of efficient and reliable software delivery. They automate the entire journey from code commit to production deployment, ensuring every change is tested, built, and deployed with minimal human intervention. This section dives deep into two critical aspects: Build and Deploy and Automation. By the end, you’ll have a robust foundation for creating pipelines that are resilient, scalable, and production-ready.

Build and Deploy

The build and deploy phase transforms your source code into a production-ready application. In Kubernetes environments, this typically involves three key steps:

  1. Compile code into a container image
  2. Push the image to a registry (e.g., Docker Hub)
  3. Deploy the image to your Kubernetes cluster

Let’s walk through a concrete example using a Go application:

Example: Building and Deploying a Go Application

  1. Create a Dockerfile (for building the Go application):
<code class="language-dockerfile">   # Dockerfile</p>
<p>   FROM golang:1.21-alpine</p>
<p>   WORKDIR /app</p>
<p>   COPY . .</p>
<p>   RUN go build -o app</p>
<p>   EXPOSE 8080</p>
<p>   CMD ["./app"]</code>

  1. Create a GitHub Actions workflow (triggers on main branch pushes):
<code class="language-yaml">   name: Build and Deploy</p>

<p>   on:</p>
<p>     push:</p>
<p>       branches: [ main ]</p>

<p>   jobs:</p>
<p>     build-deploy:</p>
<p>       runs-on: ubuntu-latest</p>
<p>       steps:</p>
<p>         - name: Checkout code</p>
<p>           uses: actions/checkout@v4</p>

<p>         - name: Set up Go</p>
<p>           uses: actions/setup-go@v4</p>
<p>           with:</p>
<p>             go-version: '1.21'</p>

<p>         - name: Build</p>
<p>           run: go build -o app</p>

<p>         - name: Push to Docker Hub</p>
<p>           uses: docker/build-push-action@v4</p>
<p>           with:</p>
<p>             context: .</p>
<p>             dockerfile: Dockerfile</p>
<p>             tags: gcr.io/my-project/app:$(git rev-parse HEAD)</p>

<p>         - name: Deploy to Kubernetes</p>
<p>           uses: kubernetes/action-kubectl@v1</p>
<p>           with:</p>
<p>             command: apply -f k8s/deployment.yaml</code>

  1. Create a Kubernetes deployment manifest (k8s/deployment.yaml):
<code class="language-yaml">   apiVersion: apps/v1</p>
<p>   kind: Deployment</p>
<p>   metadata:</p>
<p>     name: go-app</p>
<p>   spec:</p>
<p>     replicas: 1</p>
<p>     selector:</p>
<p>       matchLabels:</p>
<p>         app: go-app</p>
<p>     template:</p>
<p>       metadata:</p>
<p>         labels:</p>
<p>           app: go-app</p>
<p>       spec:</p>
<p>         containers:</p>
<p>         - name: go-app</p>
<p>           image: gcr.io/my-project/app:$(git rev-parse HEAD)</p>
<p>           ports:</p>
<p>             - containerPort: 8080</code>

Why this matters: This pipeline ensures reproducibility by embedding the commit hash in the image tag. If a deployment fails, you can instantly roll back to a previous stable version using the exact commit context. This is critical for production reliability.

Automation

Automation goes beyond simple scripting—it’s about building systems that are self-healing and resilient. The most advanced approach is GitOps, which treats infrastructure as code and uses Git as the single source of truth for deployments.

Why GitOps is powerful

GitOps transforms automation by:

  • Eliminating manual deployments (changes are applied automatically when committed to Git)
  • Enabling instant rollbacks (revert to previous Git commits with one click)
  • Providing full auditability (every change is tracked in Git history)

Example GitOps Workflow:

<code class="language-bash"># Install Flux (GitOps controller)
<p>flux install --git-repo=https://github.com/your-username/your-repo.git \</p>
<p>  --git-branch=main \</p>
<p>  --kubernetes \</p>
<p>  --namespace=flux</p>

<h1>Commit your Kubernetes manifest to Git (e.g., k8s/deployment.yaml)</h1>
<p>echo "apiVersion: apps/v1</p>
<p>kind: Deployment</p>
<p>metadata:</p>
<p>  name: go-app</p>
<p>spec:</p>
<p>  replicas: 1</p>
<p>  selector:</p>
<p>    matchLabels:</p>
<p>      app: go-app</p>
<p>  template:</p>
<p>    metadata:</p>
<p>      labels:</p>
<p>        app: go-app</p>
<p>    spec:</p>
<p>      containers:</p>
<p>      - name: go-app</p>
<p>        image: gcr.io/my-project/app:$(git rev-parse HEAD)</p>
<p>        ports:</p>
<p>          - containerPort: 8080</p>
<p>" > k8s/deployment.yaml</code>

Key difference: Traditional CI/CD pipelines deploy after code changes, while GitOps deploys from Git changes. This makes GitOps ideal for environments requiring strict compliance and traceability.

Summary

In this section, we’ve explored the critical aspects of CI/CD pipelines: Build and Deploy and Automation. We demonstrated a practical workflow for building and deploying a Go application to Kubernetes, and we extended it to include automated testing. We also introduced GitOps as a modern approach to automation that leverages Git as the single source of truth for infrastructure.

By automating your build, test, and deployment processes, you ensure that your applications are delivered consistently, securely, and at scale. Remember: automation is not just about running commands—it’s about building systems that are resilient and self-healing. 🚀