agentsclimarketplace

Nginx to traefik

Skill qwedsazxc78/devops-ai-skill/skills/nginx-to-traefik

⚡ Cross-platform DevOps AI Skill Pack — Horus (IaC) + Zeus (GitOps) agents, ingress→Gateway migration & architecture-diagram painter for Claude Code, Codex CLI, Gemini CLI & Antigravity

Install
npx -y skills add qwedsazxc78/devops-ai-skill --skill nginx-to-traefik

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 9 stars9 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Class-swap migration that ports services from NGINX Ingress to Traefik Ingress (`ingressClassName: traefik`) while keeping both controllers running in parallel. DNS A-records are the only cutover lever. Designed for eye-of-horus-gitops conventions: nginx files move to archive/ (never deleted), Traefik Ingresses live in kustomization.resources (never patches), backend Service names and secretName are written verbatim (Kustomize namePrefix does not touch them). Operator-declared LB IPs only — never auto-derived from cluster state. State stored in docs/reports/nginx-to-traefik/<slug>/.

SKILL.md

8.6 KB, as published. Nobody here has run it

nginx-to-traefik Skill

Invoked by Zeus pipeline *nginx-to-traefik.

This skill is the first half of the chained migration NGINX → Traefik Ingress → Gateway API. Used standalone it ports a batch of services to Traefik while leaving the NGINX controller serving everyone else. Used under skill nginx-to-gateway (the orchestrator), its state.yaml output is consumed as the input to skill gateway-api-migration with --source-class traefik.

Canonical references

FileWhen to read
references/nginx-to-traefik-env-config.mdStep 0b — env-config schema and operator prompts
references/annotation-translation.mdStep 3 — annotation mapping
references/dns-cutover-runbook.mdStep 10 — printed/linked at end of run

Bundled scripts

ScriptUsed byPurpose
scripts/inventory_nginx_ingresses.pyStep 1Per-overlay nginx Ingress inventory
scripts/generate_traefik_ingress.pyStep 3Emit <service>-traefik-ingress.yaml
scripts/update_kustomization.pyStep 5, 6Idempotent edits to kustomization.yaml + app.ingress.yaml
scripts/validate_cross_consistency.shStep 7b4-way DNS↔verify↔ingress↔cert cross-check

Activation

Triggered explicitly by *nginx-to-traefik from Zeus. Not auto-triggered.

Invocation forms

*nginx-to-traefik                              # interactive: inventory + propose batches
*nginx-to-traefik <env>                        # process all services in one env
*nginx-to-traefik <env> <batch>                # named batch (b1 | b2)
*nginx-to-traefik <env> <service>              # single service
*nginx-to-traefik --resume                     # continue from state.yaml

Step Flow

StepActionScript
0Tool check (kustomize, yq, git)inline command -v
0bLoad references/nginx-to-traefik-env-config.md; prompt operator for Traefik + nginx LB IPs if missing, write to config, then continueinline
1Inventory active nginx ingresses per envinventory_nginx_ingresses.py
2Propose batch plan, wait for y/N confirmationinline
3Generate <service>-traefik-ingress.yaml per servicegenerate_traefik_ingress.py
4git mv nginx file to archive/inline
5Edit kustomization.yaml: add Traefik file to resources:, drop nginx from patches:update_kustomization.py
6Update common.traefik/overlays/<env>/app.ingress.yaml managed-cert host listupdate_kustomization.py
7kustomize build both modules for the envinline
7b4-way consistency checkvalidate_cross_consistency.sh
8Update scripts/dns-create-traefik.sh batch listinline
9Update scripts/verify-traefik-<env>.sh URL listinline
10Print commit message + file list (never auto-commit)inline

Step 0 — Tool check

Run command -v kustomize yq git. HALT on any missing.

Step 0b — Env-config

Read references/nginx-to-traefik-env-config.md. If state.yaml.envConfig is missing entries for the target env, issue the 5 prompts listed in the reference and write the captured values back. Never derive LB IPs from any cluster resource — this is invariant §5.3 from the spec.

Step 1 — Inventory

Invoke inventory_nginx_ingresses.py --overlay-dir <common.service/overlays/<env>>. Filter to ingressClass == "nginx". Write to state.yaml.inventory[]. HALT if zero nginx ingresses found.

Step 2 — Batch plan

Group inventory entries by host TLD + service criticality. Default batches: b1 = read-mostly services, b2 = write-heavy services. Print the proposed batch plan and ask y/N. HALT on decline.

Step 3 — Generate Traefik Ingress per service

