0Pricing
Linux Command Line & Bash Scripting Mastery · Lekcja

Edycja plików konfiguracyjnych YAML za pomocą yq

Odczytuj i modyfikuj bezpośrednio pliki YAML Kubernetes i CI za pomocą yq, zachowując ich strukturę oraz komentarze.

Edycja plików konfiguracyjnych YAML za pomocą yq to bezpłatna lekcja Linux Command Line & Bash Scripting Mastery na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Linux Command Line & Bash Scripting Mastery, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Linux Command Line & Bash Scripting Mastery zawiera 4 lekcji w sumie.

Czym jest yq i dlaczego warto używać go do YAML?

yq to przenośny procesor YAML działający w wierszu poleceń, podobnie jak jq obsługuje JSON. Umożliwia odczytywanie, filtrowanie i edytowanie plików YAML bez pisania skryptu w Pythonie lub Ruby.

Istnieją dwa popularne narzędzia o nazwie yq:

  • mikefarah/yq (Go) — aktywnie rozwijane, obsługuje YAML, JSON, XML i TOML. W tej lekcji używana jest ta wersja.
  • kislyuk/yq (Python) — opakowanie jq dla YAML; składnia jest inna.

Zainstaluj wersję dla Go:

  • brew install yq w systemie macOS
  • snap install yq w systemie Linux
  • Lub pobierz plik binarny: wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq && chmod +x /usr/local/bin/yq

Sprawdź instalację: yq --version powinno wypisać v4.x.x. Wersja 4 używa innej składni wyrażeń niż wersja 3, dlatego wersja ma znaczenie.

# Install yq (Go version) on Linux
wget -q https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 \
  -O /usr/local/bin/yq
chmod +x /usr/local/bin/yq

# Confirm version
yq --version

Odczytywanie wartości z pliku YAML wdrożenia Kubernetes

Zanim zaczniesz cokolwiek edytować, naucz się odczytywać pola YAML. W przypadku wdrożenia Kubernetes możesz wyodrębnić dowolną zagnieżdżoną wartość za pomocą ścieżek w notacji kropkowej.

Przykładowy plik deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: production
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: app
          image: my-app:1.0.0

Najważniejsze polecenia odczytu:

  • yq '.metadata.name' deployment.yaml — wypisuje my-app
  • yq '.spec.replicas' deployment.yaml — wypisuje 3
  • yq '.spec.template.spec.containers[0].image' deployment.yaml — wypisuje my-app:1.0.0

Domyślnie wynik jest zwykłym tekstem (bez cudzysłowów). Dodaj flagę -r lub użyj | yq -r, jeśli potrzebujesz surowych ciągów znaków w skryptach.

# Create a sample deployment YAML
cat > /tmp/deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: production
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: app
          image: my-app:1.0.0
EOF

# Read individual fields
echo "App name:    $(yq '.metadata.name' /tmp/deployment.yaml)"
echo "Replicas:    $(yq '.spec.replicas' /tmp/deployment.yaml)"
echo "Image:       $(yq '.spec.template.spec.containers[0].image' /tmp/deployment.yaml)"

Edycja w miejscu za pomocą flagi -i

Najważniejszą flagą w praktycznych zastosowaniach jest -i (in-place, czyli edycja w miejscu). Bez niej yq wypisuje wyniki na stdout i pozostawia plik bez zmian.

Składnia:

  • Odczyt tylko do stdout: yq '.spec.replicas' file.yaml
  • Edycja w miejscu: yq -i '.spec.replicas = 5' file.yaml

Operator przypisania = ustawia wartość. Wyrażenie jest pełnym filtrem yq, dlatego w jednym przebiegu można połączyć odczyt i zapis.

Ważne: yq -i całkowicie przepisuje plik. Komentarze umieszczone w tym samym wierszu co pole są zazwyczaj zachowywane, ale samodzielne bloki komentarzy mogą zmienić położenie. Zawsze zatwierdzaj pliki YAML w systemie kontroli wersji przed wykonaniem masowych edycji w miejscu.

Najpierw przetestuj polecenie bez -i, a następnie dodaj tę flagę, gdy wynik będzie zgodny z oczekiwaniami.

