Dominando el Filtrado de Salida de la CLI de AWS con JQ: Técnicas Avanzadas
Usa jq con la salida JSON de AWS CLI para filtrar, remodelar y exportar datos de la nube para scripts e informes.
Dominando el Filtrado de Salida de AWS CLI con JQ: Técnicas Avanzadas
El filtrado de salida de AWS CLI se vuelve complicado cuando un comando devuelve JSON profundamente anidado. Puede que solo necesites un ID de instancia, un valor de etiqueta o un informe CSV corto, pero comandos como aws ec2 describe-instances devuelven muchos más datos que eso.
AWS CLI tiene una opción incorporada --query que usa JMESPath, y a menudo es la herramienta adecuada para búsquedas simples. jq es útil cuando deseas un remodelado JSON más rico, lógica condicional, salida CSV o filtros que puedas reutilizar en scripts de shell.
Comienza con Salida JSON
jq lee JSON, así que haz que AWS CLI devuelva JSON explícitamente:
aws ec2 describe-instances --output json
También puedes configurar JSON como tu valor predeterminado con aws configure, pero usar --output json en ejemplos y scripts hace que la dependencia sea obvia.
Instala jq con el gestor de paquetes de tu sistema si aún no está disponible:
sudo apt update && sudo apt install jq
sudo dnf install jq
brew install jq
Leer e Inspeccionar JSON de AWS
El filtro de identidad, ., devuelve el JSON de entrada. Es útil cuando deseas una salida con formato bonito mientras aprendes la forma de una respuesta:
aws ec2 describe-instances --output json | jq '.'
Para seleccionar una clave de nivel superior, usa la notación de puntos:
aws ec2 describe-instances --output json | jq '.Reservations'
La mayoría de los comandos de AWS envuelven datos útiles en arrays. Para instancias EC2, la estructura es Reservations[] seguido de Instances[], por lo que generalmente necesitas ambos niveles.
Iterar a Través de Arrays
Usa .[] para emitir cada elemento de un array. Este comando imprime cada ID de instancia EC2 en todas las reservas:
aws ec2 describe-instances --output json | jq '.Reservations[].Instances[].InstanceId'
Por defecto, la salida de cadena incluye comillas JSON. Agrega -r cuando necesites texto sin formato para un bucle de shell u otro comando:
aws ec2 describe-instances --output json | jq -r '.Reservations[].Instances[].InstanceId'
También puedes construir un objeto más pequeño solo con los campos que te interesan:
aws ec2 describe-instances --output json |
jq '.Reservations[].Instances[] | {id: .InstanceId, state: .State.Name, type: .InstanceType}'
Eso te da registros JSON compactos en lugar de la respuesta completa de EC2.
Filtrar con select()
Usa select() cuando solo quieras registros que coincidan con una condición. Este ejemplo lista los IDs de instancias en ejecución:
aws ec2 describe-instances --output json |
jq -r '.Reservations[].Instances[] | select(.State.Name == "running") | .InstanceId'
Las cadenas literales dentro de un filtro jq usan comillas dobles, como "running". Si envuelves todo el programa jq en comillas simples, tu shell pasará esas comillas dobles de manera segura.
Para una verificación más específica, filtra por tipo de instancia:
aws ec2 describe-instances --output json |
jq -r '.Reservations[].Instances[] | select(.InstanceType == "t3.micro") | .InstanceId'
Manejar Campos Opcionales de Forma Segura
Los recursos de AWS a menudo omiten campos. Las etiquetas son un ejemplo común. Si una instancia no tiene un array Tags, .Tags[] puede fallar. Usa el iterador opcional .Tags[]?:
aws ec2 describe-instances --output json |
jq '.Reservations[].Instances[] | {id: .InstanceId, name: (.Tags[]? | select(.Key == "Name") | .Value)}'
Eso funciona, pero puede producir ningún valor de name cuando falta la etiqueta. Para scripts, un valor predeterminado suele ser más fácil de consumir:
aws ec2 describe-instances --output json |
jq '.Reservations[].Instances[] | {
id: .InstanceId,
name: ((.Tags[]? | select(.Key == "Name") | .Value) // "unnamed")
}'
Devolver un Array en Lugar de un Flujo
Muchos filtros jq emiten un flujo de valores. Si otra herramienta espera un array JSON válido, envuelve la expresión entre corchetes:
aws ec2 describe-instances --output json |
jq '[.Reservations[].Instances[].InstanceId]'
Esto es útil cuando estás escribiendo un archivo JSON para otro paso de automatización.
Exportar CSV o TSV
Para informes compatibles con hojas de cálculo, construye un array de campos y pásalo a @csv o @tsv. Usa -r para que jq escriba líneas CSV sin formato en lugar de cadenas JSON:
aws ec2 describe-instances --output json |
jq -r '.Reservations[].Instances[] | [.InstanceId, .InstanceType, .State.Name] | @csv'
Para incluir una fila de encabezado, emítela antes de las filas de datos:
aws ec2 describe-instances --output json |
jq -r '["instance_id","instance_type","state"], (.Reservations[].Instances[] | [.InstanceId, .InstanceType, .State.Name]) | @csv'
Ejemplo Práctico: Encontrar IPs Elásticas No Asociadas
Las direcciones IP elásticas no asociadas pueden generar costos evitables. Este comando lista las IPs públicas donde AWS no devolvió un AssociationId:
aws ec2 describe-addresses --output json |
jq -r '.Addresses[] | select(.AssociationId == null) | .PublicIp'
Si imprime direcciones, revísalas antes de liberarlas:
aws ec2 release-address --allocation-id eipalloc-0123456789abcdef0
No canalices comandos de liberación directamente desde una consulta de descubrimiento hasta que hayas verificado los resultados. Un breve paso de revisión es más barato que recuperarse de eliminar el recurso equivocado.
Cuándo Usar --query en su Lugar
Usa --query de AWS CLI para proyecciones simples porque se ejecuta antes del formato de salida y mantiene el comando autocontenido:
aws ec2 describe-instances \
--query 'Reservations[].Instances[].InstanceId' \
--output text
Recurre a jq cuando el resultado necesite más transformación, como valores de respaldo, formato CSV, combinación de campos o filtros más largos que sean más fáciles de leer en la sintaxis de jq.
Conclusión
Usa --output json como punto de transferencia entre AWS CLI y jq. Luego combina .[], select(), construcción de objetos, valores predeterminados // y salida sin formato -r para convertir grandes respuestas de AWS en los datos exactos que tu script o informe necesita.