

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.

# Asignación y referencia de variables en las reglas de Guard
<a name="variables"></a>

Puedes asignar variables en tus archivos de AWS CloudFormation Guard reglas para almacenar la información a la que quieras hacer referencia en tus reglas de Guard. Guard admite la asignación de variables con un solo disparo. Las variables se evalúan de forma perezosa, lo que significa que Guard solo evalúa las variables cuando se ejecutan reglas.

**Topics**
+ [Asignación de variables](#assigning-variables)
+ [Variables de referencia](#referencing-variables)
+ [Ámbito de la variable](#variable-scope)
+ [Ejemplos de variables en los archivos de reglas de Guard](#variables-examples)

## Asignación de variables
<a name="assigning-variables"></a>

Use la `let` palabra clave para inicializar y asignar una variable. Como práctica recomendada, utilice las mayúsculas y minúsculas para los nombres de las variables. Las variables pueden almacenar literales estáticos o propiedades dinámicas resultantes de las consultas. En el siguiente ejemplo, la variable `ecs_task_definition_task_role_arn` almacena el valor `arn:aws:iam:123456789012:role/my-role-name` de cadena estática.

```
let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-role-name'
```

En el siguiente ejemplo, la variable `ecs_tasks` almacena los resultados de una consulta que busca todos los `AWS::ECS::TaskDefinition` recursos de una CloudFormation plantilla. Puede hacer referencia `ecs_tasks` a la información sobre esos recursos para acceder a ellos al escribir reglas.

```
let ecs_tasks = Resources.*[
    Type == 'AWS::ECS::TaskDefinition'
]
```

## Variables de referencia
<a name="referencing-variables"></a>

Use el `%` prefijo para hacer referencia a una variable.

Según el ejemplo de `ecs_task_definition_task_role_arn` variable que aparece en[Asignación de variables](#assigning-variables), puede hacer referencia `ecs_task_definition_task_role_arn` a la `query|value literal` sección de una cláusula de regla de guardia. El uso de esa referencia garantiza que el valor especificado para la `TaskDefinitionArn` propiedad de cualquier `AWS::ECS::TaskDefinition` recurso de una CloudFormation plantilla sea el valor de cadena estática`arn:aws:iam:123456789012:role/my-role-name`.

```
Resources.*.Properties.TaskDefinitionArn == %ecs_task_definition_role_arn
```

Según el ejemplo de `ecs_tasks` variable de[Asignación de variables](#assigning-variables), puede hacer referencia `ecs_tasks` en una consulta (por ejemplo, %ECS\$1Tasks.properties). En primer lugar, Guard evalúa la variable `ecs_tasks` y, a continuación, utiliza los valores devueltos para recorrer la jerarquía. Si la variable se `ecs_tasks` resuelve en valores que no son cadenas, Guard arroja un error.

**nota**  
Actualmente, Guard no admite la referencia a variables dentro de los mensajes de error personalizados.

## Ámbito de la variable
<a name="variable-scope"></a>

El alcance se refiere a la visibilidad de las variables definidas en un archivo de reglas. El nombre de una variable solo se puede usar una vez dentro de un ámbito. Hay tres niveles en los que se puede declarar una variable, o tres posibles ámbitos de variables:
+ A **nivel de archivo**: normalmente se declaran en la parte superior del archivo de reglas, pero se pueden usar variables a nivel de archivo en todas las reglas del archivo de reglas. Están visibles en todo el archivo.

  En el siguiente archivo de reglas de ejemplo, las variables `ecs_task_definition_task_role_arn` y `ecs_task_definition_execution_role_arn` se inicializan a nivel de archivo.

  ```
  let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-task-role-name'
  let ecs_task_definition_execution_role_arn = 'arn:aws:iam::123456789012:role/my-execution-role-name'
  
  rule check_ecs_task_definition_task_role_arn
  {
      Resources.*.Properties.TaskRoleArn == %ecs_task_definition_task_role_arn
  }
  
  rule check_ecs_task_definition_execution_role_arn
  {
      Resources.*.Properties.ExecutionRoleArn == %ecs_task_definition_execution_role_arn
  }
  ```
+ **Nivel de regla**: declaradas dentro de una regla, las variables de nivel de regla solo son visibles para esa regla específica. Cualquier referencia fuera de la regla produce un error.

  En el siguiente archivo de reglas de ejemplo, las variables `ecs_task_definition_task_role_arn` y `ecs_task_definition_execution_role_arn` se inicializan en el nivel de la regla. Solo se `ecs_task_definition_task_role_arn` puede hacer referencia a ellas dentro de la `check_ecs_task_definition_task_role_arn` regla nombrada. Solo puede hacer referencia a la `ecs_task_definition_execution_role_arn` variable dentro de la regla `check_ecs_task_definition_execution_role_arn` nombrada.

  ```
  rule check_ecs_task_definition_task_role_arn
  {
      let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-task-role-name'
      Resources.*.Properties.TaskRoleArn == %ecs_task_definition_task_role_arn
  }
  
  rule check_ecs_task_definition_execution_role_arn
  {
      let ecs_task_definition_execution_role_arn = 'arn:aws:iam::123456789012:role/my-execution-role-name'
      Resources.*.Properties.ExecutionRoleArn == %ecs_task_definition_execution_role_arn
  }
  ```
+ **Nivel de bloque**: declaradas dentro de un bloque, como una `when` cláusula, las variables de nivel de bloque solo son visibles para ese bloque específico. Cualquier referencia fuera del bloque produce un error.

  En el siguiente archivo de reglas de ejemplo, las variables `ecs_task_definition_task_role_arn` y `ecs_task_definition_execution_role_arn` se inicializan a nivel de bloque dentro del `AWS::ECS::TaskDefinition` bloque de tipos. Solo puede hacer referencia a `ecs_task_definition_execution_role_arn` las variables `ecs_task_definition_task_role_arn` y dentro de los bloques de `AWS::ECS::TaskDefinition` tipos para sus reglas respectivas.

  ```
  rule check_ecs_task_definition_task_role_arn
  {
      AWS::ECS::TaskDefinition
      {
          let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-task-role-name'
          Properties.TaskRoleArn == %ecs_task_definition_task_role_arn
      }
  }
  
  rule check_ecs_task_definition_execution_role_arn
  {
      AWS::ECS::TaskDefinition
      {
          let ecs_task_definition_execution_role_arn = 'arn:aws:iam::123456789012:role/my-execution-role-name'
          Properties.ExecutionRoleArn == %ecs_task_definition_execution_role_arn
      }
  }
  ```

## Ejemplos de variables en los archivos de reglas de Guard
<a name="variables-examples"></a>

En las siguientes secciones se proporcionan ejemplos de asignación estática y dinámica de variables.

### Asignación estática
<a name="assigning-static-variables"></a>

A continuación se muestra un ejemplo CloudFormation de plantilla.

```
Resources:
  EcsTask:
    Type: 'AWS::ECS::TaskDefinition'
    Properties:
      TaskRoleArn: 'arn:aws:iam::123456789012:role/my-role-name'
```

Basándose en esta plantilla, puede escribir una regla denominada `check_ecs_task_definition_task_role_arn` que garantice que la `TaskRoleArn` propiedad de todos los recursos de la `AWS::ECS::TaskDefinition` plantilla es`arn:aws:iam::123456789012:role/my-role-name`.

```
rule check_ecs_task_definition_task_role_arn
{
    let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-role-name'
    Resources.*.Properties.TaskRoleArn == %ecs_task_definition_task_role_arn
}
```

Dentro del ámbito de la regla, puede inicializar una variable llamada `ecs_task_definition_task_role_arn` y asignarle el valor `'arn:aws:iam::123456789012:role/my-role-name'` de cadena estática. La cláusula de regla comprueba si el valor especificado para la `TaskRoleArn` propiedad del `EcsTask` recurso es `arn:aws:iam::123456789012:role/my-role-name` haciendo referencia a la `ecs_task_definition_task_role_arn` variable de la sección. `query|value literal`

### Asignación dinámica
<a name="example-dynamic-assignment"></a>

A continuación se muestra un ejemplo CloudFormation de plantilla.

```
Resources:
  EcsTask:
    Type: 'AWS::ECS::TaskDefinition'
    Properties:
      TaskRoleArn: 'arn:aws:iam::123456789012:role/my-role-name'
```

Basándose en esta plantilla, puede inicializar una variable llamada `ecs_tasks` dentro del ámbito del archivo y asignarle la consulta`Resources.*[ Type == 'AWS::ECS::TaskDefinition'`. Guard consulta todos los recursos de la plantilla de entrada y almacena información sobre ellos en `ecs_tasks` ella. También puede escribir una regla llamada `check_ecs_task_definition_task_role_arn` que garantice que la `TaskRoleArn` propiedad de todos los recursos de la `AWS::ECS::TaskDefinition` plantilla sea `arn:aws:iam::123456789012:role/my-role-name`

```
let ecs_tasks = Resources.*[
    Type == 'AWS::ECS::TaskDefinition'
]

rule check_ecs_task_definition_task_role_arn
{
    %ecs_tasks.Properties.TaskRoleArn == 'arn:aws:iam::123456789012:role/my-role-name'
}
```

La cláusula de regla comprueba si el valor especificado para la `TaskRoleArn` propiedad del `EcsTask` recurso es `arn:aws:iam::123456789012:role/my-role-name` haciendo referencia a la `ecs_task_definition_task_role_arn` variable de la `query` sección.

### Hacer cumplir la configuración de la plantilla CloudFormation
<a name="example-3"></a>

Veamos un ejemplo más complejo de un caso de uso de producción. En este ejemplo, escribimos reglas de Guard para garantizar controles más estrictos sobre la forma en que se definen las tareas de Amazon ECS.

La siguiente es una CloudFormation plantilla de ejemplo.

```
Resources:
  EcsTask:
    Type: 'AWS::ECS::TaskDefinition'
    Properties:
      TaskRoleArn: 
        'Fn::GetAtt': [TaskIamRole, Arn]
      ExecutionRoleArn:
        'Fn::GetAtt': [ExecutionIamRole, Arn]

  TaskIamRole:
    Type: 'AWS::IAM::Role'
    Properties:
      PermissionsBoundary: 'arn:aws:iam::123456789012:policy/MyExamplePolicy'

  ExecutionIamRole:
    Type: 'AWS::IAM::Role'
    Properties:
      PermissionsBoundary: 'arn:aws:iam::123456789012:policy/MyExamplePolicy'
```

Basándonos en esta plantilla, escribimos las siguientes reglas para garantizar que se cumplan estos requisitos:
+ Cada `AWS::ECS::TaskDefinition` recurso de la plantilla tiene un rol de tarea y un rol de ejecución adjunto.
+ Los roles de tarea y los roles de ejecución son roles AWS Identity and Access Management (IAM).
+ Los roles se definen en la plantilla.
+ La `PermissionsBoundary` propiedad se especifica para cada función.

```
# Select all Amazon ECS task definition resources from the template
let ecs_tasks = Resources.*[
    Type == 'AWS::ECS::TaskDefinition'
]

# Select a subset of task definitions whose specified value for the TaskRoleArn property is an Fn::Gett-retrievable attribute
let task_role_refs = some %ecs_tasks.Properties.TaskRoleArn.'Fn::GetAtt'[0]

# Select a subset of TaskDefinitions whose specified value for the ExecutionRoleArn property is an Fn::Gett-retrievable attribute
let execution_role_refs = some %ecs_tasks.Properties.ExecutionRoleArn.'Fn::GetAtt'[0]

# Verify requirement #1
rule all_ecs_tasks_must_have_task_end_execution_roles 
    when %ecs_tasks !empty 
{
    %ecs_tasks.Properties {
        TaskRoleArn exists
        ExecutionRoleArn exists
    }
}

# Verify requirements #2 and #3
rule all_roles_are_local_and_type_IAM
    when all_ecs_tasks_must_have_task_end_execution_roles
{
    let task_iam_references = Resources.%task_role_refs
    let execution_iam_reference = Resources.%execution_role_refs

    when %task_iam_references !empty {
        %task_iam_references.Type == 'AWS::IAM::Role'
    }

    when %execution_iam_reference !empty {
        %execution_iam_reference.Type == 'AWS::IAM::Role'
    }
}

# Verify requirement #4
rule check_role_have_permissions_boundary
    when all_ecs_tasks_must_have_task_end_execution_roles
{
    let task_iam_references = Resources.%task_role_refs
    let execution_iam_reference = Resources.%execution_role_refs

    when %task_iam_references !empty {
        %task_iam_references.Properties.PermissionsBoundary exists
    }

    when %execution_iam_reference !empty {
        %execution_iam_reference.Properties.PermissionsBoundary exists
    }
}
```