Just enough theory for data pipelines CI/CD automation

What’s this about?

Let’s quickly introduce the basic glossary:

  • By task, we mean a unit element of a pipeline. In particular, a task could be:

    • ETL job which takes one or multiple tables as input, and produces one or multiple tables as output

    • A task might have upstream and downstream dependencies

    • In practice, the task could be a one-step inside multitask job, or a single-step job

  • Tasks are to be combined into pipelines

  • By data pipeline, we mean the composition of tasks. Pipelines shall have the following properties:

    • The pipeline consists of one or more tasks

    • The pipeline might be triggered in different ways. In particular, pipelines can be classified by the following properties:

      • Batch or streaming

      • Regularly scheduled or triggered by an external event

      • It has a defined set of inputs (tables, files, other data sources) and a defined set of outputs (in a perfect setup it shall be Delta tables, but also could be other outputs such as databases/event queues etc.)

  • CI - alias for Continuous Integration. In short, CI is a process, responsible for the correct handling of code changes in a particular project. CI might include components such as unit and integration tests. Important to drop a separation line - CI is not responsible for deploying the artifacts to a specific environment. It is responsible for verifying that code changes are properly managed and tested inside the development environment.

  • CD - alias for Continuous Delivery. In short, while the CI process verifies that code changes themselves are managed well inside the development environment, the CD is responsible for propagating the code changes towards production environments and properly providing the releases.

By automation, we mean the process of accepting the code changes and rolling out releases towards different environments shall be automated as much as possible. In a perfect setup, there shall be no way for manual changes of the code in the production environment.

Now, we can combine a definition of “data pipelines CI & CD automation”:

Note

The process of changing the code of particular data pipelines shall be managed and tested in the most possible automated way. In particular, when a change is applied towards the code of the data pipeline, this change shall be tested on a development environment and approved first.

Generic CI/CD setup

To make CI/CD possible, 3 main requirements shall be fulfilled:

  • Code shall be stored in a git-like repository. In practice, it means using git providers such as GitHub, GitLab, Azure Repos, Bitbucket, etc.

  • Each important code change shall trigger a CI or a CD pipeline.

  • In contrast to data pipelines, CI/CD pipelines describe the set of steps required to perform CI/CD operations (while data pipelines describe the ETL or ML operations on top of the data). There are multiple CI/CD providers, such as Jenkins, GitHub Actions, GitLab CI, Azure DevOps, Bitbucket Pipelines, Circle CI, Drone CI, etc.

Whichever git provider and CI/CD provider you choose, most probably you will end up organizing the following:

  • CI/CD pipelines will be defined in a YAML-like format. The CI/CD pipelines will describe a set of steps that shall be performed on each trigger.

  • A generic set of steps inside a CI pipeline for a Python project can look like this:

    • Install Python in a CI environment

    • Install project dependencies in a CI environment

    • Verify the code conventions with linters

    • Run unit tests

    • Run integration tests

    • Collect code coverage metrics

  • A generic set of steps inside a CD pipeline can look like this:

    • Get the artifact (for example, Python package) from the artifact repository

    • Stop currently running data pipelines

    • Release the new version for currently running data pipelines

    • Collect release information

    • To understand which deployment pipeline needs to be executed in which case, most of the CI/CD providers support triggers functionality. A trigger is an event that could happen with the repository, for example:

      • on push into a branch with name feature/*

      • on each merge towards the main (might be also called master) branch

      • on each new tag, for example when a tag v1.0.0 has been pushed

  • A combination of these events allows configuring a set of proper CI/CD pipelines to make the overall process controllable. In most cases, such CI/CD pipelines are defined inside the same repository where data pipelines, mostly for the simplicity of management and project modularity.

Basic CI/CD architecture

Combining all of the above, here is a generic CI/CD architecture that can be applied for some projects:

../_images/cicd_arch.png