On this page
CI/CD pipeline architecture
Continuous Integration and Continuous Deployment (CI/CD) pipelines automate the testing, building, and release of software. They enforce parity between environments and remove manual intervention from the release path.
Introduction
A CI/CD pipeline is an automated sequence of steps that takes code from a version control repository and delivers it to a production environment. Continuous Integration merges developer changes into a central repository frequently, running automated builds and tests. Continuous Deployment extends this by automatically releasing every passing build to users.
Pipelines enforce consistency. They ensure that the exact same artifact tested in a staging environment is the one deployed to production.
Mental Model
Think of a pipeline as a state machine. The commit enters the system and moves through discrete stages: build, test, package, deploy. Each stage acts as a gate. If a stage fails, the pipeline halts and reports the failure. The artifact only reaches production if every gate opens successfully.
Commit -> [ Build ] -> [ Unit Test ] -> [ Integration Test ] -> [ Deploy Staging ] -> [ Deploy Prod ]
Operational Pattern
Pipelines implement the “build once, deploy many” pattern. The build stage compiles the code and bundles dependencies into an immutable artifact, such as an OCI container image. The pipeline tags this image with a unique identifier.
Subsequent stages deploy this exact image. The pipeline injects environment-specific configuration at runtime. This guarantees that the code tested in lower environments is identical to the code running in production.
Modern pipelines run steps concurrently to reduce total execution time. If unit tests and static analysis do not depend on each other, the pipeline executes them in parallel.
Failure Modes
Tests fail intermittently without underlying code changes. This is known as a flaky test. Flaky tests erode trust in the pipeline. When developers stop trusting the pipeline, they ignore failures and deploy broken code.
Pipelines break when external dependencies become unavailable. If a package registry goes offline during the build stage, the pipeline halts.
Long execution times delay feedback. A pipeline that takes an hour to run discourages developers from committing small, frequent changes.
Security
Pipelines execute arbitrary code by design. This makes them a high-value target for supply chain attacks.
Build environments require strict isolation. A compromised test script in one pipeline run must not affect subsequent runs or access secrets belonging to other projects. Use ephemeral, single-use build runners.
Pipelines hold credentials for deployment environments. Apply the principle of least privilege. The pipeline should only have the permissions necessary to deploy the specific application it builds, not broad administrative access to the entire cluster.
Operational Guidance
Keep the feedback loop short. The pipeline should report build or unit test failures within five minutes of a commit. Move slow, comprehensive tests to later stages or run them asynchronously.
Fail fast. Execute the fastest and most likely to fail tests first. Do not run a 30-minute integration suite if the code cannot pass a 5-second syntax check.
Treat pipeline configuration as code. Store the pipeline definition in the same repository as the application code. This allows versioning, review, and testing of pipeline changes alongside the application.
Diagnostics
Monitor pipeline duration. Track the time from commit to production deployment. Set a threshold and investigate when the duration exceeds it.
Track the build success rate. A low success rate indicates either unstable tests or a flawed development process.
Inspect build logs for warnings. Warnings often precede failures. Resolve deprecation notices and dependency warnings before they break the build.
Related topics
Sources & further reading
- Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation - Humble & Farley, 2010