

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# AWS CloudFormation Guard Règles d'écriture
<a name="writing-rules"></a>

Dans AWS CloudFormation Guard, *les règles* sont les policy-as-code règles. Vous rédigez des règles dans le langage spécifique au domaine Guard (DSL) par rapport auxquelles vous pouvez valider vos données au format JSON ou YAML. Les règles sont composées de *clauses*.

Vous pouvez enregistrer les règles écrites à l'aide du Guard DSL dans des fichiers en texte brut qui utilisent n'importe quelle extension de fichier.

Vous pouvez créer plusieurs fichiers de règles et les classer en tant qu'*ensemble de règles*. Les ensembles de règles vous permettent de valider vos données au format JSON ou YAML par rapport à plusieurs fichiers de règles en même temps.

**Topics**
+ [Clauses](#clauses)
+ [Utilisation de requêtes dans les clauses](#clauses-queries)
+ [Utilisation d'opérateurs dans les clauses](#clauses-operators)
+ [Utilisation de messages personnalisés dans les clauses](#clauses-custom-messages)
+ [Combinaison de clauses](#combining-clauses)
+ [Utiliser des blocs avec les règles de garde](#blocks)
+ [Utilisation des fonctions intégrées](#built-in-functions)
+ [Définition des requêtes Guard et filtrage](query-and-filtering.md)
+ [Affectation et référencement de variables dans les règles Guard](variables.md)
+ [Composer des blocs de règles nommées dans AWS CloudFormation Guard](named-rule-block-composition.md)
+ [Rédaction de clauses pour effectuer des évaluations contextuelles](context-aware-evaluations.md)

## Clauses
<a name="clauses"></a>

Les clauses sont des expressions booléennes dont la valeur est vraie (`PASS`) ou fausse (`FAIL`). Les clauses utilisent soit des opérateurs binaires pour comparer deux valeurs, soit des opérateurs unaires qui agissent sur une seule valeur.

**Exemples de clauses unaires**

La clause unaire suivante évalue si la collection `TcpBlockedPorts` est vide.

```
InputParameters.TcpBlockedPorts not empty
```

La clause unaire suivante détermine si la `ExecutionRoleArn` propriété est une chaîne.

```
Properties.ExecutionRoleArn is_string
```

**Exemples de clauses binaires**

La clause binaire suivante évalue si la `BucketName` propriété contient la chaîne`encrypted`, quel que soit le casier.

```
Properties.BucketName != /(?i)encrypted/
```

La clause binaire suivante évalue si la `ReadCapacityUnits` propriété est inférieure ou égale à 5 000.

```
Properties.ProvisionedThroughput.ReadCapacityUnits <= 5000
```

### Syntaxe pour écrire les clauses des règles Guard
<a name="clauses-syntax"></a>

```
<query> <operator> [query|value literal] [custom message]
```

### Propriétés des clauses de la règle Guard
<a name="clauses-properties"></a>

`query`  <a name="clauses-properties-query"></a>
Expression séparée par des points (`.`) écrite pour parcourir des données hiérarchiques. Les expressions de requête peuvent inclure des expressions de filtre pour cibler un sous-ensemble de valeurs. Les requêtes peuvent être attribuées à des variables afin que vous puissiez les écrire une seule fois et les référencer ailleurs dans un ensemble de règles, ce qui vous permettra d'accéder aux résultats des requêtes.  
Pour plus d'informations sur la rédaction de requêtes et le filtrage, consultez[Définition des requêtes et filtrage](query-and-filtering.md).  
 *Obligatoire* : oui

`operator`  <a name="clauses-properties-operator"></a>
Opérateur unaire ou binaire qui permet de vérifier l'état de la requête. Le côté gauche (LHS) d'un opérateur binaire doit être une requête, et le côté droit (RHS) doit être une requête ou une valeur littérale.  
 *Opérateurs binaires pris en charge* : `==` `!=` (Égal) \| `>` (Non égal) \| `>=` (Supérieur à) \| (Supérieur ou égal à) \| `<` (Inférieur à) \| `<=` (Inférieur ou égal à) \| `IN` (Dans une liste au format [x, y, z]  
 *Opérateurs unaires pris en charge* : `exists` \| `empty` \| `is_string` \| \| `is_list` \| `is_struct` `not(!)`  
 *Obligatoire* : oui

`query|value literal`  <a name="clauses-properties-value-literal"></a>
Une requête ou un littéral de valeur pris en charge tel que `string` ou`integer(64)`.   
*Litéraux de valeur pris* en charge :  
+ Tous les types primitifs : `string``integer(64)`,`float(64)`,`bool`,`char`, `regex`
+ Tous les types de plages spécialisés pour exprimer `integer(64)``float(64)`, ou les `char` plages exprimées comme suit :
  + `r[<lower_limit>, <upper_limit>]`, qui se traduit par toute valeur `k` répondant à l'expression suivante : `lower_limit <= k <= upper_limit`
  + `r[<lower_limit>, <upper_limit>`), qui se traduit par toute valeur `k` répondant à l'expression suivante : `lower_limit <= k < upper_limit`
  + `r(<lower_limit>, <upper_limit>]`, qui se traduit par toute valeur `k` répondant à l'expression suivante : `lower_limit < k <= upper_limit`
  + `r(<lower_limit>, <upper_limit>),`qui se traduit par toute valeur `k` répondant à l'expression suivante : `lower_limit < k < upper_limit`
+ Tableaux associatifs (cartes) pour les données de structure clé-valeur imbriquées. Par exemple :

  `{ "my-map": { "nested-maps": [ { "key": 10, "value": 20 } ] } }`
+ Tableaux de types primitifs ou de types de tableaux associatifs
 *Obligatoire* : conditionnel ; obligatoire lorsqu'un opérateur binaire est utilisé.

`custom message`  <a name="clauses-properties-custom-message"></a>
Chaîne fournissant des informations sur la clause. Le message s'affiche dans les sorties détaillées des `test` commandes `validate` et et peut être utile pour comprendre ou débugger l'évaluation des règles sur des données hiérarchiques.  
 *Obligatoire* : non

## Utilisation de requêtes dans les clauses
<a name="clauses-queries"></a>

Pour plus d'informations sur la rédaction de requêtes, reportez-vous [Définition des requêtes et filtrage](query-and-filtering.md) aux sections et[Affectation et référencement de variables dans les règles Guard](variables.md).

## Utilisation d'opérateurs dans les clauses
<a name="clauses-operators"></a>

Voici des exemples de CloudFormation modèles, `Template-1` et`Template-2`. Pour démontrer l'utilisation des opérateurs pris en charge, les exemples de requêtes et de clauses de cette section font référence à ces exemples de modèles.

**Modèle-1**

```
Resources:
 S3Bucket:
   Type: AWS::S3::Bucket
   Properties:
     BucketName: MyServiceS3Bucket
     BucketEncryption:
       ServerSideEncryptionConfiguration:
         - ServerSideEncryptionByDefault:
             SSEAlgorithm: 'aws:kms'
             KMSMasterKeyID: 'arn:aws:kms:us-east-1:123456789:key/056ea50b-1013-3907-8617-c93e474e400'
     Tags:
       - Key: stage
         Value: prod
       - Key: service
         Value: myService
```

**Modèle-2**

```
Resources:
 NewVolume:
   Type: AWS::EC2::Volume
   Properties: 
     Size: 100
     VolumeType: io1
     Iops: 100
     AvailabilityZone:
       Fn::Select:
         - 0
         - Fn::GetAZs: us-east-1
     Tags:
       - Key: environment
         Value: test
   DeletionPolicy: Snapshot
```

### Exemples de clauses utilisant des opérateurs unaires
<a name="clauses-unary-operators"></a>
+ `empty`— Vérifie si une collection est vide. Vous pouvez également l'utiliser pour vérifier si une requête contient des valeurs dans des données hiérarchiques, car les requêtes aboutissent à une collection. Vous ne pouvez pas l'utiliser pour vérifier si une chaîne vide (`""`) est définie dans les requêtes contenant des valeurs de chaîne. Pour de plus amples informations, veuillez consulter [Définition des requêtes et filtrage](query-and-filtering.md).

  La clause suivante vérifie si une ou plusieurs ressources sont définies dans le modèle. Il est évalué comme `PASS` étant donné qu'une ressource avec l'ID logique `S3Bucket` est définie dans`Template-1`.

  ```
  Resources !empty
  ```

  La clause suivante vérifie si une ou plusieurs balises sont définies pour la `S3Bucket` ressource. Il est évalué à `PASS` parce `S3Bucket` que deux balises sont définies pour la `Tags` propriété dans`Template-1`.

  ```
  Resources.S3Bucket.Properties.Tags !empty
  ```
+ `exists`— Vérifie si chaque occurrence de la requête possède une valeur et peut être utilisée à la place de`!= null`.

  La clause suivante vérifie si la `BucketEncryption` propriété est définie pour`S3Bucket`. Il est évalué à `PASS` parce qu'il `BucketEncryption` est défini pour `S3Bucket` dans`Template-1`.

  ```
  Resources.S3Bucket.Properties.BucketEncryption exists
  ```

**Note**  
Les `not exists` contrôles `empty` et évaluent la présence `true` de clés de propriété manquantes lors de la traversée des données d'entrée. Par exemple, si la `Properties` section n'est pas définie dans le modèle pour le`S3Bucket`, la clause est `Resources.S3Bucket.Properties.Tag empty` évaluée à`true`. Les `empty` vérifications `exists` et n'affichent pas le chemin du pointeur JSON à l'intérieur du document dans les messages d'erreur. Ces deux clauses comportent souvent des erreurs de récupération qui ne tiennent pas compte de ces informations de traversée.
+ `is_string`— Vérifie si chaque occurrence de la requête est de `string` type.

  La clause suivante vérifie si une valeur de chaîne est spécifiée pour la `BucketName` propriété de la `S3Bucket` ressource. Il est évalué à `PASS` parce que la valeur de chaîne `"MyServiceS3Bucket"` est spécifiée `BucketName` dans`Template-1`.

  ```
  Resources.S3Bucket.Properties.BucketName is_string
  ```
+ `is_list`— Vérifie si chaque occurrence de la requête est de `list` type.

  La clause suivante vérifie si une liste est spécifiée pour la `Tags` propriété de la `S3Bucket` ressource. Il est évalué à `PASS` parce que deux paires clé-valeur sont spécifiées pour in. `Tags` `Template-1`

  ```
  Resources.S3Bucket.Properties.Tags is_list
  ```
+ `is_struct`— Vérifie si chaque occurrence de la requête est une donnée structurée.

  La clause suivante vérifie si des données structurées sont spécifiées pour la `BucketEncryption` propriété de la `S3Bucket` ressource. Il est évalué à `PASS` parce qu'il `BucketEncryption` est spécifié à l'aide du type de `ServerSideEncryptionConfiguration` propriété {{(object)}} in`Template-1`.

  ```
  Resources.S3Bucket.Properties.BucketEncryption is_struct
  ```

**Note**  
Pour vérifier l'état inverse, vous pouvez utiliser l'opérateur (` not !`) avec les `is_struct` opérateurs `is_string``is_list`, et.

### Exemples de clauses utilisant des opérateurs binaires
<a name="clauses-binary-operators"></a>

La clause suivante vérifie si la valeur spécifiée pour la `BucketName` propriété de la `S3Bucket` ressource `Template-1` contient la chaîne`encrypt`, quel que soit le casier. Cela se traduit par le `PASS` fait que le nom du compartiment spécifié `"MyServiceS3Bucket"` ne contient pas la chaîne`encrypt`.

```
Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/
```

La clause suivante vérifie si la valeur spécifiée pour la `Size` propriété de la `NewVolume` ressource `Template-2` se situe dans une plage spécifique : 50 <= `Size` <= 200. Il est évalué à `PASS` parce que `100` c'est spécifié pour`Size`.

```
Resources.NewVolume.Properties.Size IN r[50,200]
```

La clause suivante vérifie si la valeur spécifiée pour la `VolumeType` propriété de la `NewVolume` ressource dans `Template-2` est `io1``io2`, ou`gp3`. Il est évalué à `PASS` parce que `io1` c'est spécifié pour`NewVolume`.

```
Resources.NewVolume.Properties.NewVolume.VolumeType IN [ 'io1','io2','gp3' ]
```

**Note**  
Les exemples de requêtes présentés dans cette section illustrent l'utilisation d'opérateurs utilisant les ressources avec un caractère logique IDs `S3Bucket` et`NewVolume`. Les noms de ressources sont souvent définis par l'utilisateur et peuvent être nommés arbitrairement dans un modèle d'infrastructure en tant que code (IaC). Pour écrire une règle générique qui s'applique à toutes les `AWS::S3::Bucket` ressources définies dans le modèle, la forme de requête la plus couramment utilisée est`Resources.*[ Type == ‘AWS::S3::Bucket’ ]`. Pour plus d'informations, consultez [Définition des requêtes et filtrage](query-and-filtering.md) pour plus de détails sur l'utilisation et explorez le répertoire [des exemples](https://github.com/aws-cloudformation/cloudformation-guard/tree/main/guard-examples) dans le `cloudformation-guard` GitHub référentiel.

## Utilisation de messages personnalisés dans les clauses
<a name="clauses-custom-messages"></a>

Dans l'exemple suivant, les clauses pour `Template-2` inclure un message personnalisé.

```
Resources.NewVolume.Properties.Size IN r(50,200) 
<<
    EC2Volume size must be between 50 and 200, 
    not including 50 and 200
>>
Resources.NewVolume.Properties.VolumeType IN [ 'io1','io2','gp3' ] <<Allowed Volume Types are io1, io2, and gp3>>
```

## Combinaison de clauses
<a name="combining-clauses"></a>

Dans Guard, chaque clause écrite sur une nouvelle ligne est combinée implicitement à la clause suivante en utilisant une conjonction (logique booléenne`and`). Consultez l'exemple suivant.

```
# clause_A ^ clause_B ^ clause_C
clause_A
clause_B
clause_C
```

Vous pouvez également utiliser la disjonction pour combiner une clause avec la clause suivante en spécifiant `or|OR` à la fin de la première clause.

```
<query> <operator> [query|value literal] [custom message] [or|OR]
```

Dans une clause Guard, les disjonctions sont évaluées en premier, suivies des conjonctions. Les règles de protection peuvent être définies comme une conjonction de disjonctions de clauses (une `and|AND` ou `or|OR` plusieurs) dont l'évaluation correspond à `true` (`PASS`) ou `false` (`FAIL`). Ceci est similaire à la [forme normale conjonctive](https://en.wikipedia.org/wiki/Conjunctive_normal_form). 

Les exemples suivants illustrent l'ordre des évaluations des clauses.

```
# (clause_E v clause_F) ^ clause_G
clause_E OR clause_F
clause_G

# (clause_H v clause_I) ^ (clause_J v clause_K)
clause_H OR
clause_I
clause_J OR
clause_K

# (clause_L v clause_M v clause_N) ^ clause_O
clause_L OR
clause_M OR
clause_N 
clause_O
```

Toutes les clauses basées sur cet exemple `Template-1` peuvent être combinées à l'aide d'une conjonction. Consultez l'exemple suivant.

```
Resources.S3Bucket.Properties.BucketName is_string
Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/
Resources.S3Bucket.Properties.BucketEncryption exists
Resources.S3Bucket.Properties.BucketEncryption is_struct
Resources.S3Bucket.Properties.Tags is_list
Resources.S3Bucket.Properties.Tags !empty
```

## Utiliser des blocs avec les règles de garde
<a name="blocks"></a>

Les blocs sont des compositions qui éliminent la verbosité et la répétition d'un ensemble de clauses, de conditions ou de règles connexes. Il existe trois types de blocs :
+ Blocs de requêtes
+ `when`blocs
+ Blocs de règles nommés

### Blocs de requêtes
<a name="query-blocks"></a>

Les clauses suivantes sont basées sur cet exemple`Template-1`. La conjonction a été utilisée pour combiner les clauses.

```
Resources.S3Bucket.Properties.BucketName is_string
Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/
Resources.S3Bucket.Properties.BucketEncryption exists
Resources.S3Bucket.Properties.BucketEncryption is_struct
Resources.S3Bucket.Properties.Tags is_list
Resources.S3Bucket.Properties.Tags !empty
```

Des parties de l'expression de requête de chaque clause sont répétées. Vous pouvez améliorer la composabilité et supprimer la verbosité et la répétition d'un ensemble de clauses associées ayant le même chemin de requête initial en utilisant un bloc de requête. Le même ensemble de clauses peut être écrit comme indiqué dans l'exemple suivant.

```
Resources.S3Bucket.Properties {
    BucketName is_string
    BucketName != /(?i)encrypt/
    BucketEncryption exists
    BucketEncryption is_struct
    Tags is_list
    Tags !empty
}
```

Dans un bloc de requête, la requête qui précède le bloc définit le contexte des clauses contenues dans le bloc.

Pour plus d'informations sur l'utilisation des blocs, consultez[Composer des blocs de règles nommées](named-rule-block-composition.md).

### `when`blocs
<a name="when-blocks"></a>

Vous pouvez évaluer les blocs de manière conditionnelle en utilisant des `when` blocs, qui se présentent sous la forme suivante.

```
  when <condition> {
       Guard_rule_1
       Guard_rule_2
       ...
   }
```

Le `when` mot clé indique le début du `when` bloc. `condition`est une règle de la Garde. Le bloc n'est évalué que si l'évaluation de la condition aboutit à `true` (`PASS`).

Voici un exemple de `when` bloc basé sur`Template-1`.

```
when Resources.S3Bucket.Properties.BucketName is_string {
     Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/
 }
```

La clause contenue dans le `when` bloc n'est évaluée que si la valeur spécifiée pour `BucketName` est une chaîne. Si la valeur spécifiée pour `BucketName` est référencée dans la `Parameters` section du modèle, comme indiqué dans l'exemple suivant, la clause contenue dans le `when` bloc n'est pas évaluée.

```
Parameters:
   S3BucketName:
     Type: String
 Resources:
   S3Bucket:
     Type: AWS::S3::Bucket
     Properties:
       BucketName: 
         Ref: S3BucketName
     ...
```

### Blocs de règles nommés
<a name="named-rule-blocks"></a>

Vous pouvez attribuer un nom à un ensemble de règles (*ensemble de règles*), puis référencer ces blocs de validation modulaires, appelés blocs de *règles nommées*, dans d'autres règles. Les blocs de règles nommées se présentent sous la forme suivante.

```
  rule <rule name> [when <condition>] {
    Guard_rule_1
    Guard_rule_2
    ...
    }
```

Le `rule` mot clé indique le début du bloc de règles nommées.

`rule name`est une chaîne lisible par l'homme qui identifie de manière unique un bloc de règles nommé. Il s'agit d'une étiquette pour l'ensemble de règles Guard qu'elle encapsule. Dans cette utilisation, le terme *règle de garde* inclut les clauses, les blocs de requêtes, les `when` blocs et les blocs de règles nommées. Le nom de la règle peut être utilisé pour faire référence au résultat de l'évaluation de l'ensemble de règles qu'il encapsule, ce qui rend les blocs de règles nommés réutilisables. Le nom de la règle fournit également un contexte sur les échecs des règles dans les sorties de `test` commande `validate` et. Le nom de la règle est affiché avec le statut d'évaluation du bloc (`PASS`,`FAIL`, ou`SKIP`) dans le résultat d'évaluation du fichier de règles. Consultez l'exemple suivant.

```
# Sample output of an evaluation where check1, check2, and check3 are rule names.
template.json Status = **FAIL**
**SKIP rules**
check1 **SKIP**
**PASS rules**
check2 **PASS**
**FAILED rules**
check3 **FAIL**
```

Vous pouvez également évaluer les blocs de règles nommées de manière conditionnelle en spécifiant le `when` mot clé suivi d'une condition après le nom de la règle.

Voici l'exemple de `when` bloc dont il a été question précédemment dans cette rubrique.

```
rule checkBucketNameStringValue when Resources.S3Bucket.Properties.BucketName is_string {
    Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/
}
```

En utilisant des blocs de règles nommées, ce qui précède peut également être écrit comme suit.

```
rule checkBucketNameIsString {
    Resources.S3Bucket.Properties.BucketName is_string
}
rule checkBucketNameStringValue when checkBucketNameIsString {
    Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/
}
```

Vous pouvez réutiliser et regrouper des blocs de règles nommés avec d'autres règles Guard. Voici quelques exemples.

```
rule rule_name_A {
    Guard_rule_1 OR
    Guard_rule_2
    ...
}

rule rule_name_B {
    Guard_rule_3
    Guard_rule_4
    ...
}

rule rule_name_C {
    rule_name_A OR rule_name_B
}

rule rule_name_D {
    rule_name_A
    rule_name_B
}

rule rule_name_E when rule_name_D {
    Guard_rule_5
    Guard_rule_6
    ...
}
```

## Utilisation des fonctions intégrées
<a name="built-in-functions"></a>

AWS CloudFormation Guard fournit des fonctions intégrées que vous pouvez utiliser dans vos règles pour effectuer des opérations telles que la manipulation de chaînes, l'analyse JSON et la conversion de types de données. Les fonctions ne sont prises en charge que par l'affectation à une variable.

### Principales fonctions
<a name="key-functions"></a>

`json_parse(json_string)`  
Analyse les chaînes JSON en ligne à partir d'un modèle. Après l'analyse, vous pouvez évaluer les propriétés de l'objet obtenu.

`count(collection)`  
Renvoie le nombre d'éléments auxquels une requête aboutit.

`regex_replace(base_string, regex_to_extract, regex_replacement)`  
Remplace des parties d'une chaîne à l'aide d'expressions régulières.

Pour une liste complète des fonctions disponibles, notamment la manipulation de chaînes, les opérations de collecte et les fonctions de conversion de type de données, consultez la [documentation des fonctions](https://github.com/aws-cloudformation/cloudformation-guard/blob/main/docs/FUNCTIONS.md) dans le GitHub référentiel Guard.