

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Guard 규칙에서 변수 할당 및 참조
<a name="variables"></a>

 AWS CloudFormation Guard 규칙 파일에 변수를 할당하여 Guard 규칙에서 참조하려는 정보를 저장할 수 있습니다. Guard는 원샷 변수 할당을 지원합니다. 변수는 느리게 평가됩니다. 즉, Guard는 규칙이 실행될 때만 변수를 평가합니다.

**Topics**
+ [변수 할당](#assigning-variables)
+ [변수 참조](#referencing-variables)
+ [변수 범위](#variable-scope)
+ [Guard 규칙 파일의 변수 예제](#variables-examples)

## 변수 할당
<a name="assigning-variables"></a>

`let` 키워드를 사용하여 변수를 초기화하고 할당합니다. 변수 이름에는 스네이크 케이스를 사용하는 것이 가장 좋습니다. 변수는 쿼리로 인한 정적 리터럴 또는 동적 속성을 저장할 수 있습니다. 다음 예제에서 변수는 정적 문자열 값를 `ecs_task_definition_task_role_arn` 저장합니다`arn:aws:iam:123456789012:role/my-role-name`.

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

다음 예제에서 변수는 템플릿의 모든 `AWS::ECS::TaskDefinition` 리소스를 CloudFormation 검색하는 쿼리의 결과를 `ecs_tasks` 저장합니다. 규칙을 작성할 때 `ecs_tasks`를 참조하여 해당 리소스에 대한 정보에 액세스할 수 있습니다.

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

## 변수 참조
<a name="referencing-variables"></a>

`%` 접두사를 사용하여 변수를 참조합니다.

의 `ecs_task_definition_task_role_arn` 변수 예제를 기반으로 [변수 할당](#assigning-variables)Guard 규칙 절의 `ecs_task_definition_task_role_arn` `query|value literal` 섹션에서를 참조할 수 있습니다. 이 참조를 사용하면 CloudFormation 템플릿에 있는 `AWS::ECS::TaskDefinition` 리소스의 `TaskDefinitionArn` 속성에 지정된 값이 정적 문자열 값가 됩니다`arn:aws:iam:123456789012:role/my-role-name`.

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

의 `ecs_tasks` 변수 예제를 기반으로 쿼리`ecs_tasks`에서를 참조[변수 할당](#assigning-variables)할 수 있습니다(예: %ecs\$1tasks.Properties). 먼저 Guard는 변수를 평가한 `ecs_tasks` 다음 반환된 값을 사용하여 계층 구조를 통과합니다. 변수가 문자열이 아닌 값으로 `ecs_tasks` 확인되면 Guard에서 오류가 발생합니다.

**참고**  
현재 Guard는 사용자 지정 오류 메시지 내에서 변수 참조를 지원하지 않습니다.

## 변수 범위
<a name="variable-scope"></a>

범위는 규칙 파일에 정의된 변수의 가시성을 나타냅니다. 변수 이름은 범위 내에서 한 번만 사용할 수 있습니다. 변수를 선언할 수 있는 세 가지 수준 또는 세 가지 가능한 변수 범위가 있습니다.
+ **파일 수준 -** 일반적으로 규칙 파일 상단에 선언되며 규칙 파일 내의 모든 규칙에서 파일 수준 변수를 사용할 수 있습니다. 전체 파일에 표시됩니다.

  다음 예제 규칙 파일에서 변수 `ecs_task_definition_task_role_arn` 및 `ecs_task_definition_execution_role_arn`는 파일 수준에서 초기화됩니다.

  ```
  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
  }
  ```
+ **규칙 수준 -** 규칙 내에서 선언된 규칙 수준 변수는 해당 특정 규칙에만 표시됩니다. 규칙 외부에서 참조하면 오류가 발생합니다.

  다음 예제 규칙 파일에서 변수 `ecs_task_definition_task_role_arn` 및 `ecs_task_definition_execution_role_arn`는 규칙 수준에서 초기화됩니다. 는 `check_ecs_task_definition_task_role_arn`명명된 규칙 내에서만 참조할 `ecs_task_definition_task_role_arn` 수 있습니다. `check_ecs_task_definition_execution_role_arn` 명명된 규칙 내에서만 `ecs_task_definition_execution_role_arn` 변수를 참조할 수 있습니다.

  ```
  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
  }
  ```
+ **블록 수준 -** `when` 절과 같은 블록 내에서 선언된 블록 수준 변수는 해당 특정 블록에만 표시됩니다. 블록 외부의 모든 참조로 인해 오류가 발생합니다.

  다음 예제 규칙 파일에서 변수 `ecs_task_definition_task_role_arn` 및 `ecs_task_definition_execution_role_arn`는 `AWS::ECS::TaskDefinition` 유형 블록 내의 블록 수준에서 초기화됩니다. 각 규칙의 `AWS::ECS::TaskDefinition` 유형 블록 내에서만 `ecs_task_definition_task_role_arn` 및 `ecs_task_definition_execution_role_arn` 변수를 참조할 수 있습니다.

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

## Guard 규칙 파일의 변수 예제
<a name="variables-examples"></a>

다음 섹션에서는 변수의 정적 할당과 동적 할당의 예를 제공합니다.

### 정적 할당
<a name="assigning-static-variables"></a>

다음은 CloudFormation 템플릿의 예입니다.

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

이 템플릿을 기반으로 모든 `AWS::ECS::TaskDefinition` 템플릿 리소스의 `TaskRoleArn` 속성이 인지 `check_ecs_task_definition_task_role_arn` 확인하는 라는 규칙을 작성할 수 있습니다`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
}
```

규칙 범위 내에서 라는 변수를 초기화`ecs_task_definition_task_role_arn`하고 정적 문자열 값를 할당할 수 있습니다`'arn:aws:iam::123456789012:role/my-role-name'`. 규칙 절은 `query|value literal` 섹션의 `ecs_task_definition_task_role_arn` 변수를 `arn:aws:iam::123456789012:role/my-role-name` 참조하여 `EcsTask` 리소스의 `TaskRoleArn` 속성에 지정된 값이 인지 확인합니다.

### 동적 할당
<a name="example-dynamic-assignment"></a>

다음은 CloudFormation 템플릿의 예입니다.

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

이 템플릿을 기반으로 파일 범위 `ecs_tasks` 내에서 라는 변수를 초기화하고 쿼리를 할당할 수 있습니다`Resources.*[ Type == 'AWS::ECS::TaskDefinition'`. Guard는 입력 템플릿의 모든 리소스를 쿼리하고 이에 대한 정보를에 저장합니다`ecs_tasks`. 또한 모든 `AWS::ECS::TaskDefinition` 템플릿 리소스의 `TaskRoleArn` 속성`check_ecs_task_definition_task_role_arn`이 `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'
}
```

규칙 절은 `query` 섹션의 `ecs_task_definition_task_role_arn` 변수를 `arn:aws:iam::123456789012:role/my-role-name` 참조하여 `EcsTask` 리소스의 `TaskRoleArn` 속성에 지정된 값이 인지 확인합니다.

### CloudFormation 템플릿 구성 적용
<a name="example-3"></a>

프로덕션 사용 사례의 보다 복잡한 예를 살펴보겠습니다. 이 예제에서는 Amazon ECS 태스크 정의 방법에 대한 보다 엄격한 제어를 보장하기 위해 Guard 규칙을 작성합니다.

다음은 CloudFormation 템플릿의 예입니다.

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

이 템플릿을 기반으로 다음 규칙을 작성하여 이러한 요구 사항이 충족되도록 합니다.
+ 템플릿의 각 `AWS::ECS::TaskDefinition` 리소스에는 태스크 역할과 실행 역할이 모두 연결되어 있습니다.
+ 작업 역할과 실행 역할은 AWS Identity and Access Management (IAM) 역할입니다.
+ 역할은 템플릿에 정의되어 있습니다.
+ `PermissionsBoundary` 속성은 각 역할에 대해 지정됩니다.

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