Giter Site home page Giter Site logo

ci-cd-playground's Introduction

CI/CD Playground

This repository is intended to create a basic Flask Web Application and to create related CI/CD pipelines using Minikube, Helm, Jenkins and Terraform.

Introduction

This project walks through implementing a simple CI/CD pipeline for a Python Flask application. The following is demonstrated:

  • Integrating Jenkins with a GitHub project
  • Implementing a CI/CD pipeline using a Jenkinsfile
  • Testing and running static code analysis, publishing related reports to the Jenkins Pipeline
  • Building the Python package
  • Building the Docker image using the Python package
  • Publishing the Docker image to Docker Hub
  • Deploying the Docker image to a K8s cluster

Prerequisites

Before you get started you'll need to have these:

  • GitHub Account
  • Docker Hub Account or any other public/private Docker Image Registry Account
  • A local or remote Jenkins server. In this project, a local installation used. Refer here for the local installation instructions and the configuration for this project
  • A local or remote K8s cluster. In this project, Minikube used for a local K8s cluster installation. If you will also use the Minikube, you'll need a container or virtual machine manager, such as: Docker, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox, or VMWare
  • Python Version >= 3.6

Project Structure

.
├── Jenkinsfile
├── Makefile
├── README.md
├── app/
├── deploy/
│   ├── helm-chart/
│   └── terraform/
└── local-installations/
    └── jenkins/

app directory contains the source code and configuration files of the application.

deploy directory contains the Helm Chart and the Terraform configuration files to deploy the application to a K8s cluster.

local-installations directory contains related documents to refer for installing and configuring Jenkins server.

Workflow

On every pipeline execution, the code goes through the following steps:

  1. Code is cloned from this repository, built, tested and analyzed for bugs and bad patterns.
  2. A Docker Container Image is built then published to Docker Container Registry.
  3. If all previous steps finished successfully, the pipeline is paused for the approval to continue to the deployment.
  4. If approved, the container image is deployed in a fresh new container in related K8s namespace.

Targeted release version for the Python package and Docker image is set in the target-version.json file in the app directory. Three tags were used as suffixes to separate the packages: dev (development), rc (release candidate), and no suffix (release).

  • Any pipeline running from not main branches (a.k.a. feature/bug fix branches) builds the Python package and Docker image with the <target-version>-dev-<uuid> tag, then publishes the Docker image to registry and deploys it to dev namespace on the K8s cluster.
  • Any pipeline running from the main branch builds the Python package and Docker image with the <target-version>-rc-<uuid> , then publishes the Docker image to registry and deploys it to rc namespace on the K8s cluster.
  • Any pipeline running from git tag builds the Python package and Docker image with the <target-version> tag, then publishes the Docker image to registry and deploys it to prod namespace on the K8s cluster.

Thoughts and Future Works

For a healthier SDLC:

  • Make your developments in feature branches.
  • Create short-lived branches.
  • Commit often.
  • Run the pipeline to see failures fast, to test the deployment on K8s.
  • Prevent merging unhealthy branches to main branch.

Expand the release version identification with community standards.

Add more stages between development, release candidate, and release. This is not necessary since this is a personal and one-person project. But, with a growing team, it would be better to have more controls before merging the feature branches to the main branch.

The CI/CD pipeline covered in this project is only for one application. Add some other units such as a database or another service that the app will communicate with and implement a mechanism for integration tests.

Test the Terraform configurations using a tool such as kitchen

ci-cd-playground's People

Contributors

erolkeskiner avatar dependabot[bot] avatar

Watchers

 avatar

ci-cd-playground's Issues

Local Terraform state file

The pipeline needs to import the Terraform state before executing the deployment.
This is causing state problems if the target namespace and Helm release does not already exist or already created but not with Terraform.
Since this is a local development environment, use a directory on the local machine for Terraform state files.

K8s preparations

Create '/healtz' endpoint(s) for liveness and readiness probes

Separate /versionz endpoint to another container

Create another Flask app to serve /versionz endpoint to run in another container next to main app.
Create another container image to use as a reverse proxy in front of the main app and versionz app.

Create a Jenkinsfile

Run tests and/or code analysis
Build Docker image
Publish Docker image
Deploy the published image to minikube based on branches and tags using created Helm Chart

Create a Helm Chart for the Web App

Enable/disable a sidecar container in the deployment with a flag in the values file
If sidecar is enabled deploy it in front of the Web App container as a proxy

Create a Makefile for the Web App

Clean workspace
Create virtualenv
Resolve dependencies
Refresh dependencies
Build docker image(s)
Run unit tests
Run the Web App locally with Python command (use the command-line argument for the listening port (defaults to 8080))
Run the Web App locally in a Docker container (use the command-line argument for the listening port (defaults to 8080))
Run code style and standards analysis with flake8 (or another linter)

Version info endpoint

Create '/versionz' endpoint that returns a JSON with query time, git hash and name of the project

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.