# Start with the deployment from the previous scene
echo 'Before:' && yq '.spec.replicas' /tmp/deployment.yaml

# Edit in place: scale to 5 replicas
yq -i '.spec.replicas = 5' /tmp/deployment.yaml

echo 'After:' && yq '.spec.replicas' /tmp/deployment.yaml

Aktualizowanie tagu obrazu kontenera

Bardzo częstym zadaniem w CI jest zwiększenie tagu obrazu Docker w manifeście Kubernetes po zbudowaniu nowego obrazu. Dzięki yq można to zrobić jednym wierszem.

Wzorzec wygląda następująco:

  • Wybierz kontener po nazwie za pomocą select(), aby uniknąć sztywnego odwołania do indeksu 0 tablicy.
  • Użyj operatora aktualizacji |= lub =, aby ustawić nową wartość.

Użycie indeksu tablicy (podatne na błędy, jeśli lista kontenerów się zmieni):

  • yq -i '.spec.template.spec.containers[0].image = "my-app:2.1.0"' deployment.yaml

Użycie select() (odporne na zmiany):

  • yq -i '(.spec.template.spec.containers[] | select(.name == "app")).image = "my-app:2.1.0"' deployment.yaml

W potoku CI tag można przekazać jako zmienną powłoki:

NEW_TAG="my-app:2.1.0"
CONTAINER_NAME="app"

# Robust update: target by container name, not index
yq -i \
  "(.spec.template.spec.containers[] | select(.name == \"${CONTAINER_NAME}\")).image = \"${NEW_TAG}\"" \
  /tmp/deployment.yaml

# Verify
yq '.spec.template.spec.containers[0].image' /tmp/deployment.yaml

Dodawanie i usuwanie pól

Oprócz aktualizowania istniejących pól yq może dodawać nowe klucze i usuwać istniejące.

Dodawanie pola:

  • Po prostu przypisz wartość do nieistniejącej ścieżki: yq -i '.metadata.labels.version = "v2"' file.yaml
  • Jeśli brakuje klucza nadrzędnego (labels), yq utworzy go automatycznie.

Usuwanie pola:

  • Użyj funkcji del(): yq -i 'del(.metadata.annotations)' file.yaml
  • Usuń element tablicy po indeksie: yq -i 'del(.spec.template.spec.containers[1])' file.yaml

Dodawanie elementu do tablicy:

  • yq -i '.spec.template.spec.containers += [{"name": "sidecar", "image": "envoy:latest"}]' file.yaml
# Add a label to the deployment
yq -i '.metadata.labels.version = "v2"' /tmp/deployment.yaml
yq -i '.metadata.labels.managed-by = "ci-pipeline"' /tmp/deployment.yaml

echo '--- Labels after adding ---'
yq '.metadata.labels' /tmp/deployment.yaml

# Delete one label
yq -i 'del(.metadata.labels.managed-by)' /tmp/deployment.yaml

echo '--- Labels after delete ---'
yq '.metadata.labels' /tmp/deployment.yaml

Praca z wielodokumentowymi plikami YAML

Manifesty Kubernetes często zawierają wiele zasobów w jednym pliku, rozdzielonych za pomocą ---. Domyślnie yq przetwarza wszystkie dokumenty w takim pliku.

Najważniejsze techniki:

  • Wyświetlanie typów wszystkich dokumentów: yq '.[].kind' multi.yaml — zwróć uwagę na początkowe .[], które służy do iterowania po dokumentach.
  • Wybór konkretnego dokumentu według typu: yq 'select(.kind == "Service")' multi.yaml
  • Edycja w miejscu tylko pasujących dokumentów:

yq -i 'select(.kind == "Deployment").spec.replicas = 2' multi.yaml

Dokumenty, które nie spełniają predykatu select(), są przekazywane bez zmian, więc zasoby Service, ConfigMap i inne pozostają nienaruszone.

Aby podzielić plik wielodokumentowy na pojedyncze pliki, można iterować po wynikach yq lub użyć:

  • yq -s '.kind' multi.yaml — zapisuje osobny plik dla każdego dokumentu, nazwany zgodnie z wartością .kind.
cat > /tmp/multi.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
---
apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  port: 80
EOF

