0Pricing
Linux Command Line & Bash Scripting Mastery · Aula

Edição de arquivos de configuração YAML com yq

Leia e altere YAML do Kubernetes e da integração contínua no próprio local usando yq, preservando a estrutura e os comentários.

Edição de arquivos de configuração YAML com yq é uma aula grátis de Linux Command Line & Bash Scripting Mastery no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Linux Command Line & Bash Scripting Mastery, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.

O que é yq e por que usá-lo para YAML

yq é um processador portátil de YAML para a linha de comando, semelhante à forma como o jq processa JSON. Ele permite ler, filtrar e editar arquivos YAML sem escrever um script em Python ou Ruby.

Há duas ferramentas populares chamadas yq:

  • mikefarah/yq (Go) — mantida ativamente, oferece suporte a YAML, JSON, XML e TOML. Esta lição usa essa versão.
  • kislyuk/yq (Python) — um adaptador de jq para YAML; a sintaxe é diferente.

Instale a versão em Go:

  • brew install yq no macOS
  • snap install yq no Linux
  • Ou baixe o binário: wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq && chmod +x /usr/local/bin/yq

Verifique: yq --version deve exibir v4.x.x. A versão 4 usa uma sintaxe de expressões diferente da v3, portanto a versão é importante.

# 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

Lendo valores de um YAML de implantação do Kubernetes

Antes de editar qualquer coisa, aprenda a ler campos YAML. Dada uma implantação do Kubernetes, você pode extrair qualquer valor aninhado usando caminhos com notação de pontos.

Exemplo de 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

Principais comandos de leitura:

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

A saída é texto simples por padrão (sem aspas). Adicione a opção -r ou use | yq -r se precisar de strings brutas em scripts.

# 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)"

Editando no próprio arquivo com a opção -i

A opção mais importante para uso no mundo real é -i (no próprio arquivo). Sem ela, yq exibe os resultados na saída padrão e deixa o arquivo inalterado.

Sintaxe:

  • Somente leitura (saída padrão): yq '.spec.replicas' file.yaml
  • Edição no próprio arquivo: yq -i '.spec.replicas = 5' file.yaml

O operador de atribuição = define um valor. A expressão é um filtro yq completo, portanto você pode combinar leitura e gravação em uma única passagem.

Importante: yq -i reescreve o arquivo inteiro. Comentários colocados na mesma linha que um campo geralmente são preservados, mas blocos de comentários independentes podem mudar de lugar. Sempre faça commit do YAML no controle de versão antes de executar edições em massa no próprio arquivo.

Teste primeiro sem -i e adicione-o quando estiver satisfeito com a saída.

# 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

Atualizando a tag da imagem do contêiner

Uma tarefa muito comum de CI é atualizar a tag da imagem Docker em um manifesto do Kubernetes depois que uma nova imagem é criada. Com yq, isso se resume a uma única linha.

O padrão é:

  • Identifique o contêiner pelo nome usando select(), para evitar fixar o índice 0 da matriz.
  • Use |= (operador de atualização) ou = para definir o novo valor.

Usando o índice da matriz (frágil se a lista de contêineres mudar):

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

Usando select() (robusto):

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

Em um pipeline de CI, você passaria a tag como uma variável do shell:

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

Adicionando e removendo campos

Além de atualizar campos existentes, yq pode adicionar novas chaves ou excluir as existentes.

Adicionando um campo:

  • Basta atribuir um valor a um caminho que não existe: yq -i '.metadata.labels.version = "v2"' file.yaml
  • Se a chave pai (labels) estiver ausente, yq a criará automaticamente.

Excluindo um campo:

  • Use a função del(): yq -i 'del(.metadata.annotations)' file.yaml
  • Exclua um elemento da matriz pelo índice: yq -i 'del(.spec.template.spec.containers[1])' file.yaml

Adicionando um elemento a uma matriz:

  • 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

Trabalhando com arquivos YAML de vários documentos

