

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

# Guard Hook의 리소스를 평가하기 위한 Guard 규칙 작성
<a name="guard-hooks-write-rules"></a>

AWS CloudFormation Guard 는 policy-as-code 작성하는 데 사용할 수 있는 오픈 소스 및 범용 도메인별 언어(DSL)입니다. 이 주제에서는 Guard를 사용하여 Guard Hook에서 실행하여 CloudFormation 및 AWS Cloud Control API 작업을 자동으로 평가할 수 있는 예제 규칙을 작성하는 방법을 설명합니다. 또한 Guard Hook 실행 시기에 따라 Guard 규칙에 사용할 수 있는 다양한 유형의 입력에 중점을 둡니다. Guard Hook는 다음 유형의 작업 중에 실행되도록 구성할 수 있습니다.
+ 리소스 작업
+ 스택 작업
+ 변경 세트 작업

가드 규칙 작성에 대한 자세한 내용은 [규칙 작성을 참조하세요 AWS CloudFormation Guard](https://docs.aws.amazon.com/cfn-guard/latest/ug/writing-rules.html).

**Topics**
+ [리소스 작업 가드 규칙](#guard-hooks-write-rules-resource-operations)
+ [스택 작업 가드 규칙](#guard-hooks-write-rules-stack-operations)
+ [변경 세트 작업 가드 규칙](#guard-hooks-write-rules-change-set-operations)

## 리소스 작업 가드 규칙
<a name="guard-hooks-write-rules-resource-operations"></a>

리소스를 생성, 업데이트 또는 삭제할 때마다 리소스 작업으로 간주됩니다. 예를 들어 새 리소스를 생성하는 CloudFormation 스택 업데이트를 실행하면 리소스 작업이 완료됩니다. Cloud Control API를 사용하여 리소스를 생성, 업데이트 또는 삭제할 때 리소스 작업으로도 간주됩니다. 후크의 구성에서 `RESOURCE` 및 `CLOUD_CONTROL` 작업을 대상으로 Guard Hook를 구성할 수 `TargetOperations` 있습니다. Guard Hook에서 리소스 작업을 평가하면 Guard 엔진이 리소스 입력을 평가합니다.

**Topics**
+ [가드 리소스 입력 구문](#guard-hooks-write-rules-resource-operations-input)
+ [Guard 리소스 작업 입력 예제](#guard-hooks-write-rules-resource-operations-example)
+ [리소스 변경에 대한 가드 규칙](#guard-hooks-rules-resource-changes)

### 가드 리소스 입력 구문
<a name="guard-hooks-write-rules-resource-operations-input"></a>

Guard 리소스 입력은 Guard 규칙에서 평가할 수 있는 데이터입니다.

다음은 리소스 입력의 셰이프 예제입니다.

```
HookContext:
  AWSAccountID: String
  StackId: String
  HookTypeName: String
  HookTypeVersion: String
  InvocationPoint: [CREATE_PRE_PROVISION, UPDATE_PRE_PROVISION, DELETE_PRE_PROVISION]
  TargetName: String
  TargetType: RESOURCE
  TargetLogicalId: String
  ChangeSetId: String
Resources:
  {ResourceLogicalID}:
    ResourceType: {ResourceType}
    ResourceProperties:
        {ResourceProperties}
Previous:
  ResourceLogicalID:
    ResourceType: {ResourceType}
    ResourceProperties:
        {PreviousResourceProperties}
```

`HookContext`  <a name="guard-hook-resource-hookcontext"></a>  
`AWSAccountID`  <a name="guard-hook-resource-awsaccountid"></a>
평가 중인 리소스가 AWS 계정 포함된의 ID입니다.  
`StackId`  <a name="guard-hook-resource-stackid"></a>
리소스 작업의 일부인 CloudFormation 스택의 스택 ID입니다. 호출자가 Cloud Control API인 경우 비어 있습니다.  
`HookTypeName`  <a name="guard-hook-resource-hooktypename"></a>
실행 중인 후크의 이름입니다.  
`HookTypeVersion`  <a name="guard-hook-resource-hooktypeversion"></a>
실행 중인 후크의 버전입니다.  
`InvocationPoint`  <a name="guard-hook-resource-invocationpoint"></a>
후크가 실행되는 프로비저닝 로직의 정확한 지점입니다.  
*유효한 값*: (`CREATE_PRE_PROVISION` \$1 `UPDATE_PRE_PROVISION` \$1 `DELETE_PRE_PROVISION`)  
`TargetName`  <a name="guard-hook-resource-targetname"></a>
평가 중인 대상 유형입니다. 예: `AWS::S3::Bucket`.  
`TargetType`  <a name="guard-hook-resource-targettype"></a>
평가 중인 대상 유형입니다. 예: `AWS::S3::Bucket`. Cloud Control API로 프로비저닝된 리소스의 경우이 값은 입니다`RESOURCE`.  
`TargetLogicalId`  <a name="guard-hook-resource-targetlogicalid"></a>
평가 중인 리소스`TargetLogicalId`의 입니다. 후크의 오리진이 CloudFormation인 경우 리소스의 논리적 ID(논리적 이름이라고도 함)가 됩니다. 후크의 오리진이 Cloud Control API인 경우 구성된 값이 됩니다.  
`ChangeSetId`  <a name="guard-hook-resource-changesetid"></a>
후크 호출을 유발하기 위해 실행된 변경 세트 ID입니다. 리소스 변경이 Cloud Control API 또는 , `create-stack` `update-stack`또는 `delete-stack` 작업에 의해 시작된 경우이 값은 비어 있습니다.

`Resources`  <a name="guard-hook-resource-resources"></a>  
`ResourceLogicalID`  <a name="guard-hook-resource-current-resourcelogicalid"></a>
CloudFormation에서 작업을 시작하면 `ResourceLogicalID`는 CloudFormation 템플릿에 있는 리소스의 논리적 ID입니다.  
Cloud Control API에서 작업을 시작하면 `ResourceLogicalID`는 리소스 유형, 이름, 작업 ID 및 요청 ID의 조합입니다.  
`ResourceType`  <a name="guard-hook-resource-current-resourcetype"></a>
리소스의 유형 이름입니다(예: `AWS::S3::Bucket`).  
`ResourceProperties`  <a name="guard-hook-resource-current-resourceproperties"></a>
수정 중인 리소스의 제안된 속성입니다. Guard Hook가 CloudFormation 리소스 변경에 대해 실행 중이면 모든 함수, 파라미터 및 변환이 완전히 해결됩니다. 리소스가 삭제되는 경우이 값은 비어 있습니다.

`Previous`  <a name="guard-hook-resource-previous"></a>  
`ResourceLogicalID`  <a name="guard-hook-resource-previous-resourcelogicalid"></a>
CloudFormation에서 작업을 시작하면 `ResourceLogicalID`는 CloudFormation 템플릿에 있는 리소스의 논리적 ID입니다.  
Cloud Control API에서 작업을 시작하면 `ResourceLogicalID`는 리소스 유형, 이름, 작업 ID 및 요청 ID의 조합입니다.  
`ResourceType`  <a name="guard-hook-resource-previous-resourcetype"></a>
리소스의 유형 이름입니다(예: `AWS::S3::Bucket`).  
`ResourceProperties`  <a name="guard-hook-resource-previous-resourceproperties"></a>
수정 중인 리소스와 연결된 현재 속성입니다. 리소스가 삭제되는 경우이 값은 비어 있습니다.

### Guard 리소스 작업 입력 예제
<a name="guard-hooks-write-rules-resource-operations-example"></a>

다음 예제 입력은 업데이트할 `AWS::S3::Bucket` 리소스의 정의를 수신하는 Guard Hook를 보여줍니다. 이는 Guard에서 평가에 사용할 수 있는 데이터입니다.

```
HookContext:
  AwsAccountId: "123456789012"
  StackId: "arn:aws:cloudformation:us-west-2:123456789012:stack/MyStack/1a2345b6-0000-00a0-a123-00abc0abc000"
  HookTypeName: org::s3policy::hook
  HookTypeVersion: "00001"
  InvocationPoint: UPDATE_PRE_PROVISION
  TargetName: AWS::S3::Bucket
  TargetType: RESOURCE
  TargetLogicalId: MyS3Bucket
  ChangeSetId: ""
Resources:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: amzn-s3-demo-bucket
      ObjectLockEnabled: true
Previous:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: amzn-s3-demo-bucket
      ObjectLockEnabled: false
```

리소스 유형에 사용할 수 있는 모든 속성을 보려면 섹션을 참조하세요[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-s3-bucket.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-s3-bucket.html).

### 리소스 변경에 대한 가드 규칙
<a name="guard-hooks-rules-resource-changes"></a>

Guard Hook는 리소스 변경을 평가할 때 후크로 구성된 모든 규칙을 다운로드하는 것으로 시작합니다. 그런 다음 이러한 규칙은 리소스 입력에 대해 평가됩니다. 규칙이 평가에 실패하면 후크가 실패합니다. 실패가 없으면 후크가 통과합니다.

다음 예제는 `ObjectLockEnabled` 속성이 `AWS::S3::Bucket` 리소스 유형에 `true` 대한 것인지 평가하는 Guard 규칙입니다.

```
let s3_buckets_default_lock_enabled = Resources.*[ Type == 'AWS::S3::Bucket']

rule S3_BUCKET_DEFAULT_LOCK_ENABLED when %s3_buckets_default_lock_enabled !empty {
  %s3_buckets_default_lock_enabled.Properties.ObjectLockEnabled exists
  %s3_buckets_default_lock_enabled.Properties.ObjectLockEnabled == true
  <<
    Violation: S3 Bucket ObjectLockEnabled must be set to true.
    Fix: Set the S3 property ObjectLockEnabled parameter to true.
  >>
}
```

이 규칙은 다음 입력에 대해 실행될 때 `ObjectLockEnabled` 속성이 로 설정되지 않았으므로 실패합니다`true`.

```
Resources:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: amzn-s3-demo-bucket 
      ObjectLockEnabled: false
```

이 규칙은 다음 입력에 대해 실행될 때 `ObjectLockEnabled`가 로 설정되어 있으므로 통과합니다`true`.

```
Resources:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: amzn-s3-demo-bucket
      ObjectLockEnabled: true
```

후크가 실패하면 실패한 규칙이 CloudFormation 또는 Cloud Control API로 다시 전파됩니다. Guard Hook에 대해 로깅 버킷이 구성된 경우 추가 규칙 피드백이 제공됩니다. 이 추가 피드백에는 `Violation` 및 `Fix` 정보가 포함됩니다.

## 스택 작업 가드 규칙
<a name="guard-hooks-write-rules-stack-operations"></a>

CloudFormation 스택이 생성, 업데이트 또는 삭제되면 새 템플릿을 평가하여 시작하여 스택 작업이 진행되지 않도록 Guard Hook를 구성할 수 있습니다. 후크의 구성에서 `STACK` 작업을 대상으로 Guard Hook를 구성할 수 `TargetOperations` 있습니다.

**Topics**
+ [가드 스택 입력 구문](#guard-hooks-write-rules-stack-operations-input)
+ [Guard 스택 작업 입력 예제](#guard-hooks-write-rules-stack-operations-example)
+ [스택 변경에 대한 가드 규칙](#guard-hooks-rules-stack-changes)

### 가드 스택 입력 구문
<a name="guard-hooks-write-rules-stack-operations-input"></a>

Guard 스택 작업에 대한 입력은 Guard 규칙이 평가할 전체 CloudFormation 템플릿을 제공합니다.

다음은 스택 입력의 셰이프 예제입니다.

```
HookContext:
  AWSAccountID: String
  StackId: String
  HookTypeName: String
  HookTypeVersion: String
  InvocationPoint: [CREATE_PRE_PROVISION, UPDATE_PRE_PROVISION, DELETE_PRE_PROVISION]
  TargetName: String
  TargetType:STACK
  ChangeSetId: String
{Proposed CloudFormation Template}
Previous:
    {CloudFormation Template}
```

`HookContext`  <a name="guard-hook-stack-hookcontext"></a>  
`AWSAccountID`  <a name="guard-hook-stack-awsaccountid"></a>
리소스가 AWS 계정 포함된의 ID입니다.  
`StackId`  <a name="guard-hook-stack-stackid"></a>
스택 작업의 일부인 CloudFormation 스택의 스택 ID입니다.  
`HookTypeName`  <a name="guard-hook-stack-hooktypename"></a>
실행 중인 후크의 이름입니다.  
`HookTypeVersion`  <a name="guard-hook-stack-hooktypeversion"></a>
실행 중인 후크의 버전입니다.  
`InvocationPoint`  <a name="guard-hook-stack-invocationpoint"></a>
후크가 실행되는 프로비저닝 로직의 정확한 지점입니다.  
*유효한 값*: (`CREATE_PRE_PROVISION` \$1 `UPDATE_PRE_PROVISION` \$1 `DELETE_PRE_PROVISION`)  
`TargetName`  <a name="guard-hook-stack-targetname"></a>
평가 중인 스택의 이름입니다.  
`TargetType`  <a name="guard-hook-stack-targettype"></a>
이 값은 스택 수준 후크로 실행될 `STACK` 때 입니다.  
`ChangeSetId`  <a name="guard-hook-stack-changesetid"></a>
후크 호출을 유발하기 위해 실행된 변경 세트 ID입니다. 스택 작업이 `create-stack`, `update-stack`또는 `delete-stack` 작업에 의해 시작된 경우이 값은 비어 있습니다.

`Proposed CloudFormation Template`  <a name="guard-hook-stack-template-current-template"></a>
CloudFormation `create-stack` 또는 `update-stack` 작업에 전달된 전체 CloudFormation 템플릿 값입니다. 여기에는 `Resources`, `Outputs`및가 포함됩니다`Properties`. CloudFormation에 제공된 내용에 따라 JSON 또는 YAML 문자열일 수 있습니다.  
`delete-stack` 작업에서이 값은 비어 있습니다.

`Previous`  <a name="guard-hook-stack-template-previous-template"></a>
마지막으로 성공적으로 배포된 CloudFormation 템플릿입니다. 스택이 생성되거나 삭제되는 경우이 값은 비어 있습니다.  
`delete-stack` 작업에서이 값은 비어 있습니다.

**참고**  
제공된 템플릿은 `create` 또는 `update` 스택 작업에 전달됩니다. 스택을 삭제할 때 템플릿 값이 제공되지 않습니다.

### Guard 스택 작업 입력 예제
<a name="guard-hooks-write-rules-stack-operations-example"></a>

다음 예제 입력은 전체 템플릿과 이전에 배포된 템플릿을 수신하는 Guard Hook를 보여줍니다. 이 예제의 템플릿은 JSON 형식을 사용합니다.

```
HookContext:
  AwsAccountId: 123456789012
  StackId: "arn:aws:cloudformation:us-west-2:123456789012:stack/MyStack/1a2345b6-0000-00a0-a123-00abc0abc000"
  HookTypeName: org::templatechecker::hook
  HookTypeVersion: "00001"
  InvocationPoint: UPDATE_PRE_PROVISION
  TargetName: MyStack
  TargetType: CHANGE_SET
  TargetLogicalId: arn:aws:cloudformation:us-west-2:123456789012:changeSet/SampleChangeSet/1a2345b6-0000-00a0-a123-00abc0abc000
  ChangeSetId: arn:aws:cloudformation:us-west-2:123456789012:changeSet/SampleChangeSet/1a2345b6-0000-00a0-a123-00abc0abc000
Resources: {
   "S3Bucket": {
        "Type": "AWS::S3::Bucket",
        "Properties": {
           "BucketEncryption": {
               "ServerSideEncryptionConfiguration": [ 
                {"ServerSideEncryptionByDefault": 
                    {"SSEAlgorithm": "aws:kms", 
                      "KMSMasterKeyID": "KMS-KEY-ARN" }, 
                      "BucketKeyEnabled": true } 
                ] 
           }
        }
}
Previous: {
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "S3Bucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {}
        }
    }
}
```

### 스택 변경에 대한 가드 규칙
<a name="guard-hooks-rules-stack-changes"></a>

Guard Hook는 스택 변경 사항을 평가할 때 후크로 구성된 모든 규칙을 다운로드하여 시작합니다. 그런 다음 이러한 규칙은 리소스 입력에 대해 평가됩니다. 규칙이 평가에 실패하면 후크가 실패합니다. 실패가 없으면 후크가 통과합니다.

다음 예제는가 `aws:kms` 또는 로 `BucketEncryption` `SSEAlgorithm` 설정된 상태에서 라는 속성을 포함하는 `AWS::S3::Bucket` 리소스 유형이 있는지 평가하는 Guard 규칙입니다`AES256`.

```
let s3_buckets_s3_default_encryption = Resources.*[ Type == 'AWS::S3::Bucket']

rule S3_DEFAULT_ENCRYPTION_KMS when %s3_buckets_s3_default_encryption !empty {
  %s3_buckets_s3_default_encryption.Properties.BucketEncryption exists
  %s3_buckets_s3_default_encryption.Properties.BucketEncryption.ServerSideEncryptionConfiguration[*].ServerSideEncryptionByDefault.SSEAlgorithm in ["aws:kms","AES256"]
  <<
    Violation: S3 Bucket default encryption must be set.
    Fix: Set the S3 Bucket property BucketEncryption.ServerSideEncryptionConfiguration.ServerSideEncryptionByDefault.SSEAlgorithm to either "aws:kms" or "AES256"
  >>
}
```

규칙이 다음 템플릿에 대해 실행되면가 됩니다`fail`.

```
AWSTemplateFormatVersion: 2010-09-09
Description: S3 bucket without default encryption
Resources:
  EncryptedS3Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Sub 'encryptedbucket-${AWS::Region}-${AWS::AccountId}'
```

규칙이 다음 템플릿에 대해 실행되면가 됩니다`pass`.

```
AWSTemplateFormatVersion: 2010-09-09
Description: S3 bucket with default encryption using SSE-KMS with an S3 Bucket Key
Resources:
  EncryptedS3Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Sub 'encryptedbucket-${AWS::Region}-${AWS::AccountId}'
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: 'aws:kms'
              KMSMasterKeyID: KMS-KEY-ARN
            BucketKeyEnabled: true
```

## 변경 세트 작업 가드 규칙
<a name="guard-hooks-write-rules-change-set-operations"></a>

CloudFormation 변경 세트가 생성되면 변경 세트에 제안된 템플릿 및 변경 사항을 평가하여 변경 세트 실행을 차단하도록 Guard Hook를 구성할 수 있습니다.

**Topics**
+ [가드 변경 세트 입력 구문](#guard-hooks-write-rules-change-set-operations-input)
+ [가드 변경 세트 작업 입력의 예](#guard-hooks-write-rules-change-set-operations-example)
+ [변경 세트 작업에 대한 가드 규칙](#guard-hooks-rules-change-set-operations)

### 가드 변경 세트 입력 구문
<a name="guard-hooks-write-rules-change-set-operations-input"></a>

가드 변경 세트 입력은 Guard 규칙에서 평가할 수 있는 데이터입니다.

다음은 변경 세트 입력의 셰이프 예제입니다.

```
HookContext:
  AWSAccountID: String
  StackId: String
  HookTypeName: String
  HookTypeVersion: String
  InvocationPoint: [CREATE_PRE_PROVISION, UPDATE_PRE_PROVISION, DELETE_PRE_PROVISION]
  TargetName: CHANGE_SET
  TargetType:CHANGE_SET
  TargetLogicalId:ChangeSet ID
  ChangeSetId: String
{Proposed CloudFormation Template}
Previous:
  {CloudFormation Template}
Changes: [{ResourceChange}]
```

`ResourceChange` 모델 구문은 다음과 같습니다.

```
logicalResourceId: String 
resourceType: String
작업: CREATE, UPDATE, DELETE
lineNumber: Number
beforeContext: JSON String
afterContext: JSON String
```

`HookContext`  <a name="guard-hook-change-set-hookcontext"></a>  
`AWSAccountID`  <a name="guard-hook-change-set-awsaccountid"></a>
리소스가 AWS 계정 포함된의 ID입니다.  
`StackId`  <a name="guard-hook-change-set-stackid"></a>
스택 작업의 일부인 CloudFormation 스택의 스택 ID입니다.  
`HookTypeName`  <a name="guard-hook-change-set-hooktypename"></a>
실행 중인 후크의 이름입니다.  
`HookTypeVersion`  <a name="guard-hook-change-set-hooktypeversion"></a>
실행 중인 후크의 버전입니다.  
`InvocationPoint`  <a name="guard-hook-change-set-invocationpoint"></a>
후크가 실행되는 프로비저닝 로직의 정확한 지점입니다.  
*유효한 값*: (`CREATE_PRE_PROVISION` \$1 `UPDATE_PRE_PROVISION` \$1 `DELETE_PRE_PROVISION`)  
`TargetName`  <a name="guard-hook-change-set-targetname"></a>
평가 중인 스택의 이름입니다.  
`TargetType`  <a name="guard-hook-change-set-targettype"></a>
이 값은 변경 세트 수준 후크로 실행될 `CHANGE_SET` 때 입니다.  
`TargetLogicalId`  <a name="guard-hook-change-set-targetlogicalid"></a>
이 값은 변경 세트의 ARN입니다.  
`ChangeSetId`  <a name="guard-hook-change-set-changesetid"></a>
후크 호출을 유발하기 위해 실행된 변경 세트 ID입니다. 스택 작업이 `create-stack`, `update-stack`또는 `delete-stack` 작업에 의해 시작된 경우이 값은 비어 있습니다.

`Proposed CloudFormation Template`  <a name="guard-hook-change-set-current-template"></a>
`create-change-set` 작업에 제공된 전체 CloudFormation 템플릿입니다. CloudFormation에 제공된 내용에 따라 JSON 또는 YAML 문자열일 수 있습니다.

`Previous`  <a name="guard-hook-change-set-previous-template"></a>
마지막으로 성공적으로 배포된 CloudFormation 템플릿입니다. 스택이 생성되거나 삭제되는 경우이 값은 비어 있습니다.

`Changes`  <a name="guard-hook-change-set-changes"></a>
`Changes` 모델입니다. 여기에는 리소스 변경 사항이 나열됩니다.

변경 사항    
logicalResourceId  <a name="guard-hook-change-set-change-logicalresourceid"></a>
변경된 리소스의 논리적 리소스 이름입니다.  
resourceType  <a name="guard-hook-change-set-change-resourcetype"></a>
변경할 리소스 유형입니다.  
작업  <a name="guard-hook-change-set-change-action"></a>
리소스에서 수행 중인 작업의 유형입니다.  
*유효한 값*: (`CREATE` \$1 `UPDATE` \$1 `DELETE`)  
lineNumber  <a name="guard-hook-change-set-change-linenumber"></a>
변경과 연결된 템플릿의 행 번호입니다.  
beforeContext  <a name="guard-hook-change-set-change-beforecontext"></a>
변경 전 리소스 속성의 JSON 문자열:  

```
{"properties": {"property1": "value"}}
```  
afterContext  <a name="guard-hook-change-set-change-aftercontext"></a>
변경 후 리소스 속성의 JSON 문자열:  

```
{"properties": {"property1": "new value"}}
```

### 가드 변경 세트 작업 입력의 예
<a name="guard-hooks-write-rules-change-set-operations-example"></a>

다음 예제 입력은 전체 템플릿, 이전에 배포된 템플릿 및 리소스 변경 목록을 수신하는 Guard Hook를 보여줍니다. 이 예제의 템플릿은 JSON 형식을 사용합니다.

```
HookContext:
  AwsAccountId: "00000000"
  StackId: MyStack
  HookTypeName: org::templatechecker::hook
  HookTypeVersion: "00001"
  InvocationPoint: UPDATE_PRE_PROVISION
  TargetName: my-example-stack
  TargetType:STACK
  TargetLogicalId: arn...:changeSet/change-set
  ChangeSetId: ""
Resources: {
    "S3Bucket": {
       "Type": "AWS::S3::Bucket",
       "Properties": {
           "BucketName": "amzn-s3-demo-bucket",
           "VersioningConfiguration":{
              "Status": "Enabled"
            }                
         }
    }
Previous: {
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "S3Bucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName": "amzn-s3-demo-bucket",
                "VersioningConfiguration":{
                  "Status": "Suspended"
                }
            }
        }
    }
}
Changes: [
  {
    "logicalResourceId": "S3Bucket",
    "resourceType": "AWS::S3::Bucket",
    "action": "UPDATE",
    "lineNumber": 5,
    "beforeContext": "{\"Properties\":{\"VersioningConfiguration\":{\"Status\":\"Suspended\"}}}",
    "afterContext": "{\"Properties\":{\"VersioningConfiguration\":{\"Status\":\"Enabled\"}}}"
  }
]
```

### 변경 세트 작업에 대한 가드 규칙
<a name="guard-hooks-rules-change-set-operations"></a>

다음 예제는 Amazon S3 버킷의 변경 사항을 평가하고가 비활성화되지 않도록 하는 Guard 규칙`VersionConfiguration`입니다.

```
let s3_buckets_changing = Changes[resourceType == 'AWS::S3::Bucket']

rule S3_VERSIONING_STAY_ENABLED when %s3_buckets_changing !empty {
    let afterContext = json_parse(%s3_buckets_changing.afterContext)
    when %afterContext.Properties.VersioningConfiguration.Status !empty {
        %afterContext.Properties.VersioningConfiguration.Status == 'Enabled'
    }
}
```