# Scale ONLY the Deployment, leave Service untouched
yq -i 'select(.kind == "Deployment").spec.replicas = 4' /tmp/multi.yaml

echo '--- Deployment replicas ---'
yq 'select(.kind == "Deployment").spec.replicas' /tmp/multi.yaml

echo '--- Service port (unchanged) ---'
yq 'select(.kind == "Service").spec.port' /tmp/multi.yaml

Modyfikowanie pliku YAML CI GitHub Actions

Pliki konfiguracji CI (.github/workflows/*.yml, .gitlab-ci.yml) również są zapisane w YAML. Te same polecenia yq działają także w ich przypadku, choć ścieżki mogą być głęboko zagnieżdżone.

Typowe zadania związane z modyfikowaniem CI:

  • Przypięcie wersji runnera: zaktualizuj runs-on we wszystkich zadaniach.
  • Aktualizacja wersji akcji: znajdź kroki używające konkretnej akcji i zwiększ wersję w jej polu uses.
  • Przełączanie flagi: włącz lub wyłącz ustawienie na poziomie workflow.

Przykład: aktualizacja wszystkich kroków używających actions/checkout do wersji v4:

yq -i '(.jobs[].steps[] | select(.uses == "actions/checkout@v3")).uses = "actions/checkout@v4"' .github/workflows/ci.yml

Ten idiom — iterowanie za pomocą [], zawężanie za pomocą select() i przypisywanie za pomocą = — jest podstawowym wzorcem każdej uporządkowanej edycji YAML.

cat > /tmp/ci.yml << 'EOF'
name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm test
  lint:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v3
      - run: npm run lint
EOF

# Bump all checkout steps from v3 → v4
yq -i '(.jobs[].steps[] | select(.uses == "actions/checkout@v3")).uses = "actions/checkout@v4"' \
  /tmp/ci.yml

# Verify both jobs were updated
yq '.jobs[].steps[] | select(.uses | test("checkout")).uses' /tmp/ci.yml

Używanie zmiennych środowiskowych w wyrażeniach yq

Wpisywanie wartości bezpośrednio w wyrażeniach yq sprawia, że skrypty są podatne na zmiany. yq umożliwia wstrzykiwanie zmiennych powłoki za pomocą funkcji env() lub skróconej formy strenv().

  • env(VAR_NAME) — odczytuje zmienną środowiskową i konwertuje ją na odpowiedni typ YAML (liczba pozostaje liczbą, a ciąg znaków pozostaje ciągiem znaków).
  • strenv(VAR_NAME) — zawsze zwraca ciąg znaków, dlatego jest przydatna w przypadku tagów obrazów.

Pozwala to uniknąć problemów z cudzysłowami podczas interpolowania zmiennych wewnątrz ujętych w podwójne cudzysłowy ciągów powłoki zawierających ścieżki YAML.

Wzorzec:

export IMAGE_TAG="my-app:3.0.0"
yq -i '.spec.template.spec.containers[0].image = strenv(IMAGE_TAG)' deployment.yaml

Używaj env() podczas ustawiania pól liczbowych, takich jak replicas, aby zachować typ YAML (liczba całkowita, a nie ciąg znaków w cudzysłowie).

export APP_IMAGE="my-app:3.0.0"
export REPLICA_COUNT=6

# Set image using strenv() — result is a YAML string
yq -i '.spec.template.spec.containers[0].image = strenv(APP_IMAGE)' \
  /tmp/deployment.yaml

# Set replicas using env() — result is a YAML integer
yq -i '.spec.replicas = env(REPLICA_COUNT)' \
  /tmp/deployment.yaml

# Confirm types are correct in the output
yq '.spec.replicas, .spec.template.spec.containers[0].image' /tmp/deployment.yaml

Scalanie dwóch plików YAML

Czasami trzeba zastosować plik poprawki (niewielki plik YAML z nadpisaniami) do bazowej konfiguracji — na przykład w przypadku nadpisań zależnych od środowiska w przepływach pracy w stylu Kustomize.

yq umożliwia scalanie dwóch plików za pomocą * operatora scalania:

  • yq '. *= load("patch.yaml")' base.yaml — scala poprawkę z bazą rekursywnie i zapisuje wynik na standardowe wyjście.
  • Dodanie -i aktualizuje bazę w miejscu: yq -i '. *= load("patch.yaml")' base.yaml

Zasady scalania:

  • Wartości skalarne w poprawce zastępują wartości w bazie.
  • Mapowania są scalane rekursywnie (klucze, których nie ma w poprawce, zostają zachowane).
  • Sekwencje (tablice) są domyślnie zastępowane, a nie dołączane. Aby je dołączać, należy użyć *+.

Ten wzorzec zastępuje podatne na błędy skrypty sed, które przestają działać po zmianach białych znaków.

cat > /tmp/base.yaml << 'EOF'
app:
  name: my-service
  port: 8080
  debug: false
database:
  host: localhost
  port: 5432
EOF

cat > /tmp/patch.yaml << 'EOF'
app:
  port: 9090
  debug: true
database:
  host: db.production.svc
EOF

# Deep-merge patch into base (stdout preview first)
yq '. *= load("/tmp/patch.yaml")' /tmp/base.yaml

# Apply in place
yq -i '. *= load("/tmp/patch.yaml")' /tmp/base.yaml

Weryfikowanie YAML i konwertowanie do JSON

Przed zastosowaniem poprawionego pliku YAML do klastra warto go zweryfikować i opcjonalnie przekonwertować do formatu JSON na potrzeby innych narzędzi.

Weryfikowanie składni:

  • yq '.' file.yaml && echo "Valid" — yq kończy działanie kodem 1 w przypadku błędów parsowania, dlatego sprawdza się to w bramkach CI.

Konwertowanie YAML do JSON:

  • yq -o=json '.' file.yaml — wyświetla sformatowany JSON.
  • Potok do jq umożliwia dalsze przetwarzanie JSON: yq -o=json '.' file.yaml | jq '.metadata.name'

Konwertowanie JSON do YAML:

  • yq -P '.' file.json — flaga -P wymusza wyjście w formacie YAML (prettyprint), gdy dane wejściowe są w formacie JSON.

Konwersje te sprawiają, że yq pełni funkcję pomostu między narzędziami natywnie obsługującymi YAML (Helm, kubectl) a narzędziami natywnie obsługującymi JSON (Terraform, AWS CLI, jq).

# Validate YAML (exits 0 on success, 1 on parse error)
if yq '.' /tmp/deployment.yaml > /dev/null 2>&1; then
  echo "YAML is valid"
else
  echo "YAML parse error!" >&2
  exit 1
fi

# Convert to JSON and query with jq
yq -o=json '.' /tmp/deployment.yaml \
  | jq '{name: .metadata.name, image: .spec.template.spec.containers[0].image}'

# Round-trip: JSON snippet back to YAML
echo '{"replicas": 7, "strategy": "RollingUpdate"}' \
  | yq -P '.'

Kompletny skrypt CI do stosowania poprawek wdrożenia

Połączmy wszystkie techniki: oto rzeczywisty skrypt CI, który stosuje poprawki do manifestu Kubernetes Deployment w ramach potoku GitOps.

Skrypt:

  1. Weryfikuje wejściowy plik YAML przed jego modyfikacją.
  2. Używa env() / strenv() do wszystkich podstawień zmiennych.
  3. Aktualizuje tag obrazu kontenera za pomocą funkcji select() wyszukującej po nazwie.
  4. Zwiększa liczbę replik.
  5. Dodaje adnotację deploy-time z bieżącym znacznikiem czasu.
  6. Ponownie weryfikuje dane wyjściowe przed zatwierdzeniem zmian.

Ten wzorzec gwarantuje, że nawet przy równoczesnym uruchomieniu potoku każdy krok jest atomowy i możliwy do prześledzenia.

#!/usr/bin/env bash
set -euo pipefail

MANIFEST="/tmp/deployment.yaml"
export NEW_IMAGE="my-app:$(date +%Y%m%d)-abc1234"
export NEW_REPLICAS=3
export DEPLOY_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
export CONTAINER="app"

# 1. Validate before patching
yq '.' "$MANIFEST" > /dev/null

# 2. Update image (by container name)
yq -i \
  '(.spec.template.spec.containers[] | select(.name == strenv(CONTAINER))).image = strenv(NEW_IMAGE)' \
  "$MANIFEST"

# 3. Set replicas
yq -i '.spec.replicas = env(NEW_REPLICAS)' "$MANIFEST"

# 4. Stamp annotation
yq -i '.metadata.annotations."deploy-time" = strenv(DEPLOY_TIME)' "$MANIFEST"

# 5. Validate result
yq '.' "$MANIFEST" > /dev/null && echo "Patch applied successfully"

# 6. Show diff summary
yq '{image: .spec.template.spec.containers[0].image, replicas: .spec.replicas}' "$MANIFEST"

Sprawdź wiedzę: bezpieczna edycja wielu dokumentów

Sprawdź swoją wiedzę na temat edytowania wielodokumentowych plików YAML Kubernetes za pomocą yq.

Podsumowanie lekcji: edytowanie YAML za pomocą yq

Ukończyli Państwo lekcję dotyczącą edytowania plików konfiguracyjnych YAML za pomocą yq. Oto krótkie podsumowanie wszystkich omówionych zagadnień:

  • Instalacja: Należy użyć pliku binarnego mikefarah/yq dla Go (v4). Wersję można sprawdzić za pomocą yq --version.
  • Odczyt: Ścieżki w notacji kropkowej, takie jak .spec.replicas; dostęp do tablic za pomocą [0] lub iteracji [].
  • Edycja w miejscu: Flaga -i przepisuje plik. Zawsze należy najpierw wyświetlić podgląd bez -i.
  • Odporne wyszukiwanie: Należy preferować select(.name == "app") zamiast sztywno zakodowanych indeksów tablicy.
  • Dodawanie / usuwanie: Przypisanie wartości do nowej ścieżki ją utworzy; do usuwania pól należy używać del().
  • Pliki wielodokumentowe: Należy użyć select(.kind == "..."), aby wybrać jeden zasób i pozostawić pozostałe bez zmian.
  • Zmienne CI: Należy używać strenv(VAR) dla ciągów znaków i env(VAR) dla wartości typowanych — pozwala to uniknąć błędów cytowania w powłoce.
  • Scalanie: . *= load("patch.yaml") scala plik z nadpisaniami rekursywnie, nie tracąc kluczy, których nie obejmuje poprawka.
  • Weryfikacja i konwersja: yq '.' jako bramka lintowania; -o=json i -P do konwersji formatu.

Podstawowy wzorzec każdej poprawki YAML w CI to: weryfikacja → wybór → przypisanie → weryfikacja. Połączenie tego z strenv() i select() sprawi, że nie będą już Państwo musieli sięgać po podatne na błędy jednolinijkowe skrypty sed.

Często zadawane pytania

Czy lekcja „Edycja plików konfiguracyjnych YAML za pomocą yq” jest bezpłatna?

Tak — pełny tekst „Edycja plików konfiguracyjnych YAML za pomocą yq” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Linux Command Line & Bash Scripting Mastery, przejdź na CoddyKit PRO. Kurs Linux Command Line & Bash Scripting Mastery zawiera 4 lekcji w sumie.

Co nauczysz się w „Edycja plików konfiguracyjnych YAML za pomocą yq”?

Odczytuj i modyfikuj bezpośrednio pliki YAML Kubernetes i CI za pomocą yq, zachowując ich strukturę oraz komentarze. Ćwiczysz Linux Command Line & Bash Scripting Mastery z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Linux Command Line & Bash Scripting Mastery?

Nie wymagamy żadnego doświadczenia. Linux Command Line & Bash Scripting Mastery w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Edycja plików konfiguracyjnych YAML za pomocą yq”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Linux Command Line & Bash Scripting Mastery?

Tak. Każda lekcja Linux Command Line & Bash Scripting Mastery zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Filtrowanie i wybieranie JSON za pomocą potoków jq
  2. Przekształcanie i tworzenie obiektów JSON za pomocą jq
  3. Korzystanie z REST API za pomocą curl i jq
  4. Edycja plików konfiguracyjnych YAML za pomocą yq
← Powrót do Linux Command Line & Bash Scripting Mastery