

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Atribuição e referência de variáveis nas regras do Guard
<a name="variables"></a>

Você pode atribuir variáveis em seus arquivos de AWS CloudFormation Guard regras para armazenar informações que você deseja referenciar nas regras do Guard. O Guard suporta a atribuição de variáveis com um único disparo. As variáveis são avaliadas lentamente, o que significa que o Guard só avalia as variáveis quando as regras são executadas.

**Topics**
+ [Atribuição de variáveis](#assigning-variables)
+ [Variáveis de referência](#referencing-variables)
+ [Escopo da variável](#variable-scope)
+ [Exemplos de variáveis nos arquivos de regras do Guard](#variables-examples)

## Atribuição de variáveis
<a name="assigning-variables"></a>

Use a `let` palavra-chave para inicializar e atribuir uma variável. Como prática recomendada, use snake case para nomes de variáveis. As variáveis podem armazenar literais estáticos ou propriedades dinâmicas resultantes de consultas. No exemplo a seguir, a variável `ecs_task_definition_task_role_arn` armazena o valor da string estática`arn:aws:iam:123456789012:role/my-role-name`.

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

No exemplo a seguir, a variável `ecs_tasks` armazena os resultados de uma consulta que pesquisa todos os `AWS::ECS::TaskDefinition` recursos em um CloudFormation modelo. Você pode consultar `ecs_tasks` para acessar informações sobre esses recursos ao escrever regras.

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

## Variáveis de referência
<a name="referencing-variables"></a>

Use o `%` prefixo para referenciar uma variável.

Com base no exemplo da `ecs_task_definition_task_role_arn` variável em[Atribuição de variáveis](#assigning-variables), você pode fazer referência `ecs_task_definition_task_role_arn` na `query|value literal` seção de uma cláusula de regra do Guard. O uso dessa referência garante que o valor especificado para a `TaskDefinitionArn` propriedade de qualquer `AWS::ECS::TaskDefinition` recurso em um CloudFormation modelo seja o valor da string estática`arn:aws:iam:123456789012:role/my-role-name`.

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

Com base no exemplo da `ecs_tasks` variável em[Atribuição de variáveis](#assigning-variables), você pode fazer referência `ecs_tasks` em uma consulta (por exemplo, %ECS\$1tasks.properties). Primeiro, o Guard avalia a variável `ecs_tasks` e depois usa os valores retornados para percorrer a hierarquia. Se a variável for `ecs_tasks` resolvida para valores que não sejam de string, o Guard gerará um erro.

**nota**  
Atualmente, o Guard não oferece suporte a variáveis de referência em mensagens de erro personalizadas.

## Escopo da variável
<a name="variable-scope"></a>

O escopo se refere à visibilidade das variáveis definidas em um arquivo de regras. Um nome de variável só pode ser usado uma vez dentro de um escopo. Há três níveis em que uma variável pode ser declarada ou três escopos de variáveis possíveis:
+ **Nível de arquivo** — Normalmente declaradas na parte superior do arquivo de regras, você pode usar variáveis em nível de arquivo em todas as regras do arquivo de regras. Eles são visíveis em todo o arquivo.

  No arquivo de regras de exemplo a seguir, as variáveis `ecs_task_definition_task_role_arn` e `ecs_task_definition_execution_role_arn` são inicializadas no nível do arquivo.

  ```
  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
  }
  ```
+ **Nível de regra** — Declaradas em uma regra, as variáveis de nível de regra só são visíveis para essa regra específica. Qualquer referência fora da regra resultará em um erro.

  No arquivo de regras de exemplo a seguir, as variáveis `ecs_task_definition_task_role_arn` e `ecs_task_definition_execution_role_arn` são inicializadas no nível da regra. O só `ecs_task_definition_task_role_arn` pode ser referenciado dentro da regra `check_ecs_task_definition_task_role_arn` nomeada. Você só pode referenciar a `ecs_task_definition_execution_role_arn` variável dentro da regra `check_ecs_task_definition_execution_role_arn` nomeada.

  ```
  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
  }
  ```
+ **Nível do bloco** — Declaradas dentro de um bloco, como uma `when` cláusula, as variáveis do nível do bloco só são visíveis para aquele bloco específico. Qualquer referência fora do bloco resultará em um erro.

  No arquivo de regras de exemplo a seguir, as variáveis `ecs_task_definition_task_role_arn` e `ecs_task_definition_execution_role_arn` são inicializadas no nível do bloco dentro do `AWS::ECS::TaskDefinition` bloco de tipos. Você só pode referenciar as `ecs_task_definition_execution_role_arn` variáveis `ecs_task_definition_task_role_arn` e dentro dos blocos `AWS::ECS::TaskDefinition` de tipos para suas respectivas regras.

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

## Exemplos de variáveis nos arquivos de regras do Guard
<a name="variables-examples"></a>

As seções a seguir fornecem exemplos de atribuição estática e dinâmica de variáveis.

### Atribuição estática
<a name="assigning-static-variables"></a>

Veja a seguir um exemplo CloudFormation de modelo.

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

Com base nesse modelo, você pode escrever uma regra chamada `check_ecs_task_definition_task_role_arn` que garante que a `TaskRoleArn` propriedade de todos os recursos do `AWS::ECS::TaskDefinition` modelo seja`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 do escopo da regra, você pode inicializar uma variável chamada `ecs_task_definition_task_role_arn` e atribuir a ela o valor `'arn:aws:iam::123456789012:role/my-role-name'` da string estática. A cláusula de regra verifica se o valor especificado para a `TaskRoleArn` propriedade do `EcsTask` recurso é `arn:aws:iam::123456789012:role/my-role-name` referenciando a `ecs_task_definition_task_role_arn` variável na `query|value literal` seção.

### Atribuição dinâmica
<a name="example-dynamic-assignment"></a>

Veja a seguir um exemplo CloudFormation de modelo.

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

Com base nesse modelo, você pode inicializar uma variável chamada `ecs_tasks` dentro do escopo do arquivo e atribuir a ela a consulta`Resources.*[ Type == 'AWS::ECS::TaskDefinition'`. O Guard consulta todos os recursos no modelo de entrada e armazena informações sobre eles em`ecs_tasks`. Você também pode escrever uma regra chamada `check_ecs_task_definition_task_role_arn` que garanta que a `TaskRoleArn` propriedade de todos os recursos do `AWS::ECS::TaskDefinition` modelo seja `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'
}
```

A cláusula de regra verifica se o valor especificado para a `TaskRoleArn` propriedade do `EcsTask` recurso é `arn:aws:iam::123456789012:role/my-role-name` referenciando a `ecs_task_definition_task_role_arn` variável na `query` seção.

### Impondo a configuração CloudFormation do modelo
<a name="example-3"></a>

Vamos dar uma olhada em um exemplo mais complexo de um caso de uso de produção. Neste exemplo, escrevemos regras do Guard para garantir controles mais rígidos sobre como as tarefas do Amazon ECS são definidas.

Veja a seguir um exemplo CloudFormation de modelo.

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

Com base nesse modelo, escrevemos as seguintes regras para garantir que esses requisitos sejam atendidos:
+ Cada `AWS::ECS::TaskDefinition` recurso no modelo tem uma função de tarefa e uma função de execução anexadas.
+ As funções de tarefa e as funções de execução são funções AWS Identity and Access Management (IAM).
+ As funções são definidas no modelo.
+ A `PermissionsBoundary` propriedade é especificada para cada função.

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