← All TILs · devops

DevOps and DevSecOps terminology: DORA metrics, CI/CD for Ansible, feature branches and GitOps

devops - 2026-10-24

A glossary-style entry for the words that come up as soon as infrastructure code goes through a pipeline: what DevOps and DevSecOps mean and how they differ, how the DORA metrics measure delivery, what CI/CD looks like when the code is an Ansible playbook, how a feature-branch workflow keeps main deployable, and where GitOps fits.

DevOps

DevOps is a way of organising software delivery in which the people who write a change (development) and the people who run it in production (operations) share one goal and one workflow, instead of handing work over a wall. It is a set of practices and a culture, not a tool or a job title. The practices most often named are:

The loop is usually drawn as an infinity sign; as a cycle:

flowchart LR
    Plan --> Code --> Build --> Test --> Release --> Deploy --> Operate --> Monitor --> Plan

DevSecOps

DevSecOps adds security to the same loop. In a classic process, security reviews a finished release just before it ships, when a finding is expensive to fix. DevSecOps moves the checks earlier ("shift left") and automates them, so they run on every change like the tests do. Security becomes a shared responsibility rather than a final gate owned by another team.

Typical automated checks, and where they run:

Check What it looks for Example for IaC
Secret scanning passwords, tokens or keys committed to Git gitleaks, GitHub secret scanning
SAST (static application security testing) dangerous patterns in source code, without running it KICS or checkov on playbooks and Terraform
SCA (software composition analysis) dependencies with known vulnerabilities collections and Python packages in an execution environment
Image scanning vulnerable packages in a container image trivy on the image a job runs in
DAST (dynamic application security testing) weaknesses in the running application tests against a staging deployment
Policy as code rules a change must respect, written as code Open Policy Agent, ansible-lint profiles
flowchart LR
    Plan["Plan<br/>threat model"] --> Code["Code<br/>pre-commit secret scan"]
    Code --> Build["Build<br/>SAST, SCA"]
    Build --> Test["Test<br/>image scan, DAST"]
    Test --> Deploy["Deploy<br/>policy checks, signed artefacts"]
    Deploy --> Operate["Operate<br/>audit logs, patching"]
    Operate --> Plan

DevOps and DevSecOps compared

DevOps DevSecOps
Goal deliver changes fast and reliably the same, with security built in
Who owns security often a separate team at the end everyone, from the first commit
When security is checked before release, manually on every change, automatically
Pipeline build, test, deploy build, test, scan, deploy
Typical failure it prevents a broken deployment a broken deployment, a leaked secret, a vulnerable dependency

DevSecOps is not a separate method: it is DevOps in which security checks are part of "done".

DORA metrics