Os manifestos do Kubernetes geralmente agrupam vários recursos em um único arquivo, separados por ---. Por padrão, yq processa todos os documentos desse arquivo.

Principais técnicas:

  • Liste todos os tipos de documento: yq '.[].kind' multi.yaml — observe o .[] inicial para iterar pelos documentos.
  • Selecione um documento específico pelo tipo: yq 'select(.kind == "Service")' multi.yaml
  • Edite no próprio arquivo apenas os documentos correspondentes:

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

Os documentos que não correspondem ao predicado de select() são repassados sem alterações, portanto o Service, o ConfigMap e os outros recursos permanecem intactos.

Para dividir um arquivo com vários documentos em arquivos individuais, você pode percorrer a saída do yq ou usar:

  • yq -s '.kind' multi.yaml — grava um arquivo por documento, usando como nome o valor de .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

Aplicando correções a um YAML de CI do GitHub Actions

Arquivos de configuração de CI (.github/workflows/*.yml, .gitlab-ci.yml) também são YAML. Os mesmos comandos do yq funcionam, embora os caminhos possam ser profundamente aninhados.

Tarefas comuns de correção de CI:

  • Fixar uma versão do executor: atualize runs-on em todos os trabalhos.
  • Atualizar a versão de uma ação: encontre as etapas que usam uma ação específica e atualize o campo uses.
  • Alternar uma opção: ative ou desative uma configuração no nível do fluxo de trabalho.

Exemplo: atualizar para v4 todas as etapas que usam actions/checkout:

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

Este padrão — iterar com [], restringir com select() e atribuir com = — é a base para qualquer edição de YAML estruturado.

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

Usando variáveis de ambiente em expressões do yq

Codificar valores diretamente nas expressões do yq torna os scripts frágeis. O yq permite injetar variáveis do shell usando a função env() ou a forma abreviada strenv().

  • env(VAR_NAME) — lê a variável de ambiente e a converte para o tipo YAML apropriado (um número continua sendo número e uma string continua sendo string).
  • strenv(VAR_NAME) — sempre retorna uma string, sendo útil para tags de imagens.

Isso evita o pesadelo das aspas ao interpolar variáveis em strings do shell entre aspas duplas que contêm caminhos YAML.

Padrão:

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

Use env() ao definir campos numéricos, como replicas, para preservar o tipo YAML (inteiro, não uma string entre aspas).

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

Mesclando dois arquivos YAML

Às vezes, é necessário aplicar um arquivo de patch (uma pequena substituição em YAML) a uma configuração base — por exemplo, para substituições específicas de cada ambiente em fluxos de trabalho no estilo do Kustomize.

O yq pode mesclar dois arquivos usando o * operador de mesclagem:

  • yq '. *= load("patch.yaml")' base.yaml — faz uma mesclagem profunda do patch na base e grava na saída padrão.
  • Adicione -i para atualizar a base no próprio arquivo: yq -i '. *= load("patch.yaml")' base.yaml

Comportamento da mesclagem:

  • Os valores escalares do patch sobrescrevem os da base.
  • Os mapeamentos passam por uma mesclagem profunda (as chaves que não estão no patch são preservadas).
  • As sequências (matrizes) são substituídas por padrão, e não anexadas. Use *+ para anexá-las.

Esse padrão substitui programas frágeis em sed que quebram quando há alterações nos espaços em branco.

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

Validando YAML e convertendo para JSON

Antes de aplicar um YAML corrigido a um cluster, é uma boa prática validá-lo e, opcionalmente, convertê-lo para JSON para uso com outras ferramentas.

Validar a sintaxe:

  • yq '.' file.yaml && echo "Valid" — o yq sai com o código 1 em caso de erros de análise, portanto isso funciona em verificações de CI.

Converter YAML para JSON:

  • yq -o=json '.' file.yaml — gera JSON formatado.
  • Encadeie com jq para continuar processando o JSON: yq -o=json '.' file.yaml | jq '.metadata.name'

Converter JSON para YAML:

  • yq -P '.' file.json — o sinalizador -P força a saída em YAML (com formatação) quando a entrada está em JSON.

Essas conversões tornam o yq uma ponte entre ferramentas nativas de YAML (Helm, kubectl) e ferramentas nativas de 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 '.'

Um programa completo de patch de implantação de CI

Reunindo todas as técnicas: um programa real de CI que aplica patches a um manifesto de implantação do Kubernetes como parte de um pipeline de GitOps.

O programa:

  1. Valida o YAML de entrada antes de alterá-lo.
  2. Usa env() / strenv() para todas as substituições de variáveis.
  3. Atualiza a tag da imagem do contêiner usando um select() baseado no nome.
  4. Aumenta a quantidade de réplicas.
  5. Registra uma anotação deploy-time com o carimbo de data e hora atual.
  6. Valida novamente a saída antes de confirmar as alterações.

Esse padrão garante que, mesmo quando o pipeline é executado simultaneamente, cada etapa seja atômica e possa ser auditada.

#!/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"

Verificação de conhecimento: edição segura de vários documentos

Teste sua compreensão sobre a edição de arquivos YAML do Kubernetes com vários documentos usando o yq.

Recapitulação da lição: editando YAML com yq

Você concluiu a lição sobre edição de arquivos de configuração YAML com yq. Veja um resumo conciso de tudo o que foi abordado:

  • Instalação: Use o binário Go do mikefarah/yq (v4). Verifique com yq --version.
  • Leitura: Caminhos na notação de ponto, como .spec.replicas; acesso a matrizes com [0] ou iteração com [].
  • Edição no próprio arquivo: O sinalizador -i reescreve o arquivo. Sempre faça uma prévia sem -i primeiro.
  • Direcionamento robusto: Prefira select(.name == "app") a índices de matriz codificados diretamente.
  • Adição / exclusão: Atribua a um novo caminho para criá-lo; use del() para remover campos.
  • Arquivos com vários documentos: Use select(.kind == "...") para direcionar um recurso e deixar os demais intactos.
  • Variáveis de CI: Use strenv(VAR) para strings e env(VAR) para valores tipados — isso evita problemas de aspas do shell.
  • Mesclagem: . *= load("patch.yaml") faz uma mesclagem profunda de um arquivo de substituição sem perder as chaves que não estão no patch.
  • Validação e conversão: use yq '.' como verificação de lint; use -o=json e -P para conversão de formato.

O padrão central para qualquer patch YAML em CI é: validar → selecionar → atribuir → validar. Combine isso com strenv() e select() e você nunca mais precisará recorrer a comandos frágeis de uma linha em sed.

Perguntas Frequentes

A aula “Edição de arquivos de configuração YAML com yq” é grátis?

Sim — o texto completo de “Edição de arquivos de configuração YAML com yq” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Linux Command Line & Bash Scripting Mastery, atualize para CoddyKit PRO. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.

O que vou aprender em “Edição de arquivos de configuração YAML com yq”?

Leia e altere YAML do Kubernetes e da integração contínua no próprio local usando yq, preservando a estrutura e os comentários. Você pratica Linux Command Line & Bash Scripting Mastery com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Linux Command Line & Bash Scripting Mastery?

Nenhuma experiência prévia é necessária. Linux Command Line & Bash Scripting Mastery no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Edição de arquivos de configuração YAML com yq”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Linux Command Line & Bash Scripting Mastery?

Sim. Cada aula de Linux Command Line & Bash Scripting Mastery inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Filtragem e seleção de JSON com pipelines do jq
  2. Transformação e criação de objetos JSON com jq
  3. Consumo conjunto de APIs REST com curl e jq
  4. Edição de arquivos de configuração YAML com yq
← Voltar para Linux Command Line & Bash Scripting Mastery