Was liegt näher, als immer wiederkehrende Aufgaben mit Skripten zu automatisieren. Das reduziert den Arbeitsaufwand wie auch die Fehleranfälligkeit. In der ... (mehr)

JQ verschönert und durchsucht JSON

In jedem Fall können Sie die JSON-Ausgabe mit JQ weiterverarbeiten, etwa um an einen in der tief verschachtelten Struktur versteckten Wert zu gelangen oder sich die Ausgabe formatiert und farblich markiert auszugeben (Bild 2). Der Code in Listing 1 liest die vorhandenen Security Groups einer Region aus. Auch hier bekommt der Boto-Client die Region als Keyword-Argument übergeben.

Listing 1: Security Groups

from __future__ import print_function
import boto3
import json
import sys
ec2client = boto3.client('ec2', region_name='us-east-1')
groups = ec2client.describe_security_groups()
print(json.dumps(groups))

Mit dem folgenden Aufruf von JQ iterieren Sie über die als Liste gespeicherten "SecurityGroups" und geben dabei zu jeder den GroupName aus:

$ python3 sg.py | jq '.SecurityGroups[].GroupName'

Um das Layout der Ausgabe selber zu bestimmen, verwenden Sie die sogenannte String Interpolation, die JQ bietet. Dabei wird jede Variable mit einem Backslash und zwei Klammern umschlossen. Der Rest des Strings wird so dargestellt wie angegeben:

$ python3 sg.py | jq '.SecurityGroups[] | "\(.GroupName): \(.GroupId)"' "default: sg-0cba197b" "default_elb_3966756d-9722-3604-a7aa-aeb3277e84a3: sg-3f65ff48" "launch-wizard-1: sg-7f4af20b"

Bei der Verarbeitung per JQ befinden Sie sich natürlich dann auf Shell-Ebene, was in Ordnung ist, wenn Sie am Ende eines Skripts Daten ausgeben, die Sie sich anschauen oder mit einem anderen Skript weiterverarbeiten wollen. Weniger sinnvoll ist der Einsatz von JQ, wenn Sie innerhalb des Skripts die Daten verarbeiten möchten.

Dafür verwenden Sie besser ein Python-Modul, das sich auf die Suche in verschachtelten Listen und Dictionaries spezialisiert hat, wie etwa "nested lookup" oder "dpath", oder eins der Module, die eine Abfragesprache für JSON analog zu XPath für XML implementieren, etwa "jsonpath-ng". Ansonsten iterieren Sie wie üblich über die Liste und können dabei die Werte ausgeben:

for g in groups['SecurityGroups']:
       print(g['GroupName'], g['GroupId'])

Filter reduzieren Resultate

Darüber hinaus unterstützen viele Boto-Methoden auch Filter, die es ermöglichen, Einschränkungen der gefragten Daten bereits auf dem Server anzuwenden und somit die übertragenen Datenmengen zu reduzieren, zum Beispiel hier bei der Suche nach laufenden AWS-Instanzen:

result = ec2.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])

Wenn Sie nun etwa eine Security Group mit der Methode "delete_security_group" löschen möchten, kann es sein, dass Sie mit einer Fehlermeldung wie der folgenden konfrontiert werden:

>> ec2client.delete_security_group(GroupID='sg-29b81b5e')
...
botocore.exceptions.ClientError: An error occurred (DependencyViolation) when calling the DeleteSecurityGroup operation: resource sg-29b81b5e has a dependent object

Der Grund dafür ist, dass das zu löschende Objekt noch in einem anderen Objekt als Referenz vorkommt. Bevor dieser Verweis nicht gelöscht ist, dürfen Sie das Objekt nicht löschen. Im Fall von Security Groups können Sie zur Lösung des Problems alle Security Groups durchgehen und in den "UserIdGroupPairs" nachsehen, ob das fragliche Objekt vorhanden ist. Wenn ja, löschen Sie die Referenz, danach dürfen Sie auch das Objekt löschen, auf das verwiesen wird.

comments powered by Disqus
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023