DORA (DevOps Research and Assessment) is a research programme run by Google Cloud that surveys thousands of teams every year for its Accelerate State of DevOps report. It found that a few measurements predict how well a team delivers software. It started with four, the "four keys", and since the 2024 report it uses five, in two groups (DORA's software delivery performance metrics):

Group Metric DORA's definition
Throughput Change lead time "The amount of time it takes for a change to go from committed to version control to deployed in production."
Throughput Deployment frequency "The number of deployments over a given period or the time between deployments."
Throughput Failed deployment recovery time "The time it takes to recover from a deployment that fails and requires immediate intervention."
Instability Change fail rate "The ratio of deployments that require immediate intervention following a deployment."
Instability Deployment rework rate "The ratio of deployments that are unplanned but happen as a result of an incident in production."

The metrics changed over time (history of DORA's metrics): failed deployment recovery time replaced mean time to restore (MTTR) in the 2023 report, which narrowed it to failures caused by a change to production, and rework rate was added as the fifth metric in 2024, when recovery time also moved from the stability group to throughput.

Speed and the failure metrics are measured together, so that deploying more often only counts as progress if failures don't rise. DORA reports that they are not a trade-off: "speed and stability are not tradeoffs. In fact, we see that the metrics are correlated for most teams. Top performers do well across all five metrics, and low performers do poorly."

For an Ansible repository, the metrics map to things a pipeline already records: merges to main that ran the deploy job (frequency), the time between the first commit of a merge request and its deploy job (lead time), deploy jobs followed by a revert or a fix (change fail rate), unplanned deploys made to fix an incident (rework rate), and the time until the next successful deploy (recovery).

CI/CD applied to IaC: Ansible as an example

With application code, CI builds and tests a binary. With Ansible, there is nothing to compile, so CI checks the playbooks and tests them against throwaway hosts:

flowchart TD
    Push["git push on a feature branch"] --> Lint["Lint<br/>yamllint, ansible-lint"]
    Lint --> Secrets["Secret scan<br/>gitleaks"]
    Secrets --> Syntax["ansible-playbook --syntax-check"]
    Syntax --> Molecule["Molecule<br/>converge a container, run again for idempotence, verify"]
    Molecule --> MR{"Merge request<br/>review and approval"}
    MR -->|merged to main| Check["Dry run on staging<br/>--check --diff"]
    Check --> Staging["Deploy to staging"]
    Staging --> Approve{"Manual approval"}
    Approve --> Prod["Deploy to production"]

What each step brings:

A minimal GitLab CI file with those stages:

stages: [lint, test, deploy]

default:
  image: registry.example.com/ansible-ee:1.4.0

lint:
  stage: lint
  script:
    - yamllint .
    - ansible-lint

molecule:
  stage: test
  script:
    - molecule test

deploy_staging:
  stage: deploy
  script:
    - ansible-playbook -i inventories/staging site.yml
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

deploy_production:
  stage: deploy
  script:
    - ansible-playbook -i inventories/production site.yml
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual

The feature-branch workflow

In a feature-branch workflow, main always holds code that can be deployed, and nobody commits to it directly. Each change is made on its own short-lived branch, checked by CI, reviewed in a merge request (a pull request on GitHub), and merged only when both pass.

gitGraph
    commit id: "release 1.2"
    branch feature/ntp-role
    checkout feature/ntp-role
    commit id: "add ntp role"
    commit id: "fix lint"
    checkout main
    branch feature/sshd-hardening
    checkout feature/sshd-hardening
    commit id: "harden sshd"
    checkout main
    merge feature/ntp-role id: "MR !12 merged"
    checkout feature/sshd-hardening
    merge main id: "update from main"
    checkout main
    merge feature/sshd-hardening id: "MR !13 merged"
    commit id: "release 1.3"

The workflow is sometimes sold under names such as a "no-rework architecture"; that isn't a standard term, but it describes the aim: catch a problem on the branch, before the merge, so that nothing has to be redone on main. What makes that work:

It connects back to DORA: changes that are caught on the branch never count as failed deployments (change fail rate, rework rate), and small branches reach production sooner (lead time).

Trunk-based development takes the same idea further: branches last hours rather than days, and unfinished work is hidden behind feature flags instead of kept on a branch. Git flow goes the other way, with long-lived develop and release branches; it suits software shipped in versions more than infrastructure deployed continuously.

GitOps

GitOps uses a Git repository as the single source of truth for the desired state of a system, and lets software agents apply it. The OpenGitOps project defines four principles: the desired state is declarative, versioned and immutable, pulled automatically by an agent, and continuously reconciled with the actual state.

The difference with a CI/CD pipeline is the direction and the timing:

flowchart LR
    subgraph Push["Push model: CI/CD"]
        direction LR
        G1[(Git)] -->|merge triggers| P1[Pipeline] -->|applies once| T1[Servers]
    end
    subgraph Pull["Pull model: GitOps"]
        direction LR
        G2[(Git)] -->|watched by| A2[Agent in the target] -->|reconciles continuously| T2[Cluster]
        T2 -->|drift detected| A2
    end

Ansible and OpenTofu are push tools, so a pipeline that runs them meets only some of the principles. The GitOps with push tools entry compares them principle by principle.

Other terms that come with these

Created 2026-10-24T04:13:26+02:00 · Edit