

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# AWS CloudFormation Guard Reglas de escritura
<a name="writing-rules"></a>

En AWS CloudFormation Guard, las *reglas son reglas*. policy-as-code Las reglas se escriben en el lenguaje específico de dominio (DSL) de Guard con las que se pueden validar los datos con formato JSON o YAML. *Las reglas se componen de cláusulas.*

Puede guardar las reglas escritas con Guard DSL en archivos de texto sin formato que utilicen cualquier extensión de archivo.

*Puede crear varios archivos de reglas y clasificarlos como un conjunto de reglas.* Los conjuntos de reglas te permiten validar tus datos con formato JSON o YAML comparándolos con varios archivos de reglas al mismo tiempo.

**Topics**
+ [Cláusulas](#clauses)
+ [Uso de consultas en las cláusulas](#clauses-queries)
+ [Uso de operadores en cláusulas](#clauses-operators)
+ [Uso de mensajes personalizados en las cláusulas](#clauses-custom-messages)
+ [Combinación de cláusulas](#combining-clauses)
+ [Uso de bloques con reglas de guardia](#blocks)
+ [Uso de funciones integradas](#built-in-functions)
+ [Definición de consultas y filtrado de Guard](query-and-filtering.md)
+ [Asignación y referencia de variables en las reglas de Guard](variables.md)
+ [Componer bloques de reglas con nombre en AWS CloudFormation Guard](named-rule-block-composition.md)
+ [Redacción de cláusulas para realizar evaluaciones sensibles al contexto](context-aware-evaluations.md)

## Cláusulas
<a name="clauses"></a>

Las cláusulas son expresiones booleanas que se evalúan como true (`PASS`) o false (`FAIL`). Las cláusulas utilizan operadores binarios para comparar dos valores u operadores unarios que funcionan con un único valor.

**Ejemplos de cláusulas unarias**

La siguiente cláusula unaria evalúa si la colección `TcpBlockedPorts` está vacía.

```
InputParameters.TcpBlockedPorts not empty
```

La siguiente cláusula unaria evalúa si la `ExecutionRoleArn` propiedad es una cadena.

```
Properties.ExecutionRoleArn is_string
```

**Ejemplos de cláusulas binarias**

La siguiente cláusula binaria evalúa si la `BucketName` propiedad contiene la cadena`encrypted`, independientemente de las mayúsculas y minúsculas.

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

La siguiente cláusula binaria evalúa si la `ReadCapacityUnits` propiedad es inferior o igual a 5000.

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

### Sintaxis para escribir las cláusulas de la regla de Guard
<a name="clauses-syntax"></a>

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

### Propiedades de las cláusulas de las reglas de Guard
<a name="clauses-properties"></a>

`query`  <a name="clauses-properties-query"></a>
Expresión separada por puntos (`.`) escrita para recorrer datos jerárquicos. Las expresiones de consulta pueden incluir expresiones de filtro para dirigirse a un subconjunto de valores. Las consultas se pueden asignar a variables para que pueda escribirlas una vez y hacer referencia a ellas en cualquier otro lugar de un conjunto de reglas, lo que le permitirá acceder a los resultados de las consultas.  
Para obtener más información sobre cómo escribir consultas y filtrar, consulte[Definición de consultas y filtrado](query-and-filtering.md).  
 *Obligatorio*: sí

`operator`  <a name="clauses-properties-operator"></a>
Operador binario o unario que ayuda a comprobar el estado de la consulta. El lado izquierdo (LHS) de un operador binario debe ser una consulta y el lado derecho (RHS) debe ser una consulta o un valor literal.  
 *Operadores binarios compatibles*: `==` (Igual) \| `!=` (No igual a) \| `>` (Mayor que) \| `>=` (Mayor o igual a) \| `<` (Menor que) \| `<=` (Menor que o igual a) \| `IN` (En forma de lista [x, y, z]  
 *Operadores unarios compatibles*: `exists` \| `empty` \| `is_string` \| `is_list` \| `is_struct` `not(!)`  
 *Obligatorio*: sí

`query|value literal`  <a name="clauses-properties-value-literal"></a>
Una consulta o un valor literal compatible, como `string` o`integer(64)`.   
*Valores literales admitidos*:  
+ Todos los tipos primitivos: `string``integer(64)`,,`float(64)`,`bool`, `char` `regex`
+ Todos los tipos de rangos especializados para expresar `integer(64)``float(64)`, o `char` rangos expresados como:
  + `r[<lower_limit>, <upper_limit>]`, que se traduce en cualquier valor `k` que satisfaga la siguiente expresión: `lower_limit <= k <= upper_limit`
  + `r[<lower_limit>, <upper_limit>`), que se traduce en cualquier valor `k` que satisfaga la siguiente expresión: `lower_limit <= k < upper_limit`
  + `r(<lower_limit>, <upper_limit>]`, que se traduce en cualquier valor `k` que satisfaga la siguiente expresión: `lower_limit < k <= upper_limit`
  + `r(<lower_limit>, <upper_limit>),`que se traduce en cualquier valor `k` que satisfaga la siguiente expresión: `lower_limit < k < upper_limit`
+ Matrices asociativas (mapas) para datos de estructura clave-valor anidados. Por ejemplo:

  `{ "my-map": { "nested-maps": [ { "key": 10, "value": 20 } ] } }`
+ Matrices de tipos primitivos o tipos de matrices asociativas
 *Obligatorio*: condicional; obligatorio cuando se utiliza un operador binario.

`custom message`  <a name="clauses-properties-custom-message"></a>
Cadena que proporciona información sobre la cláusula. El mensaje se muestra en las salidas detalladas de los `test` comandos `validate` y y puede resultar útil para comprender o depurar la evaluación de las reglas en datos jerárquicos.  
 *Obligatorio*: no

## Uso de consultas en las cláusulas
<a name="clauses-queries"></a>

Para obtener información sobre cómo escribir consultas, consulte [Definición de consultas y filtrado](query-and-filtering.md) y[Asignación y referencia de variables en las reglas de Guard](variables.md).

## Uso de operadores en cláusulas
<a name="clauses-operators"></a>

A continuación se muestran ejemplos CloudFormation de plantillas `Template-1` y`Template-2`. Para demostrar el uso de operadores compatibles, las consultas y cláusulas de ejemplo de esta sección hacen referencia a estas plantillas de ejemplo.

**Plantilla-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
```

**Plantilla-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
```

### Ejemplos de cláusulas que utilizan operadores unarios
<a name="clauses-unary-operators"></a>
+ `empty`— Comprueba si una colección está vacía. También se puede utilizar para comprobar si una consulta tiene valores en un dato jerárquico, ya que las consultas dan como resultado una recopilación. No se puede usar para comprobar si las consultas con valores de cadena tienen definida una cadena vacía (`""`). Para obtener más información, consulte [Definición de consultas y filtrado](query-and-filtering.md).

  La siguiente cláusula comprueba si la plantilla tiene uno o más recursos definidos. Se evalúa `PASS` porque un recurso con el identificador lógico `S3Bucket` está definido en`Template-1`.

  ```
  Resources !empty
  ```

  La siguiente cláusula comprueba si hay una o más etiquetas definidas para el `S3Bucket` recurso. Se evalúa como `PASS` porque `S3Bucket` tiene dos etiquetas definidas para la `Tags` propiedad en`Template-1`.

  ```
  Resources.S3Bucket.Properties.Tags !empty
  ```
+ `exists`— Comprueba si cada aparición de la consulta tiene un valor y se puede utilizar en lugar de`!= null`.

  La siguiente cláusula comprueba si la `BucketEncryption` propiedad está definida para`S3Bucket`. Se evalúa como `PASS` porque `BucketEncryption` se define para `S3Bucket` en`Template-1`.

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

**nota**  
Las `not exists` comprobaciones `empty` y se evalúan `true` para detectar claves de propiedad faltantes al recorrer los datos de entrada. Por ejemplo, si la `Properties` sección no está definida en la plantilla de`S3Bucket`, la cláusula se `Resources.S3Bucket.Properties.Tag empty` evalúa como. `true` Las `exists` marcas y `empty` no muestran la ruta del puntero JSON dentro del documento en los mensajes de error. Ambas cláusulas suelen tener errores de recuperación que no mantienen esta información de recorrido.
+ `is_string`— Comprueba si cada aparición de la consulta es de `string` tipo.

  La siguiente cláusula comprueba si se ha especificado un valor de cadena para la `BucketName` propiedad del `S3Bucket` recurso. Se evalúa `PASS` porque el valor de cadena `"MyServiceS3Bucket"` está especificado `BucketName` en`Template-1`.

  ```
  Resources.S3Bucket.Properties.BucketName is_string
  ```
+ `is_list`— Comprueba si cada aparición de la consulta es del `list` tipo.

  La siguiente cláusula comprueba si se ha especificado una lista para la `Tags` propiedad del `S3Bucket` recurso. El resultado es `PASS` porque se especifican dos pares clave-valor en. `Tags` `Template-1`

  ```
  Resources.S3Bucket.Properties.Tags is_list
  ```
+ `is_struct`— Comprueba si cada aparición de la consulta son datos estructurados.

  La siguiente cláusula comprueba si los datos estructurados están especificados para la `BucketEncryption` propiedad del `S3Bucket` recurso. Se evalúa como `PASS` porque `BucketEncryption` se especifica mediante el tipo de `ServerSideEncryptionConfiguration` propiedad {{(object)}} en`Template-1`.

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

**nota**  
Para comprobar el estado inverso, puede usar el operador (` not !`) con los operadores `is_string``is_list`, y`is_struct`.

### Ejemplos de cláusulas que utilizan operadores binarios
<a name="clauses-binary-operators"></a>

La siguiente cláusula comprueba si el valor especificado para la `BucketName` propiedad del `S3Bucket` recurso `Template-1` contiene la cadena`encrypt`, independientemente de las mayúsculas y minúsculas. Esto se `PASS` debe a que el nombre del depósito especificado `"MyServiceS3Bucket"` no contiene la cadena`encrypt`.

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

La siguiente cláusula comprueba si el valor especificado para la `Size` propiedad del `NewVolume` recurso `Template-2` se encuentra dentro de un rango específico: 50 <= `Size` <= 200. Se evalúa como `PASS` porque `100` está especificado para. `Size`

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

La siguiente cláusula comprueba si el valor especificado para la `VolumeType` propiedad del `NewVolume` recurso `Template-2` es `io1``io2`, o`gp3`. Se evalúa como `PASS` porque `io1` está especificado para`NewVolume`.

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

**nota**  
Las consultas de ejemplo de esta sección muestran el uso de operadores que utilizan los recursos con una IDs `S3Bucket` y `NewVolume` lógica. Los nombres de los recursos suelen estar definidos por el usuario y se pueden nombrar arbitrariamente en una plantilla de infraestructura como código (IaC). Para escribir una regla que sea genérica y se aplique a todos los `AWS::S3::Bucket` recursos definidos en la plantilla, la forma de consulta más común utilizada es. `Resources.*[ Type == ‘AWS::S3::Bucket’ ]` Para obtener más información, consulta [Definición de consultas y filtrado](query-and-filtering.md) los detalles sobre el uso y explora el directorio de [ejemplos](https://github.com/aws-cloudformation/cloudformation-guard/tree/main/guard-examples) del `cloudformation-guard` GitHub repositorio.

## Uso de mensajes personalizados en las cláusulas
<a name="clauses-custom-messages"></a>

En el siguiente ejemplo, las cláusulas para `Template-2` incluir un mensaje personalizado.

```
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>>
```

## Combinación de cláusulas
<a name="combining-clauses"></a>

En Guard, cada cláusula escrita en una nueva línea se combina implícitamente con la siguiente mediante una conjunción (lógica booleana`and`). Consulte el siguiente ejemplo.

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

También puedes usar la disyunción para combinar una cláusula con la siguiente especificándola `or|OR` al final de la primera cláusula.

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

En una cláusula de guarda, las disyunciones se evalúan primero, seguidas de las conjunciones. Las reglas de protección se pueden definir como una combinación de disyunción de cláusulas (una `and|AND` de `or|OR` s) que dan como resultado () o `true` (`PASS`). `false` `FAIL` Es similar a la forma [normal conjuntiva.](https://en.wikipedia.org/wiki/Conjunctive_normal_form) 

Los siguientes ejemplos muestran el orden de evaluación de las cláusulas.

```
# (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
```

Todas las cláusulas que se basan en el ejemplo se `Template-1` pueden combinar mediante la conjunción. Consulte el siguiente ejemplo.

```
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
```

## Uso de bloques con reglas de guardia
<a name="blocks"></a>

Los bloques son composiciones que eliminan la verbosidad y la repetición de un conjunto de cláusulas, condiciones o reglas relacionadas. Hay tres tipos de bloques:
+ Bloques de consultas
+ `when`bloques
+ bloques con reglas nombradas

### Bloques de consultas
<a name="query-blocks"></a>

A continuación se muestran las cláusulas que se basan en el ejemplo`Template-1`. Se utilizó la conjunción para combinar las cláusulas.

```
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
```

Se repiten partes de la expresión de consulta de cada cláusula. Puede mejorar la componibilidad y eliminar la verbosidad y la repetición de un conjunto de cláusulas relacionadas con la misma ruta de consulta inicial mediante el uso de un bloque de consulta. Se puede escribir el mismo conjunto de cláusulas, como se muestra en el siguiente ejemplo.

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

En un bloque de consulta, la consulta que precede al bloque establece el contexto de las cláusulas del bloque.

Para obtener más información sobre el uso de bloques, consulte[Composición de bloques de reglas nombradas](named-rule-block-composition.md).

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

Puede evaluar los bloques de forma condicional mediante `when` bloques, que adoptan la siguiente forma.

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

La `when` palabra clave designa el inicio del `when` bloque. `condition`es una regla de guardia. El bloque solo se evalúa si la evaluación de la condición da como resultado `true` (`PASS`).

El siguiente es un ejemplo de `when` bloque que se basa en`Template-1`.

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

La cláusula del `when` bloque solo se evalúa si el valor especificado `BucketName` es una cadena. Si `BucketName` se hace referencia al valor especificado en la `Parameters` sección de la plantilla, como se muestra en el siguiente ejemplo, no se evalúa la cláusula del `when` bloque.

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

### Bloques de reglas con nombre
<a name="named-rule-blocks"></a>

*Puede asignar un nombre a un conjunto de reglas (conjunto de reglas) y, a continuación, hacer referencia a estos bloques de validación modulares, denominados bloques de reglas *con nombre, en otras reglas*.* Los bloques de reglas con nombre tienen la siguiente forma.

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

La `rule` palabra clave designa el inicio del bloque de reglas con nombre asignado.

`rule name`es una cadena legible por humanos que identifica de forma única un bloque de reglas con nombre. Es una etiqueta para el conjunto de reglas de Guard que encapsula. En este uso, el término *regla de protección* incluye cláusulas, bloques de consulta, bloques y `when` bloques de reglas con nombre. El nombre de la regla se puede usar para hacer referencia al resultado de la evaluación del conjunto de reglas que encapsula, lo que hace que los bloques de reglas con nombre asignado sean reutilizables. El nombre de la regla también proporciona un contexto sobre los errores de las reglas en las salidas de los comandos `validate` y`test`. El nombre de la regla se muestra junto con el estado de evaluación del bloque (`PASS``FAIL`, o`SKIP`) en el resultado de la evaluación del archivo de reglas. Consulte el siguiente ejemplo.

```
# 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**
```

También puede evaluar los bloques de reglas con nombre de forma condicional especificando la `when` palabra clave seguida de una condición después del nombre de la regla.

A continuación se muestra el `when` bloque de ejemplo que se analizó anteriormente en este tema.

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

Al usar bloques de reglas con nombre, lo anterior también se puede escribir de la siguiente manera.

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

Puedes reutilizar y agrupar bloques de reglas con nombre propio con otras reglas de Guard. A continuación se muestran algunos ejemplos.

```
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
    ...
}
```

## Uso de funciones integradas
<a name="built-in-functions"></a>

AWS CloudFormation Guard proporciona funciones integradas que puede usar en sus reglas para realizar operaciones como la manipulación de cadenas, el análisis de JSON y la conversión de tipos de datos. Las funciones solo se admiten mediante la asignación a una variable.

### Funciones clave
<a name="key-functions"></a>

`json_parse(json_string)`  
Analiza las cadenas JSON en línea de una plantilla. Tras el análisis, puede evaluar las propiedades del objeto resultante.

`count(collection)`  
Devuelve el número de elementos en los que se resuelve una consulta.

`regex_replace(base_string, regex_to_extract, regex_replacement)`  
Sustituye partes de una cadena mediante expresiones regulares.

Para obtener una lista completa de las funciones disponibles, incluidas la manipulación de cadenas, las operaciones de recopilación y las funciones de conversión de tipos de datos, consulte la [documentación de funciones](https://github.com/aws-cloudformation/cloudformation-guard/blob/main/docs/FUNCTIONS.md) en el GitHub repositorio de Guard.