Git for Engineers — Level by Level›07 · Repositories for infrastructure and GitOps

Lesson 07 of 8 · Level 3 — Git for platforms

Repositories for infrastructure and GitOps

Repositories that hold infrastructure and GitOps configuration need extra care: how to split them, route reviews with CODEOWNERS, catch problems before commit with pre-commit hooks, keep secrets out with scanning, sign commits, and clean up properly when a secret slips through.

Practitioner → Advanced
Key wordsmonorepopolyrepoCODEOWNERSpre-commitgit hooksgitleakssecret scanningsigned commitsSSH signingcommit verificationgit filter-repo

Mono repo or many repos?

Monorepo (one repo for many services or all infrastructure) Polyrepo (one repo per service/component)
Strengths Atomic changes across components, one set of tooling, easy search Clear ownership, independent access control, small and fast
Costs Needs path-based CI, CODEOWNERS and good tooling as it grows Cross-repo changes need coordination; tooling duplicated

For platforms, a common split: application source in per-service repositories; infrastructure (Terraform) in one or a few repositories by layer or team; GitOps configuration (what runs where) in a dedicated config repository. "GitOps Principles & Practice", lesson 02, goes deeper.

A shared family calendar (one repo) makes it easy to see everything at once, but everyone needs to agree on the rules. Separate diaries (many repos) give privacy and freedom, but planning a family holiday means comparing them all.

CODEOWNERS: the right reviewers, automatically

# .github/CODEOWNERS (GitLab: CODEOWNERS with the same syntax, Gitea: similar)
*                         @acme/platform-team
/terraform/network/       @acme/network-team
/environments/prod/       @acme/platform-leads
/apps/payments/           @acme/payments-team

With branch protection requiring code-owner approval, a change to environments/prod/ can't merge without a platform lead. The file itself should be owned by the platform team.

pre-commit: catch it before it's committed

# .pre-commit-config.yaml (pin rev to versions you tested)
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
        args: [--allow-multiple-documents]
      - id: check-merge-conflict
      - id: detect-private-key
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.24.0
    hooks:
      - id: gitleaks
  - repo: https://github.com/antonbabenko/pre-commit-terraform
    rev: v1.99.0
    hooks:
      - id: terraform_fmt
      - id: terraform_validate
$ pre-commit install              # hooks now run on every git commit in this clone
$ pre-commit run --all-files      # run everything once

Run the same checks in CI (hooks can be skipped with --no-verify; CI can't).

Keep secrets out of Git

  • Never commit secrets, even to private repositories: private repos get cloned, forked, mirrored and backed up.
  • Use a secret store (Vault, AWS Secrets Manager) or encrypted-in-Git formats built for it (SOPS, Sealed Secrets: see "GitOps Principles & Practice", lesson 04).
  • Scan with gitleaks in pre-commit and CI; enable your Git server's secret scanning and push protection where available.

When a secret leaks anyway:

  1. Rotate/revoke it now. This is the only step that actually removes the risk.
  2. Check where it could have been used (cloud audit logs, access logs).
  3. Remove it from history if required: git filter-repo --path <file> --invert-paths (or --replace-text), force-push, and ask everyone to re-clone. Coordinate this; it rewrites every later commit.
  4. Add the pattern to the scanner so it can't happen the same way again.

Signed commits

Signing proves a commit came from the holder of a key, which matters for repositories that control production (GitOps configuration, Terraform):

$ git config --global gpg.format ssh
$ git config --global user.signingkey ~/.ssh/id_ed25519.pub
$ git config --global commit.gpgsign true
$ git config --global tag.gpgsign true

Upload the same key as a signing key on the Git server; commits then show as verified, and branch protection can require signatures.

Try it: guard a repository

  1. Add the .pre-commit-config.yaml above to a test repo (adjust versions), run pre-commit install and pre-commit run --all-files.
  2. Try committing a file containing a fake AWS key pattern; watch gitleaks block it.
  3. Add a CODEOWNERS file and require code-owner review on main; open a PR touching an owned path.
  4. Turn on SSH commit signing and check git log --show-signature -1.

Recap

  • Split app source, infrastructure and GitOps config sensibly; monorepo vs polyrepo is about ownership and tooling.
  • CODEOWNERS + branch protection = the right reviewers, enforced.
  • pre-commit locally and the same checks in CI; gitleaks for secrets.
  • Leaked secret: rotate first, then clean history with git filter-repo.
  • Sign commits for repositories that change production.

This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.