DevOps & Delivery · Beginner to Advanced
CI/CD Pipeline: Complete Developer Learning Guide
Understand how modern teams build, test, package, secure, release, and deploy software. Learn CI/CD foundations, pipeline architecture, GitHub Actions, GitLab CI/CD, Jenkins, Azure Pipelines, CircleCI, containers, Kubernetes, GitOps, deployment strategies, and practical workflows for .NET applications.
A CI/CD pipeline is an automated workflow that helps a development team move software changes from source control through validation and delivery. It can compile an application, run tests, create versioned artifacts, perform security checks, deploy to environments, and verify that the release is healthy.
CI/CD is not a single product and it is not limited to one cloud provider. GitHub Actions, GitLab CI/CD, Jenkins, Azure Pipelines, CircleCI, Bitbucket Pipelines, and other systems provide different ways to automate similar engineering practices. The underlying principles remain useful regardless of the platform.
This guide explains those principles first and then compares common tools. Practical examples focus on C#, .NET, ASP.NET Core, SQL Server, Docker, and web application delivery, while keeping the concepts applicable to other technology stacks.
Learning roadmap
- DevOps and CI/CD foundations
- Continuous Integration (CI)
- Continuous Delivery and Deployment
- Anatomy of a CI/CD pipeline
- Pipeline triggers and workflow
- Source control and branching
- Build and package automation
- Automated testing in pipelines
- Artifacts and package repositories
- Environments and configuration
- Runners, agents and executors
- CI/CD platforms overview
- GitHub Actions
- GitLab CI/CD
- Jenkins
- Azure Pipelines
- CircleCI and other platforms
- Docker and container pipelines
- Kubernetes deployment
- GitOps and Argo CD
- Deployment strategies
- Infrastructure as Code
- Secrets and configuration management
- DevSecOps and pipeline security
- Software supply-chain security
- Database migrations and releases
- Monitoring and release verification
- Pipeline optimization
- Monorepos and microservices
- Delivery metrics and DORA
- End-to-end .NET CI/CD example
- Common CI/CD mistakes
- CI/CD implementation checklist
- Interview questions
- Official learning resources
1. DevOps and CI/CD foundations
What is DevOps?
DevOps is a set of cultural practices, engineering processes, and tools that improve collaboration between software development and IT operations. Its goal is to deliver software reliably and frequently while improving feedback, automation, and operational responsibility.
DevOps is not simply installing a CI/CD tool. It involves shared ownership, version control, automated testing, infrastructure automation, observability, security, and continuous improvement.
What is a pipeline?
A pipeline is a defined sequence or graph of automated tasks. A pipeline can be triggered by a code push, pull request, merge request, schedule, release tag, manual action, or another system event.
Common DevOps practices
- Version control: Track application code, pipeline definitions, and infrastructure configuration.
- Continuous integration: Integrate and validate changes frequently.
- Continuous delivery: Keep software in a releasable state.
- Infrastructure as Code: Define infrastructure using versioned, reviewable configuration.
- Automated testing: Run repeatable checks throughout development.
- Monitoring and feedback: Observe deployed systems and use operational data to improve them.
- Security automation: Include security checks and access controls in the delivery process.
2. Continuous Integration (CI)
Continuous Integration is the practice of frequently integrating code changes into a shared repository and automatically validating those changes. A CI pipeline commonly restores dependencies, compiles the solution, runs automated tests, and reports the results.
Typical CI workflow
Developer changes code
|
v
Commit and push to Git
|
v
Pull request / merge request
|
v
CI pipeline starts
|
v
Restore dependencies
|
v
Build and static checks
|
v
Run automated tests
|
v
Publish test results
|
v
Review and merge
Why CI matters
- Find integration and compilation problems early.
- Give developers fast feedback on changes.
- Reduce the risk of long-lived, conflicting branches.
- Ensure a consistent build process across developer machines and CI agents.
- Provide evidence that a change passed defined checks before merging.
CI is most effective when changes are integrated regularly and the automated checks are reliable. A pipeline that takes hours or frequently fails for unrelated reasons weakens feedback and discourages teams from using it.
3. Continuous Delivery and Continuous Deployment
CD can refer to Continuous Delivery or Continuous Deployment. Both extend CI by automating the path from a validated change to a deployable or deployed release, but they differ in the final production decision.
| Practice | Meaning | Production release |
|---|---|---|
| Continuous Delivery | Every validated change is kept in a state that can be released through a repeatable process. | Production deployment may require a human approval or business decision. |
| Continuous Deployment | Every change that passes the required pipeline checks is automatically deployed to production. | Deployment is automated without a separate manual release approval. |
Continuous Delivery flow
Code change
|
v
Build + Test + Scan
|
v
Create versioned artifact
|
v
Deploy to test / staging
|
v
Acceptance and release checks
|
v
Production approval
|
v
Deploy to production
Continuous Deployment flow
Code change
|
v
Build + Test + Scan
|
v
Create versioned artifact
|
v
Automated release checks
|
v
Automatic production deployment
|
v
Health verification and monitoring
4. Anatomy of a CI/CD pipeline
A pipeline is usually composed of stages, jobs, steps, agents, conditions, artifacts, and environments. The exact terminology varies by platform, but the concepts are similar.
| Component | Purpose |
|---|---|
| Trigger | Event or condition that starts a pipeline. |
| Pipeline | Complete automated workflow definition. |
| Stage | Major phase such as Build, Test, Security, or Deploy. |
| Job | Unit of work that runs on an execution environment. |
| Step | Individual command, script, or action within a job. |
| Runner / agent | Machine or execution service that runs jobs. |
| Artifact | Output produced by a build, such as a package or container image. |
| Environment | Target such as Development, QA, Staging, or Production. |
| Variable / secret | Configuration value or protected credential used by a job. |
| Approval / gate | Condition that must be satisfied before a protected action proceeds. |
Example pipeline stages
Pipeline
|
+-- CI
| +-- Restore
| +-- Build
| +-- Unit Tests
| +-- Code Quality
| +-- Security Scans
| +-- Package
|
+-- CD
+-- Deploy to Development
+-- Integration Tests
+-- Deploy to Staging
+-- Acceptance Checks
+-- Approval
+-- Deploy to Production
+-- Health Verification
Stages do not always have to run sequentially. Independent jobs can execute in parallel, while dependency rules determine which jobs must complete before others begin.
5. Pipeline triggers and workflow
A trigger determines when a pipeline starts. A well-designed pipeline uses different triggers for validation, scheduled maintenance, and controlled releases.
| Trigger | Typical use |
|---|---|
| Push | Run CI when a developer pushes a commit. |
| Pull request / merge request | Validate a proposed change before it is merged. |
| Branch filter | Run specific workflows for main, development, or release branches. |
| Tag / release | Create or deploy a versioned release. |
| Scheduled | Run nightly tests, dependency checks, or maintenance tasks. |
| Manual | Allow an authorized user to start a workflow or approve a deployment. |
| Pipeline completion | Start a downstream pipeline after another pipeline succeeds. |
| External event | Start work from a webhook, API call, or another system. |
Pull-request validation should normally run before code is merged. Production deployment should use protected branches, release conditions, and environment controls appropriate to the application.
6. Source control and branching strategy
Source control provides history, collaboration, review, and traceability. Git is commonly used with CI/CD platforms, but the pipeline principles are not tied to a specific Git hosting provider.
Common branching approaches
- Trunk-based development: Developers integrate small changes into a shared mainline frequently, using short-lived branches and feature flags where needed.
- Feature branching: A feature is developed on a separate branch and merged after review and validation.
- Release branching: A release branch is maintained for stabilization or supported versions when the product's release model requires it.
- GitFlow: A more structured branching model with dedicated development, release, and hotfix branches. It may suit some release processes but can introduce longer-lived branches and merge overhead.
Pull request checks
- Build and test the proposed code.
- Run linting, formatting, static analysis, and security checks.
- Require code review for protected branches.
- Verify that required checks pass before merge.
- Use branch protection or repository rules to prevent bypassing critical controls.
7. Build and package automation
A build converts source code and dependencies into an executable or deployable output. A reliable pipeline should build in a controlled environment and report failures clearly.
Typical .NET build commands
# Restore NuGet dependencies
dotnet restore
# Compile the solution
dotnet build MyApplication.sln --configuration Release --no-restore
# Publish an application
dotnet publish src/MyApplication.Api/MyApplication.Api.csproj \
--configuration Release \
--no-build \
--output ./publish
In a production pipeline, the publish step should use the intended runtime and deployment model. Framework-dependent and self-contained deployments have different runtime requirements. Container builds may publish into a runtime image instead of producing a standalone folder artifact.
Build once, promote the same artifact
A strong release process creates a versioned artifact from a particular commit and promotes that same artifact through Development, QA, Staging, and Production. Rebuilding separately for each environment can create differences between what was tested and what was released.
Commit abc123
|
v
Build package: app-1.4.0
|
+----> Development
|
+----> QA
|
+----> Staging
|
+----> Production
Environment-specific values should generally be supplied through configuration and secret-management systems rather than by changing the compiled application package.
8. Automated testing in CI/CD
Automated tests provide feedback at different points in the pipeline. The test strategy should balance speed, confidence, and maintenance cost.
| Test type | Pipeline purpose |
|---|---|
| Unit tests | Fast validation of isolated business logic. |
| Integration tests | Verify interactions between application components and dependencies. |
| API tests | Validate HTTP behavior, contracts, status codes, and authorization. |
| UI / E2E tests | Validate critical user journeys through the running application. |
| Performance tests | Measure response times and behavior under defined workloads. |
| Security tests | Identify code, dependency, configuration, and runtime security issues. |
Run .NET tests in a pipeline
dotnet restore
dotnet build MyApplication.sln \
--configuration Release \
--no-restore
dotnet test MyApplication.sln \
--configuration Release \
--no-build \
--logger "trx;LogFileName=test-results.trx"
Configure the CI platform to collect and publish test results. A test command that runs but whose results are not visible to developers is harder to troubleshoot and audit.
Quality gates
A quality gate is a condition that must be met before the pipeline proceeds. Examples include all required tests passing, no prohibited severity of security findings, a successful code-quality analysis, or an approved deployment.
9. Artifacts and package repositories
An artifact is a versioned output produced by a pipeline. It may be a compiled application, NuGet package, ZIP archive, container image, Helm chart, or deployment manifest bundle.
Common artifact and package repositories
| Repository | Common use |
|---|---|
| GitHub Packages | Store packages and container images associated with GitHub repositories and organizations. |
| GitLab Package Registry | Store packages and container images within GitLab projects or groups. |
| Azure Artifacts | Host NuGet, npm, Maven, Python, and other supported package types. |
| JFrog Artifactory | Central artifact management across multiple package formats and repositories. |
| Sonatype Nexus Repository | Host and proxy software packages and build artifacts. |
| Docker Hub / container registries | Store and distribute container images. |
| Amazon ECR / Google Artifact Registry | Cloud-hosted container and artifact storage. |
Artifact versioning
Use immutable or uniquely identifiable artifact versions. Useful identifiers include semantic versions, release tags, commit SHAs, build numbers, and image digests.
For container images, a tag such as latest is convenient for experimentation but is not a reliable release identity. A deployment record should identify the exact image digest or immutable version that was deployed.
10. Environments and configuration
An environment is a place where an application is built, tested, or operated. Environment separation helps teams validate changes progressively before exposing them to real users.
| Environment | Purpose |
|---|---|
| Local | Developer workstation for coding and quick checks. |
| Development | Shared environment for early integration and developer testing. |
| QA / Test | Functional, integration, and exploratory validation. |
| Staging / Pre-production | Production-like validation before release. |
| Production | Live system serving real users. |
Not every project needs every environment. The important point is to make environment purpose, data, access, and promotion rules explicit.
Configuration by environment
ASP.NET Core supports configuration from JSON files, environment variables, command-line arguments, and other providers. Environment-specific settings should be externalized and protected where necessary.
// Example: appsettings.Production.json
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
}
}
Connection strings, passwords, API keys, and signing credentials should not be committed to source control. Use a protected secret store or the CI/CD platform's secure variable mechanism.
11. Runners, agents and executors
A pipeline needs computing resources to execute its jobs. Different platforms use different names for these execution environments.
| Platform | Execution terminology |
|---|---|
| GitHub Actions | Runner |
| GitLab CI/CD | Runner |
| Jenkins | Agent / node |
| Azure Pipelines | Agent |
| CircleCI | Executor |
| Bitbucket Pipelines | Step runtime / runner |
Hosted vs self-hosted execution
- Hosted runners: The platform provides and manages the execution machine. This reduces infrastructure maintenance but may have usage limits, cost, and environment constraints.
- Self-hosted runners: The organization manages its own machines or containers. This provides control over network access, tools, hardware, and private resources, but also creates patching, isolation, and security responsibilities.
Use isolated and appropriately scoped execution environments. Avoid running untrusted pull-request code on a machine that has production credentials or unrestricted access to internal systems.
12. CI/CD platforms overview
Many platforms can implement the same core pipeline. Their differences include source-control integration, configuration syntax, execution model, reusable components, deployment approvals, security controls, hosting options, and ecosystem.
| Platform | Pipeline definition | Typical strengths |
|---|---|---|
| GitHub Actions | YAML workflow files | Native GitHub integration, hosted and self-hosted runners, reusable workflows, marketplace actions. |
| GitLab CI/CD | .gitlab-ci.yml | Integrated source control, pipelines, runners, registry, environments, and security capabilities. |
| Jenkins | Jenkinsfile (Groovy) | Flexible automation server, extensive plugin ecosystem, self-managed execution. |
| Azure Pipelines | YAML or Classic UI | Multi-platform builds, agents, environments, approvals, and integration with Azure DevOps. |
| CircleCI | .circleci/config.yml | Workflow orchestration, executors, reusable Orbs, parallel jobs, caching. |
| Bitbucket Pipelines | bitbucket-pipelines.yml | Pipeline automation integrated with Bitbucket repositories. |
| Buildkite | Pipeline configuration and agents | Hosted orchestration with organization-managed agents and infrastructure flexibility. |
| TeamCity | UI and Kotlin DSL | Build management, build chains, test reporting, and JetBrains ecosystem integration. |
| Google Cloud Build | YAML / JSON build config | Managed builds and integrations with Google Cloud services. |
| AWS CodePipeline | Pipeline configuration | Release orchestration across AWS services and external build/deployment providers. |
Platform features and pricing change over time. Evaluate current documentation, hosting requirements, security model, integrations, and expected pipeline usage before selecting a tool.
13. GitHub Actions
GitHub Actions is a CI/CD and workflow automation platform integrated with GitHub repositories. Workflows are YAML files stored under .github/workflows.
Core concepts
- Workflow: The complete automation definition.
- Event: An event that triggers a workflow, such as push or pull request.
- Job: A group of steps executed on a runner.
- Step: A shell command or reusable action.
- Action: A reusable unit of automation.
- Runner: The machine that executes a job.
- Environment: A deployment target with optional protection rules and secrets.
Example: build and test a .NET application
# .github/workflows/dotnet-ci.yml
name: .NET CI
on:
push:
branches: [ "main", "develop" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
- name: Set up .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Restore
run: dotnet restore MyApplication.sln
- name: Build
run: dotnet build MyApplication.sln -c Release --no-restore
- name: Test
run: dotnet test MyApplication.sln -c Release --no-build
This is an illustrative workflow. Use the .NET SDK version supported by the project and pin third-party actions to reviewed versions or immutable commit SHAs according to your organization's policy.
Reusable workflows and environments
Reusable workflows allow teams to centralize common pipeline logic. Environments can add deployment protection rules, required reviewers, branch restrictions, and environment-specific secrets. Use narrowly scoped workflow permissions and avoid granting write access to jobs that only need to build and test.
14. GitLab CI/CD
GitLab CI/CD defines pipelines in a repository-level .gitlab-ci.yml file. Pipelines contain jobs grouped into stages, and GitLab Runners execute the jobs.
Core concepts
- Pipeline: Complete set of jobs created for an event or manual trigger.
- Stage: Logical phase such as build, test, or deploy.
- Job: Individual task executed by a runner.
- Runner: Execution service that picks up jobs.
- Artifact: Output or report retained for later jobs or download.
- Cache: Reusable data intended to speed up later jobs.
Example .NET pipeline
# .gitlab-ci.yml
stages:
- build
- test
- publish
variables:
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
build:
stage: build
image: mcr.microsoft.com/dotnet/sdk:10.0
script:
- dotnet restore MyApplication.sln
- dotnet build MyApplication.sln -c Release --no-restore
unit_tests:
stage: test
image: mcr.microsoft.com/dotnet/sdk:10.0
script:
- dotnet test MyApplication.sln -c Release
needs:
- build
publish:
stage: publish
image: mcr.microsoft.com/dotnet/sdk:10.0
script:
- dotnet publish src/MyApplication.Api/MyApplication.Api.csproj -c Release -o publish
artifacts:
paths:
- publish/
needs:
- unit_tests
In GitLab, jobs in the same stage can run in parallel unless dependencies or scheduling rules constrain them. The needs keyword can express direct job dependencies and enable more flexible execution than waiting for every job in a previous stage.
Additional capabilities
GitLab supports merge request pipelines, child and parent pipelines, multi-project pipelines, environments, deployment approvals, package and container registries, and security scanning features depending on configuration and subscription tier.
15. Jenkins
Jenkins is an open-source automation server used to build, test, and deliver software. It can run on self-managed infrastructure and connect to different source-control systems, build tools, deployment targets, and plugins.
Core concepts
- Controller: Coordinates jobs, configuration, and scheduling.
- Agent: Executes pipeline work on a connected machine.
- Pipeline: Versioned workflow definition.
- Stage: Named phase of the workflow.
- Step: Individual command or plugin-provided operation.
- Jenkinsfile: Pipeline definition stored with source code.
- Plugin: Extension that adds integrations or capabilities.
Declarative Jenkinsfile example
pipeline {
agent any
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Restore') {
steps {
sh 'dotnet restore MyApplication.sln'
}
}
stage('Build') {
steps {
sh 'dotnet build MyApplication.sln -c Release --no-restore'
}
}
stage('Test') {
steps {
sh 'dotnet test MyApplication.sln -c Release --no-build'
}
}
stage('Publish') {
steps {
sh 'dotnet publish src/MyApplication.Api/MyApplication.Api.csproj -c Release -o publish'
}
}
}
}
This example assumes an agent with the required .NET SDK and shell tools. A Windows agent may use the appropriate Windows command step. Production pipelines should also archive or publish the output, configure credentials securely, and define deployment controls.
Jenkins considerations
- Maintain and update the controller and plugins.
- Use separate, isolated agents for untrusted and trusted workloads.
- Limit credentials available to each job.
- Keep pipeline definitions in source control.
- Review plugin provenance, permissions, and maintenance status.
16. Azure Pipelines
Azure Pipelines is the CI/CD service in Azure DevOps. It supports applications written in many languages and can deploy to cloud services, virtual machines, containers, Kubernetes, and on-premises targets. It can use repositories hosted in Azure Repos or GitHub.
Core concepts
- Pipeline: Defines the build, test, and deployment workflow.
- Stage: Major phase such as Build, Test, or Deploy.
- Job: Group of steps executed by an agent or supported agentless service.
- Step: Script or task within a job.
- Agent: Machine that executes jobs.
- Artifact: Output passed to later stages or pipelines.
- Environment: Deployment target with history, checks, and approvals.
Example YAML pipeline
# azure-pipelines.yml
trigger:
branches:
include:
- main
- develop
pool:
vmImage: ubuntu-latest
variables:
buildConfiguration: Release
steps:
- task: UseDotNet@2
inputs:
packageType: sdk
version: '10.0.x'
- script: dotnet restore MyApplication.sln
displayName: Restore
- script: dotnet build MyApplication.sln --configuration $(buildConfiguration) --no-restore
displayName: Build
- script: dotnet test MyApplication.sln --configuration $(buildConfiguration) --no-build
displayName: Test
- script: dotnet publish src/MyApplication.Api/MyApplication.Api.csproj -c $(buildConfiguration) -o $(Build.ArtifactStagingDirectory)
displayName: Publish
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)
ArtifactName: drop
Azure Pipelines also supports multi-stage YAML pipelines, templates, variable groups, secure files, deployment jobs, environments, approvals, and checks. These features are useful for separating build validation from controlled environment deployments.
17. CircleCI and other CI/CD platforms
CircleCI
CircleCI defines pipeline configuration in .circleci/config.yml. A configuration contains jobs, executors, workflows, and steps. Workflows orchestrate job dependencies and can run independent jobs in parallel.
# .circleci/config.yml
version: 2.1
jobs:
build-and-test:
docker:
- image: mcr.microsoft.com/dotnet/sdk:10.0
steps:
- checkout
- run:
name: Restore
command: dotnet restore MyApplication.sln
- run:
name: Build
command: dotnet build MyApplication.sln -c Release --no-restore
- run:
name: Test
command: dotnet test MyApplication.sln -c Release --no-build
workflows:
build:
jobs:
- build-and-test
CircleCI also provides reusable Orbs, caching, workspaces, artifacts, contexts, scheduled triggers, and approval jobs. Verify executor image availability and platform-specific configuration against the current CircleCI documentation.
Bitbucket Pipelines
Bitbucket Pipelines stores pipeline definitions in bitbucket-pipelines.yml. It supports steps, deployment environments, caches, artifacts, and self-hosted runners. It is a natural option for teams already using Bitbucket repositories.
Buildkite and TeamCity
Buildkite combines hosted orchestration with agents that an organization can run in its own infrastructure. TeamCity provides build configurations, build chains, test reporting, and Kotlin DSL options. Both can be used for complex enterprise build and release workflows.
Cloud-native build services
Google Cloud Build and AWS CodePipeline provide managed build or release automation integrated with their respective cloud ecosystems. They can also work alongside external source-control and deployment tools.
18. Docker and container pipelines
Docker packages an application and its runtime dependencies into a container image. Container images help make build and runtime environments more consistent across development, testing, and deployment.
Multi-stage Dockerfile for ASP.NET Core
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore src/MyApplication.Api/MyApplication.Api.csproj
RUN dotnet publish src/MyApplication.Api/MyApplication.Api.csproj \
-c Release \
-o /app/publish \
--no-restore
# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final
WORKDIR /app
COPY --from=build /app/publish .
ENV ASPNETCORE_HTTP_PORTS=8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApplication.Api.dll"]
Use compatible SDK and runtime image versions, review image updates, and follow the hosting platform's port and health-check requirements. A production Dockerfile should also consider non-root execution, image size, trusted base images, and vulnerability scanning.
Container pipeline flow
Source code
|
v
Build and test
|
v
Build Docker image
|
v
Scan image and dependencies
|
v
Tag with version / commit
|
v
Push to container registry
|
v
Deploy exact image digest
|
v
Verify running application
Container registry examples
- Docker Hub
- GitHub Container Registry (GHCR)
- GitLab Container Registry
- Azure Container Registry (ACR)
- Amazon Elastic Container Registry (ECR)
- Google Artifact Registry
BuildKit and modern build tooling can support build caching, multi-platform images, and build metadata such as provenance and software bills of materials when configured.
19. Kubernetes deployment
Kubernetes is a container orchestration platform. It manages workloads such as Deployments, Services, Jobs, and other resources across a cluster. CI/CD systems can deploy Kubernetes manifests, Helm charts, or other declarative configuration.
Important Kubernetes concepts
- Cluster: The Kubernetes environment that manages workloads.
- Node: A machine that runs application workloads.
- Pod: The smallest deployable workload unit.
- Deployment: Manages replicated application Pods and rollout behavior.
- Service: Provides a stable network endpoint for a group of Pods.
- ConfigMap: Stores non-secret configuration data.
- Secret: Stores sensitive configuration, subject to cluster security and encryption practices.
- Ingress / Gateway: Provides HTTP routing into cluster services, depending on the installed implementation.
Example Deployment manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapplication-api
spec:
replicas: 2
selector:
matchLabels:
app: myapplication-api
template:
metadata:
labels:
app: myapplication-api
spec:
containers:
- name: api
image: registry.example.com/myapplication-api:1.0.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health/ready
port: 8080
livenessProbe:
httpGet:
path: /health/live
port: 8080
The image name is illustrative. In a real release, use an image from your trusted registry and prefer an immutable digest or controlled version tag. Configure resource requests and limits, security context, secrets, service networking, and health endpoints according to the workload.
Helm
Helm packages Kubernetes resources into charts with configurable values. A pipeline can lint, package, publish, and deploy Helm charts. Keep environment-specific values in controlled configuration and review changes before applying them to production.
20. GitOps and Argo CD
GitOps is an operational model in which Git stores the desired state of an application or infrastructure, and an automated controller reconciles the running environment toward that declared state.
Push-based deployment vs pull-based GitOps
| Push-based deployment | Pull-based GitOps |
|---|---|
| CI/CD pipeline connects to the target environment and applies deployment changes. | A controller inside or near the target environment watches the desired configuration and applies changes. |
| Pipeline generally needs deployment credentials for the target. | CI can update Git configuration without directly holding cluster deployment credentials. |
| Deployment state is driven by pipeline execution. | Controller continuously compares declared and live state and can detect drift. |
Argo CD
Argo CD is a declarative GitOps continuous delivery tool for Kubernetes. It monitors Git repositories and compares the desired manifests with the live cluster state. Depending on configuration, it can synchronize changes automatically or wait for an operator to initiate synchronization.
GitOps workflow
CI pipeline
|
+--> Build, test and scan application
|
+--> Publish versioned container image
|
+--> Update deployment manifest / Helm values
|
v
Git configuration repo
|
v
Argo CD
|
v
Kubernetes cluster
|
v
Reconcile desired state
GitOps is especially useful for Kubernetes environments and multi-service deployments. It does not replace CI: CI still builds, tests, scans, and publishes the application artifact.
21. Deployment strategies
A deployment strategy controls how a new version is introduced to users and how the system behaves if the release is unhealthy.
| Strategy | How it works | Considerations |
|---|---|---|
| Recreate | Stop the old version and start the new version. | Simple, but may cause downtime. |
| Rolling | Replace instances gradually while maintaining service capacity. | Requires compatibility between versions during rollout. |
| Blue-green | Run old and new environments separately, then switch traffic. | Can enable fast traffic switching but may require extra capacity and careful data compatibility. |
| Canary | Send a small portion of traffic to the new version, then increase gradually. | Needs routing, monitoring, and clear promotion criteria. |
| Progressive delivery | Release in controlled steps using metrics, analysis, and policy. | Requires reliable telemetry and automated or manual decision controls. |
| Feature flags | Deploy code while controlling feature exposure separately. | Flags need ownership, security, testing, and cleanup. |
Blue-green deployment
Traffic
|
Load Balancer
/ \
/ \
Blue (v1) Green (v2)
Active Ready
|
Verify new version
|
Switch traffic
Canary deployment
Initial traffic:
100% --------------------> Version 1
Canary:
90% --------------------> Version 1
10% --------------------> Version 2
After healthy verification:
50% --------------------> Version 1
50% --------------------> Version 2
Completed:
0% --------------------> Version 1
100% --------------------> Version 2
Deployment strategy selection depends on architecture, infrastructure, database compatibility, traffic routing, and the cost of running multiple versions. A rollback plan should be designed before deployment, not invented after a failure.
22. Infrastructure as Code (IaC)
Infrastructure as Code means defining infrastructure through version-controlled configuration instead of relying only on manual portal or console operations. It makes infrastructure changes reviewable, repeatable, and easier to reproduce.
Common IaC tools
- Terraform / OpenTofu: Declarative infrastructure provisioning across multiple providers.
- Bicep: Declarative language for Azure resource deployment.
- AWS CloudFormation: Infrastructure provisioning for AWS.
- Pulumi: Infrastructure as code using general-purpose programming languages.
- Ansible: Automation and configuration management for systems and services.
IaC in a pipeline
Infrastructure code change
|
v
Format and validate
|
v
Static analysis / policy checks
|
v
Generate plan / preview
|
v
Review proposed changes
|
v
Approval (where required)
|
v
Apply infrastructure changes
|
v
Verify deployed resources
Protect infrastructure state, credentials, and production deployment permissions. Avoid automatically applying unreviewed infrastructure changes to critical environments.
23. Secrets and configuration management
CI/CD pipelines often need credentials to access package feeds, cloud resources, databases, signing services, and deployment targets. These credentials must be protected.
Configuration vs secrets
| Configuration | Secret |
|---|---|
| Non-sensitive values such as feature settings, log levels, or service URLs. | Sensitive values such as passwords, access tokens, private keys, and connection credentials. |
| Can often be stored in versioned environment configuration. | Should be stored in a protected secret-management system. |
Common secret-management options
- GitHub Actions secrets and environment secrets.
- GitLab CI/CD protected and masked variables.
- Jenkins Credentials.
- Azure DevOps secret variables, variable groups, and secure files.
- HashiCorp Vault.
- AWS Secrets Manager and Systems Manager Parameter Store.
- Azure Key Vault.
- Google Secret Manager.
Prefer short-lived identity where supported
When a CI/CD platform and target cloud support workload identity federation, OpenID Connect (OIDC) can allow a job to obtain short-lived credentials without storing a long-lived cloud access key in pipeline secrets. Configure trust conditions carefully, including repository, branch, workflow, and environment identity where supported.
24. DevSecOps and pipeline security
DevSecOps integrates security practices into development and operations. A secure pipeline protects both the application being delivered and the automation system that builds and deploys it.
Security checks across the pipeline
| Security activity | Purpose |
|---|---|
| SAST | Static Application Security Testing analyzes source code for potential vulnerabilities. |
| SCA | Software Composition Analysis identifies vulnerable or risky third-party dependencies and licenses. |
| Secret scanning | Detects credentials or tokens accidentally committed to repositories. |
| Container scanning | Checks container images and their operating-system or application packages for known vulnerabilities. |
| DAST | Dynamic Application Security Testing evaluates a running application from the outside. |
| IaC scanning | Checks infrastructure definitions for insecure configuration. |
| License checks | Evaluates third-party package licenses against organizational policy. |
| Policy checks | Enforces defined security and compliance rules. |
Pipeline security principles
- Apply least privilege to users, service accounts, runners, and pipeline tokens.
- Use short-lived credentials and OIDC federation where supported.
- Protect production environments and require appropriate approvals.
- Pin and review third-party actions, plugins, images, and reusable components.
- Isolate untrusted builds from privileged deployment workloads.
- Keep runners patched and remove unused credentials and permissions.
- Log pipeline activity and monitor unusual behavior.
- Review changes to pipeline configuration as carefully as application code.
25. Software supply-chain security
Software supply-chain security focuses on the integrity and trustworthiness of everything used to build and distribute software: source code, dependencies, build tools, pipeline definitions, artifacts, and release processes.
SBOM
A Software Bill of Materials (SBOM) is a machine-readable inventory of software components included in a product. It can help teams understand dependency exposure, respond to vulnerability disclosures, and support software transparency requirements.
Artifact signing and provenance
- Artifact signing: Provides a way to verify that an artifact came from a trusted signing identity and has not been altered since signing.
- Build provenance: Records information about how an artifact was produced, such as source revision, build process, and builder identity.
- Reproducible builds: Aim for the same source and controlled inputs to produce equivalent build outputs.
- Dependency pinning: Controls which dependency versions are used by a build.
- Verified downloads: Checks integrity and origin of build tools and dependencies.
SLSA provides a framework for improving software artifact integrity and build provenance. Sigstore provides tools and services for signing and verifying software artifacts. Select controls according to your threat model and compliance requirements.
26. Database migrations and releases
Database changes need special care because application code and database schema may be deployed at different times. A deployment that replaces application files successfully can still fail if the database is incompatible.
Common migration approaches
- EF Core migrations: Version schema changes alongside the application model and apply them through a controlled process.
- SQL migration scripts: Store reviewed, versioned SQL scripts and execute them through a deployment step or database release tool.
- Database project deployment: Use a SQL Server Database Project and a DACPAC-based deployment workflow where appropriate.
Expand-and-contract pattern
For changes that need to support old and new application versions during a rolling or gradual deployment, use an expand-and-contract approach.
- Expand: Add a new nullable column, table, or compatible structure without immediately removing the old one.
- Transition: Deploy application code that can work with the compatible schema and gradually move reads and writes.
- Backfill: Populate new data where necessary using a controlled process.
- Contract: Remove obsolete structures only after all deployed code no longer depends on them.
27. Monitoring and release verification
Deployment is not the end of a release. Teams need to verify that the application is healthy and that the new version behaves correctly under real conditions.
Post-deployment checks
- Health and readiness endpoints respond as expected.
- Application instances start and remain available.
- Critical API requests succeed.
- Authentication and database connectivity work.
- Error rates and latency remain within acceptable thresholds.
- Logs and traces show no unexpected failures.
- Business-critical workflows continue to operate.
Observability signals
| Signal | What it helps explain |
|---|---|
| Logs | Detailed events and errors emitted by the application. |
| Metrics | Numerical measurements such as request rate, error rate, CPU, and memory. |
| Traces | How a request travels across services and dependencies. |
| Health checks | Whether an application or dependency is ready or functioning. |
OpenTelemetry is a vendor-neutral framework for generating and exporting telemetry such as traces, metrics, and logs. Combine telemetry with alerts and release annotations so that a deployment can be correlated with changes in system behavior.
28. Pipeline optimization
Pipeline performance affects developer feedback, release frequency, and infrastructure cost. Optimize based on measured bottlenecks rather than adding complexity without evidence.
- Dependency caching: Reuse NuGet packages and other dependencies where safe.
- Parallel jobs: Run independent test suites, builds, or scans concurrently.
- Incremental builds: Avoid rebuilding unaffected components when the tooling supports reliable incremental behavior.
- Path filters: Run only relevant jobs when a change affects a specific project or directory.
- Test selection: Run fast critical tests on every change and broader suites at suitable stages.
- Reusable templates: Standardize common steps without copying large blocks of configuration.
- Appropriate runners: Match CPU, memory, operating system, and architecture to the workload.
- Artifact reuse: Build once and promote the same artifact instead of rebuilding at every environment.
29. Monorepos and microservices
A monorepo stores multiple applications or services in one repository. A multi-repository approach stores them separately. Both can work with CI/CD, but pipeline design differs.
Monorepo pipeline considerations
- Use path filters to identify which applications or libraries changed.
- Build shared libraries before dependent applications where required.
- Use reusable workflows or templates for consistent pipeline logic.
- Keep test and deployment boundaries clear for independently released components.
Microservices pipeline considerations
- Each service should have a repeatable build, test, scan, and packaging process.
- Service contracts and compatibility should be tested.
- Use independent release controls where services deploy separately.
- Coordinate shared infrastructure and cross-service changes explicitly.
- Use consistent artifact versioning and deployment observability.
Reusable pipeline templates help standardize common controls while allowing service-specific build and test steps. Avoid creating a single tightly coupled release pipeline that prevents independently deployable services from being released safely.
30. Delivery metrics and DORA
Delivery metrics help teams understand how effectively they deliver software and how stable their releases are. Metrics should support improvement, not become simplistic individual performance scores.
| Metric | Meaning |
|---|---|
| Deployment frequency | How often an organization successfully deploys to production. |
| Lead time for changes | Time from a code change being committed to that change running in production. |
| Change failure rate | Proportion of deployments that result in a failure requiring remediation. |
| Failed deployment recovery time | How long it takes to recover from a failed deployment. |
DORA research has evolved its measurement model over time. Confirm the current definitions and measurement guidance from the official DORA resources rather than treating older summaries as permanent. Metrics need consistent definitions and context to be useful.
31. End-to-end .NET CI/CD example
Consider a full-stack application with an Angular frontend, an ASP.NET Core Web API, and a SQL Server database. The same delivery concepts can be implemented using GitHub Actions, GitLab CI/CD, Jenkins, Azure Pipelines, CircleCI, or another suitable platform.
Reference architecture
Developer
|
v
Git Repository
|
v
CI/CD Platform
|
+-- Restore and Build .NET API
|
+-- Build Angular frontend
|
+-- Run Unit and Integration Tests
|
+-- Security and Dependency Scans
|
+-- Package / Build Container Images
|
+-- Publish Versioned Artifacts
|
v
Artifact Registry
|
v
Deployment Workflow
|
+-----+------+
| |
v v
Test / QA Staging
| |
+-----+------+
|
Approval Gate
|
v
Production
|
v
Health Checks / Telemetry
Suggested repository structure
MySolution/
|
+-- src/
| +-- MyApplication.Api/
| +-- MyApplication.Application/
| +-- MyApplication.Domain/
| +-- MyApplication.Infrastructure/
| +-- MyApplication.Web/
|
+-- tests/
| +-- MyApplication.UnitTests/
| +-- MyApplication.IntegrationTests/
|
+-- database/
| +-- migrations/
| +-- scripts/
|
+-- deploy/
| +-- docker/
| +-- kubernetes/
| +-- helm/
|
+-- .github/
| +-- workflows/
|
+-- MySolution.sln
This is one possible structure. The frontend may live in a separate repository, and deployment manifests may be maintained in a separate GitOps repository.
Practical pipeline sequence
- Developer pushes code: A branch or pull request event starts CI.
- Restore and build: Restore NuGet and frontend dependencies, then compile the .NET and frontend projects.
- Run tests: Execute unit tests and selected integration tests; publish the results.
- Quality and security: Run static analysis, dependency checks, secret scanning, and other required security gates.
- Package: Publish the .NET application and build the frontend output or container images.
- Store artifacts: Publish immutable packages or image versions to a trusted registry.
- Deploy to test: Deploy the exact artifact and run smoke and integration checks.
- Promote to staging: Use the same artifact and environment-specific configuration.
- Release decision: Apply required approvals and change controls.
- Deploy to production: Use an appropriate strategy such as rolling, blue-green, or canary.
- Verify and monitor: Check health, logs, metrics, traces, and key business workflows.
Where can the application be deployed?
- Windows Server with IIS.
- Linux virtual machines with a reverse proxy and .NET runtime.
- Docker hosts or container platforms.
- Kubernetes clusters.
- Managed application hosting services across cloud providers.
- On-premises infrastructure or a hybrid environment.
CI/CD is independent of the hosting choice. The deployment job changes according to the target, but source validation, build consistency, test automation, artifact versioning, security, and release verification remain relevant.
32. Common CI/CD mistakes
- Using CI only as a deployment script: Include build validation, tests, and quality checks—not just a copy command.
- Rebuilding for every environment: Promote the same tested artifact where practical.
- Storing secrets in source control: Use protected secret stores and short-lived credentials.
- Giving every job broad permissions: Apply least privilege and separate build from deployment identities.
- Using one shared runner for everything: Isolate untrusted and privileged workloads.
- Ignoring flaky tests: Investigate unstable tests rather than repeatedly rerunning without understanding the cause.
- Deploying without health verification: Confirm that the release is actually healthy.
- Having no rollback or recovery plan: Design recovery before the release.
- Overcomplicating the first pipeline: Start with a reliable build and test workflow, then add controls incrementally.
- Ignoring database compatibility: Coordinate schema and application changes across deployment versions.
- Depending on unpinned third-party components: Review and pin actions, plugins, images, and dependencies according to policy.
- Measuring only pipeline speed: Balance speed with reliability, security, and release outcomes.
33. CI/CD implementation checklist
- Source code and pipeline configuration are version controlled.
- Pull requests run required build and test checks.
- Builds use a defined SDK and dependency strategy.
- Unit and relevant integration tests run automatically.
- Test and security results are retained and visible.
- Artifacts are versioned and stored in a trusted repository.
- The same artifact is promoted across environments where practical.
- Environment configuration is externalized.
- Secrets are protected and credentials use least privilege.
- Production deployments have suitable approvals and protection.
- Deployment strategy and rollback or recovery steps are documented.
- Database changes are backward-compatible where required.
- Post-deployment health checks and monitoring are configured.
- Runners, agents, plugins, actions, and dependencies are maintained.
- Pipeline duration, reliability, and delivery outcomes are reviewed.
34. CI/CD interview questions
1. What is CI/CD?
CI/CD is a set of practices and automation workflows that validate, package, and deliver software changes. CI focuses on frequent integration and automated validation; CD extends the process to release and deployment.
2. What is the difference between Continuous Delivery and Continuous Deployment?
Continuous Delivery keeps changes ready for release, often with a manual production approval. Continuous Deployment automatically releases every change that passes the required checks.
3. What is a pipeline stage?
A stage is a major phase of a pipeline, such as Build, Test, Security, or Deploy. A stage may contain multiple jobs.
4. What is a runner or agent?
It is the execution environment that runs pipeline jobs. Different CI/CD platforms use different names for this component.
5. What is an artifact?
An artifact is a versioned output of a build, such as a package, application publish folder, container image, or deployment bundle.
6. Why should we build once and promote the same artifact?
It helps ensure that the exact package tested in earlier environments is the package promoted to production, reducing differences caused by rebuilding.
7. What is the difference between hosted and self-hosted runners?
Hosted runners are managed by the CI/CD provider. Self-hosted runners are operated by the organization, providing more control but adding security and maintenance responsibilities.
8. What is GitOps?
GitOps uses Git as the declared source of desired system state, with an automated controller reconciling the live environment to that state.
9. What is the difference between blue-green and canary deployment?
Blue-green switches traffic between two environments. Canary gradually exposes a new version to a smaller portion of traffic before wider rollout.
10. What is Infrastructure as Code?
IaC defines infrastructure using version-controlled configuration so that infrastructure can be reviewed, repeated, and automated.
11. How do you secure a CI/CD pipeline?
Use least privilege, protected environments, short-lived credentials, isolated runners, dependency and code scanning, reviewed pipeline configuration, artifact integrity controls, and audit logging.
12. What is the role of Docker in CI/CD?
Docker packages applications and dependencies into container images that can be built, scanned, stored, and deployed consistently.
13. What is the role of Kubernetes?
Kubernetes orchestrates containerized workloads. A delivery pipeline can deploy Kubernetes manifests or Helm charts and verify rollout health.
14. What is a rollback?
A rollback restores a previous known-good application version or configuration. Database changes and data transformations may require a separate recovery strategy.
15. Is CI/CD specific to Azure?
No. CI/CD can be implemented with GitHub Actions, GitLab CI/CD, Jenkins, Azure Pipelines, CircleCI, Bitbucket Pipelines, Buildkite, TeamCity, cloud-native services, and other automation platforms.
35. Official learning resources
Use official documentation for current syntax, supported versions, security options, and platform-specific setup. Features and product capabilities can change, so check the documentation for the version you are using.
- GitHub Actions documentation
- GitLab CI/CD documentation
- Jenkins Pipeline documentation
- Azure Pipelines documentation
- CircleCI documentation
- Bitbucket Pipelines documentation
- Docker build with CI documentation
- Kubernetes Deployments
- Argo CD documentation
- OpenTelemetry documentation
- OWASP DevSecOps Guideline
- SLSA framework
- DORA research and resources