For each service in the active batch, invoke generate_traefik_ingress.py --input <service>-nginx-ingress.yaml --output <service>-traefik-ingress.yaml. Capture stderr WARN lines into state.yaml.warnings[]. Compute SHA256 of each output for state.yaml.outputs.traefikIngresses[].sha256.

Step 4 — Archive nginx file

git mv <service>-nginx-ingress.yaml archive/. HALT if the file is already under archive/. Backup the pre-edit path in state.yaml.backups[].

Step 5 — Kustomization resource edit

update_kustomization.py --overlay-dir <overlay> \
  --replace <service>-nginx-ingress.yaml=<service>-traefik-ingress.yaml \
  --drop-patch <service>-nginx-ingress.yaml

The script is idempotent: re-running step 5 on a complete state is a no-op.

Step 6 — Managed-cert host list

For each new Traefik Ingress, ensure its primary host is present in common.traefik/overlays/<env>/app.ingress.yaml.spec.tls[].hosts and spec.rules[].host. Use update_kustomization.py --app-ingress <path> --add-host <host>.

Step 7 — kustomize build

kustomize build common.service/overlays/<env> > /tmp/svc-build.yaml
kustomize build common.traefik/overlays/<env> > /tmp/traefik-build.yaml

HALT on non-zero exit. Roll back step 4–6 via git restore of backed-up files.

Step 7b — Cross-consistency check

Invoke validate_cross_consistency.sh with the four host sources. HALT on non-zero exit. The stderr stale-host list goes into the report.

Step 8 — DNS script update

Locate scripts/dns-create-traefik.sh. Find or create the array HOSTS_<ENV_UPPER>_<BATCH_UPPER>=(...). Insert each new host (idempotent via grep -q before append). Record the diff in state.yaml.steps["8"].

Step 9 — Verify script update

Same pattern as Step 8 but URLS_<ENV>_<BATCH> in scripts/verify-traefik-<env>.sh. URL format: https://<host>/.

Step 10 — Print commit message and file list

Never auto-commit. Print:

  1. The full set of files touched (Step 3 outputs + Step 4 moves + Step 5/6 edits + Step 8/9 edits).
  2. A suggested commit message in Conventional Commits zh-TW style.
  3. A pointer to references/dns-cutover-runbook.md for the operator to follow after the commit lands.

State file (state.yaml)

The state file lives at docs/reports/nginx-to-traefik/<slug>/state.yaml where <slug> is <env>-<batch>-<isodate>. Schema:

schemaVersion: 1
skillVersion: "1.0.0"
env: dev
batch: b1
createdAt: 2026-05-14T10:00:00Z
envConfig:
  capturedAt: <iso>
  envs:
    dev: { nginxLbIp: ..., traefikLbIp: ..., certIssuer: ..., managedCertNamespace: ..., managedCertResourceName: ... }
inventory:
  - { file: argocd-nginx-ingress.yaml, name: argocd-server, namespace: argocd, hosts: [argocd.dev.example.com] }
batchPlan:
  b1: [argocd-server, grafana]
outputs:
  traefikIngresses:
    - { file: argocd-traefik-ingress.yaml, host: argocd.dev.example.com, namespace: argocd, backend: argocd-server, port: 80, sha256: <hex> }
backups:
  - { path: argocd-nginx-ingress.yaml, restorePath: archive/argocd-nginx-ingress.yaml }
steps:
  "0":  { status: pass }
  "0b": { status: pass, prompts: 0 }
  "1":  { status: pass, count: 2 }
  "2":  { status: pass, confirmed: true }
  "3":  { status: pass, generated: 2, warnings: 0 }
  "4":  { status: pass, moved: 2 }
  "5":  { status: pass, edits: 2 }
  "6":  { status: pass, hostsAdded: 2 }
  "7":  { status: pass }
  "7b": { status: pass, staleHosts: [] }
  "8":  { status: pass, hostsAdded: 2 }
  "9":  { status: pass, urlsAdded: 2 }
  "10": { status: pass }
warnings: []
verdict: COMPLETE

The outputs.traefikIngresses[] list is the hand-off contract for skill C (nginx-to-gateway): when chained, skill C reads this list and passes --source-class traefik --source-state <statePath> to skill B.

Halt conditions

StepHalt cause
0Required tool missing
0bOperator declines to supply env-config values
1Zero nginx Ingresses found
2Operator declines batch plan
3generate_traefik_ingress.py exit code != 0
4File already under archive/
5kustomization.yaml schema mismatch
7kustomize build non-zero
7bCross-consistency check non-zero

After halt, the skill writes state.yaml.verdict: HALTED with the failing step. --resume re-runs from the failed step.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.