Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
AWS CloudFormation Guard Regeln für Tests
Sie können das AWS CloudFormation Guard integrierte Unit-Test-Framework verwenden, um zu überprüfen, ob Ihre Guard-Regeln wie vorgesehen funktionieren. In diesem Abschnitt erfahren Sie, wie Sie eine Unit-Test-Datei schreiben und wie Sie damit Ihre Regeldatei mit dem test Befehl testen können.
Ihre Unit-Test-Datei muss eine der folgenden Erweiterungen haben:.json,.JSON,.jsn, .yaml.YAML, oder.yml.
Themen
Voraussetzungen
Schreiben Sie Guard-Regeln, anhand derer Ihre Eingabedaten ausgewertet werden. Weitere Informationen finden Sie unter Writing Guard-Regeln.
Überblick über die Guard-Unit-Testdateien
Guard-Unit-Testdateien sind Dateien im JSON- oder YAML-Format, die mehrere Eingaben und die erwarteten Ergebnisse für Regeln enthalten, die in einer Guard-Regeldatei geschrieben sind. Es kann mehrere Stichproben geben, um unterschiedliche Erwartungen zu bewerten. Wir empfehlen, zunächst auf leere Eingaben zu testen und dann nach und nach Informationen zur Bewertung verschiedener Regeln und Klauseln hinzuzufügen.
Außerdem empfehlen wir, Unit-Testing-Dateien mit dem Suffix _test.json oder zu benennen. _tests.yaml Wenn Sie beispielsweise eine Regeldatei mit dem Namen habenmy_rules.guard, geben Sie Ihrer Unit-Test-Datei my_rules_tests.yaml einen Namen.
Syntax
Im Folgenden wird die Syntax einer Unit-Test-Datei im YAML-Format gezeigt.
--- - name: <TEST NAME> input: <SAMPLE INPUT> expectations: rules: <RULE NAME>: [PASS|FAIL|SKIP]
Eigenschaften
Im Folgenden sind die Eigenschaften einer Guard-Testdatei aufgeführt.
input-
Daten, anhand derer Sie Ihre Regeln testen können. Wir empfehlen, dass Ihr erster Test eine leere Eingabe verwendet, wie im folgenden Beispiel gezeigt.
--- - name: MyTest1 input {}Fügen Sie für nachfolgende Tests Eingabedaten zum Test hinzu.
Erforderlich: Ja
expectations-
Das erwartete Ergebnis, wenn bestimmte Regeln anhand Ihrer Eingabedaten bewertet werden. Geben Sie eine oder mehrere Regeln an, die Sie zusätzlich zum erwarteten Ergebnis für jede Regel testen möchten. Das erwartete Ergebnis muss eines der folgenden sein:
-
PASS— Bei der Ausführung mit Ihren Eingabedaten werden die Regeln wie folgt ausgewertettrue. -
FAIL— Bei der Ausführung mit Ihren Eingabedaten werden die Regeln wie folgt ausgewertetfalse. -
SKIP— Wenn die Regel anhand Ihrer Eingabedaten ausgeführt wird, wird sie nicht ausgelöst.
expectations: rules: check_rest_api_is_private: PASSErforderlich: Ja
-
Exemplarische Vorgehensweise zum Schreiben einer Unit-Test-Datei für Guard-Regeln
Im Folgenden finden Sie eine Regeldatei mit dem Namenapi_gateway_private.guard. Mit dieser Regel soll überprüft werden, ob alle in einer CloudFormation Vorlage definierten Amazon API Gateway Gateway-Ressourcentypen nur für den privaten Zugriff bereitgestellt werden. Außerdem wird geprüft, ob mindestens eine Richtlinienerklärung den Zugriff von einer Virtual Private Cloud (VPC) aus erlaubt.
# # Select allAWS::ApiGateway::RestApiresources # present in theResourcessection of the template. # let api_gws = Resources.*[ Type == 'AWS::ApiGateway::RestApi'] # # Rule intent: # 1) AllAWS::ApiGateway::RestApiresources deployed must be private. # 2) AllAWS::ApiGateway::RestApiresources deployed must have at least one AWS Identity and Access Management (IAM) policy condition key to allow access from a VPC. # # Expectations: # 1) SKIP when there are noAWS::ApiGateway::RestApiresources in the template. # 2) PASS when: # ALLAWS::ApiGateway::RestApiresources in the template have theEndpointConfigurationproperty set toType:PRIVATE. # ALLAWS::ApiGateway::RestApiresources in the template have one IAM condition key specified in thePolicyproperty withaws:sourceVpcor:SourceVpc. # 3) FAIL otherwise. # # rule check_rest_api_is_private when %api_gws !empty { %api_gws { Properties.EndpointConfiguration.Types[*] == "PRIVATE" } } rule check_rest_api_has_vpc_access when check_rest_api_is_private { %api_gws { Properties { # # ALLAWS::ApiGateway::RestApiresources in the template have one IAM condition key specified in thePolicyproperty with #aws:sourceVpcor:SourceVpc# some Policy.Statement[*] { Condition.*[ keys == /aws:[sS]ource(Vpc|VPC|Vpce|VPCE)/ ] !empty } } } }
In dieser exemplarischen Vorgehensweise wird die Absicht der ersten Regel getestet: Alle bereitgestellten AWS::ApiGateway::RestApi Ressourcen müssen privat sein.
-
Erstellen Sie eine Unit-Test-Datei mit dem Namen
api_gateway_private_tests.yaml, die den folgenden ersten Test enthält. Fügen Sie beim ersten Test eine leere Eingabe hinzu und gehen Sie davon aus, dass die Regel übersprungencheck_rest_api_is_privatewird, da keineAWS::ApiGateway::RestApiRessourcen als Eingaben vorhanden sind.--- - name: MyTest1 input: {} expectations: rules: check_rest_api_is_private: SKIP -
Führen Sie den ersten Test in Ihrem Terminal mit dem
testBefehl aus. Geben Sie für den--rules-fileParameter Ihre Regeldatei an. Geben Sie für den--test-dataParameter Ihre Unit-Test-Datei an.cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yamlDas Ergebnis des ersten Tests ist
PASS.Test Case #1 Name: "MyTest1" PASS Rules: check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP -
Fügen Sie Ihrer Unit-Test-Datei einen weiteren Test hinzu. Erweitern Sie nun den Test auf leere Ressourcen. Das Folgende ist die aktualisierte
api_gateway_private_tests.yamlDatei.--- - name: MyTest1 input: {} expectations: rules: check_rest_api_is_private: SKIP - name: MyTest2 input: Resources: {} expectations: rules: check_rest_api_is_private: SKIP -
Führen Sie es
testmit der aktualisierten Unit-Test-Datei aus.cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yamlDas Ergebnis für den zweiten Test ist
PASS.Test Case #1 Name: "MyTest1" PASS Rules: check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP Test Case #2 Name: "MyTest2" PASS Rules: check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP -
Fügen Sie Ihrer Unit-Test-Datei zwei weitere Tests hinzu. Erweitern Sie die Tests um Folgendes:
-
Eine
AWS::ApiGateway::RestApiRessource ohne angegebene Eigenschaften.Anmerkung
Dies ist keine gültige CloudFormation Vorlage, aber es ist nützlich, um zu testen, ob die Regel auch bei falsch formatierten Eingaben korrekt funktioniert.
Gehen Sie davon aus, dass dieser Test fehlschlägt, weil die
EndpointConfigurationEigenschaft nicht angegeben und daher nicht aufPRIVATEgesetzt ist. -
Eine
AWS::ApiGateway::RestApiRessource, die die erste Absicht erfüllt, wenn dieEndpointConfigurationEigenschaft auf gesetzt ist,PRIVATEaber die zweite Absicht nicht erfüllt, da für sie keine Richtlinienaussagen definiert sind. Erwarten Sie, dass dieser Test bestanden wird.
Im Folgenden finden Sie die aktualisierte Unit-Test-Datei.
--- - name: MyTest1 input: {} expectations: rules: check_rest_api_is_private: SKIP - name: MyTest2 input: Resources: {} expectations: rules: check_rest_api_is_private: SKIP - name: MyTest3 input: Resources: apiGw: Type: AWS::ApiGateway::RestApi expectations: rules: check_rest_api_is_private: FAIL - name: MyTest4 input: Resources: apiGw: Type: AWS::ApiGateway::RestApi Properties: EndpointConfiguration: Types: "PRIVATE" expectations: rules: check_rest_api_is_private: PASS -
-
Führen Sie es
testmit der aktualisierten Unit-Test-Datei aus.cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml \Das dritte Ergebnis ist
FAIL, und das vierte Ergebnis istPASS.Test Case #1 Name: "MyTest1" PASS Rules: check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP Test Case #2 Name: "MyTest2" PASS Rules: check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP Test Case #3 Name: "MyTest3" PASS Rules: check_rest_api_is_private: Expected = FAIL, Evaluated = FAIL Test Case #4 Name: "MyTest4" PASS Rules: check_rest_api_is_private: Expected = PASS, Evaluated = PASS -
Kommentieren Sie die Tests 1—3 in Ihrer Unit-Test-Datei aus. Greifen Sie nur für den vierten Test auf den ausführlichen Kontext zu. Im Folgenden finden Sie die aktualisierte Unit-Test-Datei.
--- #- name: MyTest1 # input: {} # expectations: # rules: # check_rest_api_is_private_and_has_access: SKIP #- name: MyTest2 # input: # Resources: {} # expectations: # rules: # check_rest_api_is_private_and_has_access: SKIP #- name: MyTest3 # input: # Resources: # apiGw: # Type: AWS::ApiGateway::RestApi # expectations: # rules: # check_rest_api_is_private_and_has_access: FAIL - name: MyTest4 input: Resources: apiGw: Type: AWS::ApiGateway::RestApi Properties: EndpointConfiguration: Types: "PRIVATE" expectations: rules: check_rest_api_is_private: PASS -
Überprüfen Sie die Evaluierungsergebnisse, indem Sie den
testBefehl in Ihrem Terminal ausführen und dabei das--verboseFlag verwenden. Ein ausführlicher Kontext ist nützlich, um Bewertungen zu verstehen. In diesem Fall enthält es detaillierte Informationen darüber, warum der vierte Test erfolgreich war und einPASSErgebnis hatte.cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml \ --verboseHier ist die Ausgabe dieses Durchlaufs.
Test Case #1 Name: "MyTest4" PASS Rules: check_rest_api_is_private: Expected = PASS, Evaluated = PASS Rule(check_rest_api_is_private, PASS) | Message: DEFAULT MESSAGE(PASS) Condition(check_rest_api_is_private, PASS) | Message: DEFAULT MESSAGE(PASS) Clause(Clause(Location[file:api_gateway_private.guard, line:20, column:37], Check: %api_gws NOT EMPTY ), PASS) | From: Map((Path("/Resources/apiGw"), MapValue { keys: [String((Path("/Resources/apiGw/Type"), "Type")), String((Path("/Resources/apiGw/Properties"), "Properties"))], values: {"Type": String((Path("/Resources/apiGw/Type"), "AWS::ApiGateway::RestApi")), "Properties": Map((Path("/Resources/apiGw/Properties"), MapValue { keys: [String((Path("/Resources/apiGw/Properties/EndpointConfiguration"), "EndpointConfiguration"))], values: {"EndpointConfiguration": Map((Path("/Resources/apiGw/Properties/EndpointConfiguration"), MapValue { keys: [String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types"), "Types"))], values: {"Types": String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types"), "PRIVATE"))} }))} }))} })) | Message: (DEFAULT: NO_MESSAGE) Conjunction(cfn_guard::rules::exprs::GuardClause, PASS) | Message: DEFAULT MESSAGE(PASS) Clause(Clause(Location[file:api_gateway_private.guard, line:22, column:5], Check: Properties.EndpointConfiguration.Types[*] EQUALS String("PRIVATE")), PASS) | Message: (DEFAULT: NO_MESSAGE)Die wichtigste Beobachtung aus der Ausgabe ist die Zeile
Clause(Location[file:api_gateway_private.guard, line:22, column:5], Check: Properties.EndpointConfiguration.Types[*] EQUALS String("PRIVATE")), PASS), die besagt, dass die Prüfung bestanden wurde. Das Beispiel zeigte auch den Fall, dass ein Array erwartetTypeswurde, aber ein einziger Wert angegeben wurde. In diesem Fall führte Guard die Auswertung fort und lieferte ein korrektes Ergebnis. -
Fügen Sie Ihrer Komponententestdatei für eine
AWS::ApiGateway::RestApiRessource mit der angegebenenEndpointConfigurationEigenschaft einen Testfall wie den vierten Testfall hinzu. Der Testfall schlägt fehl, anstatt erfolgreich zu sein. Im Folgenden finden Sie die aktualisierte Unit-Test-Datei.--- #- name: MyTest1 # input: {} # expectations: # rules: # check_rest_api_is_private_and_has_access: SKIP #- name: MyTest2 # input: # Resources: {} # expectations: # rules: # check_rest_api_is_private_and_has_access: SKIP #- name: MyTest3 # input: # Resources: # apiGw: # Type: AWS::ApiGateway::RestApi # expectations: # rules: # check_rest_api_is_private_and_has_access: FAIL #- name: MyTest4 # input: # Resources: # apiGw: # Type: AWS::ApiGateway::RestApi # Properties: # EndpointConfiguration: # Types: "PRIVATE" # expectations: # rules: # check_rest_api_is_private: PASS - name: MyTest5 input: Resources: apiGw: Type: AWS::ApiGateway::RestApi Properties: EndpointConfiguration: Types: [PRIVATE, REGIONAL] expectations: rules: check_rest_api_is_private: FAIL -
Führen Sie den
testBefehl mit der aktualisierten Unit-Test-Datei mithilfe des--verboseFlags aus.cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml \ --verboseDas Ergebnis ist
FAILerwartungsgemäß, daREGIONALes für angegeben wurdeEndpointConfiguration, aber nicht erwartet wird.Test Case #1 Name: "MyTest5" PASS Rules: check_rest_api_is_private: Expected = FAIL, Evaluated = FAIL Rule(check_rest_api_is_private, FAIL) | Message: DEFAULT MESSAGE(FAIL) Condition(check_rest_api_is_private, PASS) | Message: DEFAULT MESSAGE(PASS) Clause(Clause(Location[file:api_gateway_private.guard, line:20, column:37], Check: %api_gws NOT EMPTY ), PASS) | From: Map((Path("/Resources/apiGw"), MapValue { keys: [String((Path("/Resources/apiGw/Type"), "Type")), String((Path("/Resources/apiGw/Properties"), "Properties"))], values: {"Type": String((Path("/Resources/apiGw/Type"), "AWS::ApiGateway::RestApi")), "Properties": Map((Path("/Resources/apiGw/Properties"), MapValue { keys: [String((Path("/Resources/apiGw/Properties/EndpointConfiguration"), "EndpointConfiguration"))], values: {"EndpointConfiguration": Map((Path("/Resources/apiGw/Properties/EndpointConfiguration"), MapValue { keys: [String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types"), "Types"))], values: {"Types": List((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types"), [String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types/0"), "PRIVATE")), String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types/1"), "REGIONAL"))]))} }))} }))} })) | Message: DEFAULT MESSAGE(PASS) BlockClause(Block[Location[file:api_gateway_private.guard, line:21, column:3]], FAIL) | Message: DEFAULT MESSAGE(FAIL) Conjunction(cfn_guard::rules::exprs::GuardClause, FAIL) | Message: DEFAULT MESSAGE(FAIL) Clause(Clause(Location[file:api_gateway_private.guard, line:22, column:5], Check: Properties.EndpointConfiguration.Types[*] EQUALS String("PRIVATE")), FAIL) | From: String((Path("/Resources/apiGw/Properties/EndpointConfiguration/Types/1"), "REGIONAL")) | To: String((Path("api_gateway_private.guard/22/5/Clause/"), "PRIVATE")) | Message: (DEFAULT: NO_MESSAGE)Die ausführliche Ausgabe des
testBefehls folgt der Struktur der Regeldatei. Jeder Block in der Regeldatei ist ein Block in der ausführlichen Ausgabe. Der oberste Block ist jede Regel. Wenn eswhenBedingungen gibt, die gegen die Regel verstoßen, werden sie in einem gleichgeordneten Bedingungsblock angezeigt. Im folgenden Beispiel%api_gws !emptywird die Bedingung getestet und sie besteht.rule check_rest_api_is_private when %api_gws !empty {Sobald die Bedingung erfüllt ist, testen wir die Regelklauseln.
%api_gws { Properties.EndpointConfiguration.Types[*] == "PRIVATE" }%api_gwsist eine Blockregel, die demBlockClauseLevel in der Ausgabe entspricht (Zeile:21). Die Regelklausel besteht aus einer Reihe von Konjunktionsklauseln (AND), wobei jede Konjunktionsklausel eine Menge von Disjunktionen ist.ORDie Konjunktion hat eine einzige Klausel,.Properties.EndpointConfiguration.Types[*] == "PRIVATE"Daher enthält die ausführliche Ausgabe eine einzige Klausel. Der Pfad/Resources/apiGw/Properties/EndpointConfiguration/Types/1zeigt, welche Werte in der Eingabe verglichen werden. In diesem Fall handelt es sich um das Element für denTypesIndex 1.
In können Sie die Beispiele in diesem Abschnitt verwendenValidierung der Eingabedaten anhand der Guard-Regeln, um den validate Befehl zu verwenden, um Eingabedaten anhand von Regeln auszuwerten.