Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
AWS CloudFormation Guard Regole di test
Puoi utilizzare il framework di unit testing AWS CloudFormation Guard integrato per verificare che le regole di Guard funzionino come previsto. Questa sezione fornisce una procedura dettagliata su come scrivere un file di unit testing e su come utilizzarlo per testare il file delle regole con il test comando.
Il file di unit test deve avere una delle seguenti estensioni:.json,,.JSON, .jsn .yaml.YAML, o. .yml
Argomenti
Prerequisiti
Scrivi le regole di Guard in base alle quali valutare i tuoi dati di input. Per ulteriori informazioni, consulta regole di Writing Guard.
Panoramica dei file di test delle unità Guard
I file di test delle unità Guard sono file in formato JSON o YAML che contengono più input e i risultati previsti per le regole scritte all'interno di un file di regole Guard. Possono esserci più esempi per valutare aspettative diverse. Ti consigliamo di iniziare verificando la presenza di input vuoti e quindi di aggiungere progressivamente informazioni per valutare varie regole e clausole.
Inoltre, si consiglia di denominare i file di unit test utilizzando il suffisso o. _test.json _tests.yaml Ad esempio, se avete un file di regole denominatomy_rules.guard, assegnate un nome al file my_rules_tests.yaml di unit testing.
Sintassi
Di seguito viene illustrata la sintassi di un file di unit testing in formato YAML.
--- - name: <TEST NAME> input: <SAMPLE INPUT> expectations: rules: <RULE NAME>: [PASS|FAIL|SKIP]
Proprietà
Di seguito sono riportate le proprietà di un file di test Guard.
input-
Dati in base ai quali testare le tue regole. È consigliabile che il primo test utilizzi un input vuoto, come illustrato nell'esempio seguente.
--- - name: MyTest1 input {}Per i test successivi, aggiungi i dati di input al test.
Campo obbligatorio: sì
expectations-
Il risultato previsto quando regole specifiche vengono valutate rispetto ai dati di input. Specificate una o più regole da testare oltre al risultato previsto per ogni regola. Il risultato previsto deve essere uno dei seguenti:
-
PASS— Quando vengono eseguite sulla base dei dati di input, le regole restituiscono lo stesso risultatotrue. -
FAIL— Quando vengono eseguite in base ai dati di input, le regole restituiscono lo stesso risultatofalse. -
SKIP— Quando viene eseguita sui dati di input, la regola non viene attivata.
expectations: rules: check_rest_api_is_private: PASSCampo obbligatorio: sì
-
Procedura dettagliata per la scrittura di un file di test unitario delle regole di Guard
Di seguito è riportato un file di regole denominato. api_gateway_private.guard L'intento di questa regola è verificare se tutti i tipi di risorse Amazon API Gateway definiti in un CloudFormation modello sono distribuiti solo per l'accesso privato. Verifica inoltre se almeno una dichiarazione di policy consente l'accesso da un cloud privato virtuale (VPC).
# # 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 } } } }
Questa procedura dettagliata verifica l'intento della prima regola: tutte le AWS::ApiGateway::RestApi risorse distribuite devono essere private.
-
Crea un file di unit test chiamato
api_gateway_private_tests.yamlche contiene il seguente test iniziale. Con il test iniziale, aggiungi un input vuoto e aspettati che la regolacheck_rest_api_is_privatevenga ignorata perché non ci sonoAWS::ApiGateway::RestApirisorse come input.--- - name: MyTest1 input: {} expectations: rules: check_rest_api_is_private: SKIP -
Esegui il primo test nel tuo terminale usando il
testcomando. Per il--rules-fileparametro, specifica il file delle regole. Per il--test-dataparametro, specificate il file di test unitario.cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yamlIl risultato del primo test è
PASS.Test Case #1 Name: "MyTest1" PASS Rules: check_rest_api_is_private: Expected = SKIP, Evaluated = SKIP -
Aggiungi un altro test al tuo file di unit test. Ora estendi il test per includere risorse vuote. Di seguito è riportato il
api_gateway_private_tests.yamlfile aggiornato.--- - name: MyTest1 input: {} expectations: rules: check_rest_api_is_private: SKIP - name: MyTest2 input: Resources: {} expectations: rules: check_rest_api_is_private: SKIP -
Esegui
testcon il file di unit test aggiornato.cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yamlIl risultato del secondo test è
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 -
Aggiungi altri due test al tuo file di unit testing. Estendi il test per includere quanto segue:
-
Una
AWS::ApiGateway::RestApirisorsa senza proprietà specificate.Nota
Questo non è un CloudFormation modello valido, ma è utile per verificare se la regola funziona correttamente anche per input non validi.
Aspettatevi che questo test abbia esito negativo perché la
EndpointConfigurationproprietà non è specificata e quindi non è impostata su.PRIVATE -
Una
AWS::ApiGateway::RestApirisorsa che soddisfa il primo intento con laEndpointConfigurationproprietà impostata suPRIVATEma non soddisfa il secondo intento perché non ha istruzioni politiche definite. Aspettatevi che questo test venga superato.
Di seguito è riportato il file di unit test aggiornato.
--- - 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 -
-
Esegui
testcon il file di unit test aggiornato.cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml \Il terzo risultato è
FAIL, e il quarto risultato è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 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 -
Commenta i test 1-3 nel tuo file di unit testing. Accedi al contesto dettagliato solo per il quarto test. Di seguito è riportato il file di unit test aggiornato.
--- #- 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 -
Controlla i risultati della valutazione eseguendo il
testcomando nel tuo terminale, usando il--verboseflag. Il contesto verboso è utile per comprendere le valutazioni. In questo caso, fornisce informazioni dettagliate sul motivo per cui il quarto test ha avuto esito positivo.PASScfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml \ --verboseEcco l'output di quella corsa.
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)L'osservazione chiave dell'output è la riga
Clause(Location[file:api_gateway_private.guard, line:22, column:5], Check: Properties.EndpointConfiguration.Types[*] EQUALS String("PRIVATE")), PASS), che indica che il controllo è stato superato. L'esempio ha mostrato anche il caso in cui ci siTypesaspettava che fosse un array, ma è stato fornito un singolo valore. In tal caso, Guard ha continuato a valutare e ha fornito un risultato corretto. -
Aggiungi un test case come il quarto test case al tuo file di unit testing per una
AWS::ApiGateway::RestApirisorsa con laEndpointConfigurationproprietà specificata. Il test case fallirà invece di essere superato. Di seguito è riportato il file di test unitario aggiornato.--- #- 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 -
Esegui il
testcomando con il file di unit test aggiornato usando il--verboseflag.cfn-guard test --rules-file api_gateway_private.guard --test-data api_gateway_private_tests.yaml \ --verboseIl risultato è quello
FAILprevisto perchéREGIONALè stato specificatoEndpointConfigurationma non è previsto.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)L'output dettagliato del
testcomando segue la struttura del file delle regole. Ogni blocco nel file delle regole è un blocco nell'output dettagliato. Il blocco più in alto è ogni regola. Se sono presentiwhencondizioni contrarie alla regola, queste vengono visualizzate in un blocco di condizioni di pari livello. Nell'esempio seguente, la condizione%api_gws !emptyviene testata e viene soddisfatta.rule check_rest_api_is_private when %api_gws !empty {Una volta superata la condizione, testiamo le clausole della regola.
%api_gws { Properties.EndpointConfiguration.Types[*] == "PRIVATE" }%api_gwsè una regola di blocco che corrisponde alBlockClauselivello dell'output (linea:21). La clausola della regola è un insieme di clausole di congiunzione (AND), in cui ogni clausola di congiunzione è un insieme di disgiunzioni.ORLaProperties.EndpointConfiguration.Types[*] == "PRIVATE"congiunzione ha una sola clausola,. Pertanto, l'output dettagliato mostra una singola clausola. Il percorso/Resources/apiGw/Properties/EndpointConfiguration/Types/1mostra quali valori dell'input vengono confrontati, che in questo caso è l'elementoTypesindicizzato a 1.
InConvalida dei dati di input rispetto alle regole di Guard, è possibile utilizzare gli esempi in questa sezione per utilizzare il validate comando per valutare i dati di input in base alle regole.