

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

# AWS CloudFormation Guard 규칙 작성
<a name="writing-rules"></a>

에서 AWS CloudFormation Guard*규칙*은 policy-as-code 규칙입니다. JSON 또는 YAML 형식의 데이터를 검증할 수 있는 규칙을 Guard 도메인별 언어(DSL)로 작성합니다. 규칙은 *절*로 구성됩니다.

Guard DSL을 사용하여 작성된 규칙을 파일 확장명을 사용하는 일반 텍스트 파일에 저장할 수 있습니다.

여러 규칙 파일을 생성하고 *규칙 세트*로 분류할 수 있습니다. 규칙 세트를 사용하면 여러 규칙 파일에 대해 JSON 또는 YAML 형식의 데이터를 동시에 검증할 수 있습니다.

**Topics**
+ [절](#clauses)
+ [절에서 쿼리 사용](#clauses-queries)
+ [절에서 연산자 사용](#clauses-operators)
+ [절에서 사용자 지정 메시지 사용](#clauses-custom-messages)
+ [절 결합](#combining-clauses)
+ [Guard 규칙과 함께 블록 사용](#blocks)
+ [내장 함수 사용](#built-in-functions)
+ [Guard 쿼리 및 필터링 정의](query-and-filtering.md)
+ [Guard 규칙에서 변수 할당 및 참조](variables.md)
+ [에서 명명된 규칙 블록 구성 AWS CloudFormation Guard](named-rule-block-composition.md)
+ [컨텍스트 인식 평가를 수행하기 위한 절 작성](context-aware-evaluations.md)

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

절은 true(`PASS`) 또는 false()로 평가되는 부울 표현식입니다`FAIL`. 절은 이진 연산자를 사용하여 단일 값에서 작동하는 두 값 또는 단항 연산자를 비교합니다.

**단항 절의 예**

다음 단항 절은 컬렉션`TcpBlockedPorts`이 비어 있는지 여부를 평가합니다.

```
InputParameters.TcpBlockedPorts not empty
```

다음 단항 절은 `ExecutionRoleArn` 속성이 문자열인지 여부를 평가합니다.

```
Properties.ExecutionRoleArn is_string
```

**바이너리 절의 예**

다음 바이너리 절은 대/소문자에 `encrypted`관계없이 `BucketName` 속성에 문자열이 포함되어 있는지 여부를 평가합니다.

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

다음 바이너리 절은 `ReadCapacityUnits` 속성이 5,000보다 작거나 같은지 여부를 평가합니다.

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

### Guard 규칙 절 작성을 위한 구문
<a name="clauses-syntax"></a>

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

### Guard 규칙 절의 속성
<a name="clauses-properties"></a>

`query`  <a name="clauses-properties-query"></a>
계층적 데이터를 통과하도록 작성된 점(`.`)으로 구분된 표현식입니다. 쿼리 표현식에는 값의 하위 집합을 대상으로 하는 필터 표현식이 포함될 수 있습니다. 쿼리를 변수에 할당하여 변수를 한 번 작성하고 규칙 세트의 다른 곳에서 참조할 수 있으므로 쿼리 결과에 액세스할 수 있습니다.  
쿼리 작성 및 필터링에 대한 자세한 내용은 섹션을 참조하세요[쿼리 정의 및 필터링](query-and-filtering.md).  
 *필수 항목 여부:* 예

`operator`  <a name="clauses-properties-operator"></a>
쿼리의 상태를 확인하는 데 도움이 되는 단항 또는 이진 연산자입니다. 이진 연산자의 왼쪽(LHS)은 쿼리여야 하며 오른쪽(RHS)은 쿼리 또는 값 리터럴이어야 합니다.  
 *지원되는 이진 연산자*: `==` (같음) \| `!=` (같지 않음) \| `>` (크거나 같음) \| `>=` (`<`작음) \| `<=` (작거나 같음) \| `IN` ([x, y, z] 형식의 목록에서  
 *지원되는 단항 연산자*: `exists` \| `empty` \| `is_string` \| `is_list` \| \| `is_struct` \| `not(!)`  
 *필수 항목 여부:* 예

`query|value literal`  <a name="clauses-properties-value-literal"></a>
쿼리 또는 `string` 또는와 같이 지원되는 값 리터럴입니다`integer(64)`.  
*지원되는 값 리터럴*:  
+ 모든 기본 유형: `string`, `integer(64)`, `float(64)`, `bool`, `char`, `regex` 
+ 다음과 같이 표현되는 `integer(64)`, `float(64)`또는 범위를 표현하기 위한 모든 특수 `char` 범위 유형:
  + `r[<lower_limit>, <upper_limit>]`- 다음 표현식을 `k` 충족하는 모든 값으로 변환됩니다. `lower_limit <= k <= upper_limit` 
  + `r[<lower_limit>, <upper_limit>`)는 다음 표현식을 `k` 충족하는 모든 값으로 변환됩니다. `lower_limit <= k < upper_limit` 
  + `r(<lower_limit>, <upper_limit>]`- 다음 표현식을 `k` 충족하는 모든 값으로 변환됩니다. `lower_limit < k <= upper_limit` 
  + `r(<lower_limit>, <upper_limit>),` 다음 표현식을 `k` 충족하는 모든 값으로 변환됩니다. `lower_limit < k < upper_limit` 
+ 중첩된 키-값 구조 데이터에 대한 연결 배열(맵)입니다. 예제:

  `{ "my-map": { "nested-maps": [ { "key": 10, "value": 20 } ] } }`
+ 프리미티브 유형 또는 연결 배열 유형의 배열
 *필수*: 조건부, 이진 연산자를 사용할 때 필요합니다.

`custom message`  <a name="clauses-properties-custom-message"></a>
절에 대한 정보를 제공하는 문자열입니다. 메시지는 `validate` 및 `test` 명령의 상세 출력에 표시되며 계층적 데이터에 대한 규칙 평가를 이해하거나 디버깅하는 데 유용할 수 있습니다.  
 *필수 항목 여부*: 아니요

## 절에서 쿼리 사용
<a name="clauses-queries"></a>

쿼리 작성에 대한 자세한 내용은 [쿼리 정의 및 필터링](query-and-filtering.md) 및 섹션을 참조하세요[Guard 규칙에서 변수 할당 및 참조](variables.md).

## 절에서 연산자 사용
<a name="clauses-operators"></a>

다음은 CloudFormation 템플릿 `Template-1` 및의 예입니다`Template-2`. 지원되는 연산자의 사용을 보여주기 위해이 섹션의 예제 쿼리 및 절은 이러한 예제 템플릿을 참조합니다.

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

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

### 단항 연산자를 사용하는 절의 예
<a name="clauses-unary-operators"></a>
+ `empty` - 컬렉션이 비어 있는지 확인합니다. 쿼리를 사용하면 컬렉션이 생성되므로 쿼리에 계층적 데이터의 값이 있는지 확인할 수도 있습니다. 이를 사용하여 문자열 값 쿼리에 빈 문자열(`""`)이 정의되어 있는지 확인할 수 없습니다. 자세한 내용은 [쿼리 정의 및 필터링](query-and-filtering.md) 단원을 참조하십시오.

  다음 절은 템플릿에 정의된 리소스가 하나 이상 있는지 확인합니다. 논리적 ID가 인 리소스가에 정의되어 `PASS` 있으므로 로 평가`S3Bucket`됩니다`Template-1`.

  ```
  Resources !empty
  ```

  다음 절은 `S3Bucket` 리소스에 하나 이상의 태그가 정의되어 있는지 확인합니다. 에 `Tags` 속성에 대해 정의된 두 개의 태그`S3Bucket`가 `PASS` 있기 때문에 로 평가됩니다`Template-1`.

  ```
  Resources.S3Bucket.Properties.Tags !empty
  ```
+ `exists` - 쿼리의 각 발생에 값이 있고 대신 사용할 수 있는지 확인합니다`!= null`.

  다음 절은 `BucketEncryption` 속성이에 정의되어 있는지 확인합니다`S3Bucket`. 에서에 대해 `BucketEncryption`가 정의`PASS`되어 있기 때문에 `S3Bucket`로 평가됩니다`Template-1`.

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

**참고**  
`empty` 및 `not exists` 검사는 입력 데이터를 통과할 때 누락된 속성 키가 `true` 있는지 로 평가합니다. 예를 들어 `Properties` 섹션이의 템플릿에 정의되지 않은 경우 절`S3Bucket`은 로 `Resources.S3Bucket.Properties.Tag empty` 평가됩니다`true`. `exists` 및 `empty` 검사는 오류 메시지의 문서 내에 JSON 포인터 경로를 표시하지 않습니다. 이러한 두 절 모두 이러한 순회 정보를 유지하지 않는 검색 오류가 있는 경우가 많습니다.
+ `is_string` - 쿼리의 각 발생이 `string` 유형인지 확인합니다.

  다음 절은 `S3Bucket` 리소스의 `BucketName` 속성에 문자열 값이 지정되었는지 확인합니다. 문자열 값은에서에 대해 지정`PASS`되므로 `BucketName`로 평가`"MyServiceS3Bucket"`됩니다`Template-1`.

  ```
  Resources.S3Bucket.Properties.BucketName is_string
  ```
+ `is_list` - 쿼리의 각 발생이 `list` 유형인지 확인합니다.

  다음 절은 `S3Bucket` 리소스의 `Tags` 속성에 목록이 지정되어 있는지 확인합니다. 에서에 대해 두 개의 키-값 페어가 지정`PASS`되므로 `Tags`로 평가됩니다`Template-1`.

  ```
  Resources.S3Bucket.Properties.Tags is_list
  ```
+ `is_struct` - 쿼리의 각 발생이 구조화된 데이터인지 확인합니다.

  다음 절은 `S3Bucket` 리소스의 `BucketEncryption` 속성에 구조화된 데이터가 지정되어 있는지 확인합니다. 에서 `ServerSideEncryptionConfiguration` 속성 유형{{(객체)}}을 사용하여 `BucketEncryption`를 지정`PASS`하므로 로 평가됩니다`Template-1`.

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

**참고**  
역방향 상태를 확인하려면 (` not !`) 연산자를 , `is_string` `is_list`및 `is_struct` 연산자와 함께 사용할 수 있습니다.

### 이진 연산자를 사용하는 절의 예
<a name="clauses-binary-operators"></a>

다음 절은 대/소문자에 `encrypt`관계없이에서 `S3Bucket` 리소스의 `BucketName` 속성에 지정된 값에 문자열이 `Template-1` 포함되어 있는지 확인합니다. 지정된 버킷 이름에 문자열이 포함되어 `"MyServiceS3Bucket"` 있지 `PASS` 않기 때문에 로 평가됩니다`encrypt`.

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

다음 절은의 `NewVolume` 리소스 `Size` 속성에 지정된 값이 50 <= `Size` <= 200의 특정 범위 `Template-2` 내에 있는지 확인합니다. 에가 지정되어 있기 `PASS` 때문에 로 평가`100`됩니다`Size`.

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

다음 절은에서 `NewVolume` 리소스의 `VolumeType` 속성에 지정된 값이 `Template-2` `io1`, `io2`또는 인지 확인합니다`gp3`. 에가 지정되어 있기 `PASS` 때문에 로 평가`io1`됩니다`NewVolume`.

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

**참고**  
이 섹션의 예제 쿼리는 논리적 IDs `S3Bucket` 및가 있는 리소스를 사용하는 연산자의 사용을 보여줍니다`NewVolume`. 리소스 이름은 종종 사용자 정의이며 코드형 인프라(IaC) 템플릿에서 임의로 명명될 수 있습니다. 일반적이고 템플릿에 정의된 모든 `AWS::S3::Bucket` 리소스에 적용되는 규칙을 작성하려면 가장 일반적으로 사용되는 쿼리 형식은 입니다`Resources.*[ Type == ‘AWS::S3::Bucket’ ]`. 자세한 내용은 [쿼리 정의 및 필터링](query-and-filtering.md)에서 사용에 대한 세부 정보를 확인하고 `cloudformation-guard` GitHub 리포지토리의 [예제](https://github.com/aws-cloudformation/cloudformation-guard/tree/main/guard-examples) 디렉터리를 살펴보세요.

## 절에서 사용자 지정 메시지 사용
<a name="clauses-custom-messages"></a>

다음 예제에서의 절에는 사용자 지정 메시지가 `Template-2` 포함됩니다.

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

## 절 결합
<a name="combining-clauses"></a>

Guard에서 새 줄에 작성된 각 절은 (부울 `and` 로직)을 사용하여 암시적으로 다음 절과 결합됩니다. 다음 예제를 참조하세요.

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

또한 분리를 사용하여 첫 번째 절의 `or|OR` 끝에를 지정하여 절을 다음 절과 결합할 수 있습니다.

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

Guard 절에서는 분리가 먼저 평가되고 그 다음에는 연결이 평가됩니다. 가드 규칙은 (`or|OR`) 또는 `true` ()로 평가되는 절(`and|AND`의 `PASS`)의 분리와 함께 정의할 수 있습니다`false``FAIL`. 이는 [보조 정상 형식과 유사합니다](https://en.wikipedia.org/wiki/Conjunctive_normal_form).

다음 예제에서는 절의 평가 순서를 보여줍니다.

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

예제를 기반으로 하는 모든 절은 함께 사용하여 결합할 `Template-1` 수 있습니다. 다음 예제를 참조하세요.

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

## Guard 규칙과 함께 블록 사용
<a name="blocks"></a>

블록은 일련의 관련 절, 조건 또는 규칙에서 세부 정보 및 반복을 제거하는 구성입니다. 블록에는 세 가지 유형이 있습니다.
+ 쿼리 블록
+ `when` 블록
+ 명명된 규칙 블록

### 쿼리 블록
<a name="query-blocks"></a>

다음은 예제를 기반으로 하는 절입니다`Template-1`. 연결은 절을 결합하는 데 사용되었습니다.

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

각 절의 쿼리 표현식 일부가 반복됩니다. 쿼리 블록을 사용하여 구성 가능성을 개선하고 초기 쿼리 경로가 동일한 관련 절 집합에서 세부 정보 및 반복을 제거할 수 있습니다. 다음 예제와 같이 동일한 절 집합을 작성할 수 있습니다.

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

쿼리 블록에서 블록 앞의 쿼리는 블록 내 절의 컨텍스트를 설정합니다.

블록 사용에 대한 자세한 내용은 섹션을 참조하세요[명명된 규칙 블록 구성](named-rule-block-composition.md).

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

다음 형식의 블록을 사용하여 조건부로 `when` 블록을 평가할 수 있습니다.

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

`when` 키워드는 `when` 블록의 시작을 지정합니다. `condition`는 가드 규칙입니다. 블록은 조건 평가 결과 `true` ()인 경우에만 평가됩니다`PASS`.

다음은를 기반으로 하는 `when` 블록의 예입니다`Template-1`.

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

`when` 블록 내의 절은에 지정된 값이 문자열인 경우에만 평가`BucketName`됩니다. 다음 예제와 같이 템플릿의 `Parameters` 섹션에서에 지정된 값이 참조`BucketName`되는 경우 `when` 블록 내의 절은 평가되지 않습니다.

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

### 명명된 규칙 블록
<a name="named-rule-blocks"></a>

규칙 세트(*규칙 세트*)에 이름을 할당한 다음 다른 규칙에서 *명명된 규칙 블록이라고 하는 이러한 모듈식 검증 블록*을 참조할 수 있습니다. 명명된 규칙 블록의 형식은 다음과 같습니다.

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

`rule` 키워드는 명명된 규칙 블록의 시작을 지정합니다.

`rule name`는 명명된 규칙 블록을 고유하게 식별하는 사람이 읽을 수 있는 문자열입니다. 캡슐화하는 Guard 규칙 세트의 레이블입니다. 이 사용에서 *Guard 규칙*이라는 용어에는 절, 쿼리 블록, `when` 블록 및 명명된 규칙 블록이 포함됩니다. 규칙 이름은 캡슐화된 규칙 세트의 평가 결과를 참조하는 데 사용할 수 있으며, 이를 통해 명명된 규칙 블록을 재사용할 수 있습니다. 규칙 이름은 `validate` 및 `test` 명령 출력의 규칙 실패에 대한 컨텍스트도 제공합니다. 규칙 이름은 규칙 파일의 평가 출력에 블록의 평가 상태(`PASS`, `FAIL`또는 `SKIP`)와 함께 표시됩니다. 다음 예제를 참조하세요.

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

`when` 키워드 뒤에 규칙 이름 뒤에 조건을 지정하여 명명된 규칙 블록을 조건부로 평가할 수도 있습니다.

다음은이 주제에서 앞서 설명한 예제 `when` 블록입니다.

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

명명된 규칙 블록을 사용하여 앞의 내용을 다음과 같이 작성할 수도 있습니다.

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

다른 Guard 규칙과 함께 명명된 규칙 블록을 재사용하고 그룹화할 수 있습니다. 다음은 몇 가지 예입니다.

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

## 내장 함수 사용
<a name="built-in-functions"></a>

AWS CloudFormation Guard 는 규칙에서 문자열 조작, JSON 구문 분석 및 데이터 유형 변환과 같은 작업을 수행하는 데 사용할 수 있는 내장 함수를 제공합니다. 함수는 변수에 대한 할당을 통해서만 지원됩니다.

### 주요 함수
<a name="key-functions"></a>

`json_parse(json_string)`  
템플릿의 인라인 JSON 문자열을 구문 분석합니다. 구문 분석 후 결과 객체의 속성을 평가할 수 있습니다.

`count(collection)`  
쿼리가 해결하는 항목 수를 반환합니다.

`regex_replace(base_string, regex_to_extract, regex_replacement)`  
정규식을 사용하여 문자열의 일부를 대체합니다.

문자열 조작, 수집 작업 및 데이터 유형 변환 함수를 포함하여 사용 가능한 함수의 전체 목록은 Guard GitHub 리포지토리의 [함수 설명서를 참조하세요](https://github.com/aws-cloudformation/cloudformation-guard/blob/main/docs/FUNCTIONS.md).