

# Guard Hooks
<a name="guard-hooks"></a>

To use an AWS CloudFormation Guard Hook in your account, you must *activate* the Hook for the account and Region where you want to use it. Activating a Hook makes it usable in stack operations in the account and Region where it's activated. 

When you activate a Guard Hook, CloudFormation creates an entry in your account's registry for the activated Hook as a private Hook. This allows you to set any configuration properties the Hook includes. Configuration properties define how the Hook is configured for a given AWS account and Region.

**Topics**
+ [AWS CLI commands for working with Guard Hooks](#commonly-used-commands-guard-hooks)
+ [Write Guard rules to evaluate resources for Guard Hooks](guard-hooks-write-rules.md)
+ [Prepare to create a Guard Hook](guard-hooks-prepare-to-create-hook.md)
+ [Activate a Guard Hook in your account](guard-hooks-activate-hooks.md)
+ [View logs for the Guard Hooks in your account](guard-hooks-view-logs.md)
+ [Delete Guard Hooks in your account](guard-hooks-delete-hooks.md)

## AWS CLI commands for working with Guard Hooks
<a name="commonly-used-commands-guard-hooks"></a>

The AWS CLI commands for working with Guard Hooks include: 
+ [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/activate-type.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/activate-type.html) to start the activation process for a Guard Hook.
+ [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/set-type-configuration.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/set-type-configuration.html) to specify the configuration data for a Hook in your account.
+ [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-types.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-types.html) to list the Hooks in your account.
+ [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-type.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-type.html) to return detailed information about a specific Hook or specific Hook version, including current configuration data.
+ [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deactivate-type.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deactivate-type.html) to remove a previously activated Hook from your account.

# Write Guard rules to evaluate resources for Guard Hooks
<a name="guard-hooks-write-rules"></a>

AWS CloudFormation Guard is an open-source and general purpose domain specific language (DSL) you can use to author policy-as-code. This topic explains how to use Guard to author example rules which can be run in the Guard Hook to automatically evaluate CloudFormation and AWS Cloud Control API operations. It will also focus on the different types of inputs available to your Guard rules depending on when your Guard Hook runs. A Guard Hook can be configured to run during the following types of operations:
+ Resource operations
+ Stack operations
+ Change set operations

For more information on writing Guard rules, see [Writing AWS CloudFormation Guard rules](https://docs.aws.amazon.com/cfn-guard/latest/ug/writing-rules.html)

**Topics**
+ [Resource operation Guard rules](#guard-hooks-write-rules-resource-operations)
+ [Stack operation Guard rules](#guard-hooks-write-rules-stack-operations)
+ [Change set operation Guard rules](#guard-hooks-write-rules-change-set-operations)

## Resource operation Guard rules
<a name="guard-hooks-write-rules-resource-operations"></a>

Any time you create, update, or delete a resource, that's considered a resource operation. As an example, if you run update a CloudFormation stack that creates a new resource, you have completed a resource operation. When you create, update or delete a resource using Cloud Control API, that is also considered a resource operation. You can configure your Guard Hook to target `RESOURCE` and `CLOUD_CONTROL` operations in the `TargetOperations` configuration for your Hook. When your Guard Hook evaluates a resource operation, the Guard engine evaluates a resource input.

**Topics**
+ [Guard resource input syntax](#guard-hooks-write-rules-resource-operations-input)
+ [Example Guard resource operation input](#guard-hooks-write-rules-resource-operations-example)
+ [Guard rules for resource changes](#guard-hooks-rules-resource-changes)

### Guard resource input syntax
<a name="guard-hooks-write-rules-resource-operations-input"></a>

The Guard resource input is the data that's made available to your Guard rules to evaluate.

The following is an example shape of a resource input:

```
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>
The ID of the AWS account containing the resource being evaluated.  
`StackId`  <a name="guard-hook-resource-stackid"></a>
The stack ID of the CloudFormation stack that is part of the resource operation. This is empty if the caller is Cloud Control API.  
`HookTypeName`  <a name="guard-hook-resource-hooktypename"></a>
The name of the Hook that's running.  
`HookTypeVersion`  <a name="guard-hook-resource-hooktypeversion"></a>
The version of the Hook that is running.  
`InvocationPoint`  <a name="guard-hook-resource-invocationpoint"></a>
The exact point in the provisioning logic where the Hook runs.  
*Valid values*: (`CREATE_PRE_PROVISION` \$1 `UPDATE_PRE_PROVISION` \$1 `DELETE_PRE_PROVISION`)  
`TargetName`  <a name="guard-hook-resource-targetname"></a>
The target type being evaluated, for example, `AWS::S3::Bucket`.  
`TargetType`  <a name="guard-hook-resource-targettype"></a>
The target type being evaluated, for example `AWS::S3::Bucket`. For resources provisioned with Cloud Control API, this value will be `RESOURCE`.  
`TargetLogicalId`  <a name="guard-hook-resource-targetlogicalid"></a>
The `TargetLogicalId` of the resource being evaluated. If the origin of the Hook is CloudFormation, this will be the logical ID (also known as logical name) of the resource. If the origin of the Hook is Cloud Control API, this will be a constructed value.  
`ChangeSetId`  <a name="guard-hook-resource-changesetid"></a>
The change set ID that was executed to cause the Hook invocation. This value is empty if the resource change was initiated by Cloud Control API, or the `create-stack`, `update-stack`, or `delete-stack` operations.

`Resources`  <a name="guard-hook-resource-resources"></a>  
`ResourceLogicalID`  <a name="guard-hook-resource-current-resourcelogicalid"></a>
When the operation is initiated by CloudFormation, the `ResourceLogicalID` is the logical ID of the resource in the CloudFormation template.  
When the operation's initiated by Cloud Control API, the `ResourceLogicalID` is a combination of the resource type, name, operation ID, and request ID.  
`ResourceType`  <a name="guard-hook-resource-current-resourcetype"></a>
The type name of the resource (example: `AWS::S3::Bucket`).  
`ResourceProperties`  <a name="guard-hook-resource-current-resourceproperties"></a>
The proposed properties of the resource being modified. When the Guard Hook is running against the CloudFormation resource changes, any functions, parameters, and transforms will be fully resolved. If the resource is being deleted, this value will be empty.

`Previous`  <a name="guard-hook-resource-previous"></a>  
`ResourceLogicalID`  <a name="guard-hook-resource-previous-resourcelogicalid"></a>
When the operation is initiated by CloudFormation, the `ResourceLogicalID` is the logical ID of the resource in the CloudFormation template.  
When the operation's initiated by Cloud Control API, the `ResourceLogicalID` is a combination of the resource type, name, operation ID, and request ID.  
`ResourceType`  <a name="guard-hook-resource-previous-resourcetype"></a>
The type name of the resource (example: `AWS::S3::Bucket`).  
`ResourceProperties`  <a name="guard-hook-resource-previous-resourceproperties"></a>
The current properties associated with the resource being modified. If the resource is being deleted, this value will be empty.

### Example Guard resource operation input
<a name="guard-hooks-write-rules-resource-operations-example"></a>

The following example input shows a Guard Hook that will receive the definition of the `AWS::S3::Bucket` resource to update. This is the data available to Guard for evaluation.

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

To see all of the properties available for the resource type, see [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).

### Guard rules for resource changes
<a name="guard-hooks-rules-resource-changes"></a>

When a Guard Hook evaluates resource changes, it starts by downloading all the rules configured with the Hook. These rules are then evaluated against the resource input. The Hook will fail if any rules fail their evaluation. If there are no failures, the Hook will pass.

The following example is a Guard rule that evaluates if the `ObjectLockEnabled` property is `true` for any `AWS::S3::Bucket` resource types.

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

When this rule runs against the following input, it will fail since the `ObjectLockEnabled` property isn't set to `true`.

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

When this rule runs against the following input, it will pass since the `ObjectLockEnabled` is set to `true`.

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

When a Hook fails, the rules which failed will be propagated back to CloudFormation or Cloud Control API. If a logging bucket has been configured for the Guard Hook, additional rule feedback will be provided there. This additional feedback includes the `Violation` and `Fix` information.

## Stack operation Guard rules
<a name="guard-hooks-write-rules-stack-operations"></a>

When a CloudFormation stack is created, updated, or deleted, you can configure your Guard Hook to start by evaluating the new template and potentially block the stack operation from proceeding. You can configure your Guard Hook to target `STACK` operations in the `TargetOperations` configuration for your Hook.

**Topics**
+ [Guard stack input syntax](#guard-hooks-write-rules-stack-operations-input)
+ [Example Guard stack operation input](#guard-hooks-write-rules-stack-operations-example)
+ [Guard rules for stack changes](#guard-hooks-rules-stack-changes)

### Guard stack input syntax
<a name="guard-hooks-write-rules-stack-operations-input"></a>

The input for Guard stack operations provides the whole CloudFormation template for your Guard rules to evaluate.

The following is an example shape of a stack input:

```
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>
The ID of the AWS account containing the resource.  
`StackId`  <a name="guard-hook-stack-stackid"></a>
The stack ID of the CloudFormation stack that is part of the stack operation.  
`HookTypeName`  <a name="guard-hook-stack-hooktypename"></a>
The name of the Hook that's running.  
`HookTypeVersion`  <a name="guard-hook-stack-hooktypeversion"></a>
The version of the Hook that is running.  
`InvocationPoint`  <a name="guard-hook-stack-invocationpoint"></a>
The exact point in the provisioning logic where the Hook runs.  
*Valid values*: (`CREATE_PRE_PROVISION` \$1 `UPDATE_PRE_PROVISION` \$1 `DELETE_PRE_PROVISION`)  
`TargetName`  <a name="guard-hook-stack-targetname"></a>
The name of the stack being evaluated.  
`TargetType`  <a name="guard-hook-stack-targettype"></a>
This value will be `STACK` when running as a stack-level Hook.  
`ChangeSetId`  <a name="guard-hook-stack-changesetid"></a>
The change set ID that was executed to cause the Hook invocation. This value is empty if the stack operation was initiated by a `create-stack`, `update-stack`, or `delete-stack` operation.

`Proposed CloudFormation Template`  <a name="guard-hook-stack-template-current-template"></a>
The full CloudFormation template value that was passed to CloudFormation `create-stack` or `update-stack` operations. This includes things like the `Resources`, `Outputs`, and `Properties`. It can be a JSON or YAML string depending on what was provided to CloudFormation.  
In `delete-stack` operations, this value will be empty.

`Previous`  <a name="guard-hook-stack-template-previous-template"></a>
The last successfully deployed CloudFormation template. This value is empty if the stack is being created or deleted.  
In `delete-stack` operations, this value will be empty.

**Note**  
The templates provided are what is passed into `create` or `update` stack operations. When deleting a stack, no template values are provided.

### Example Guard stack operation input
<a name="guard-hooks-write-rules-stack-operations-example"></a>

The following example input shows a Guard Hook that will receive a full template and the previously deployed template. The template in this example is using the JSON format.

```
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": {}
        }
    }
}
```

### Guard rules for stack changes
<a name="guard-hooks-rules-stack-changes"></a>

When a Guard Hook evaluates stack changes, it starts by downloading all the rules configured with the Hook. These rules are then evaluated against the resource input. The Hook will fail if any rules fail their evaluation. If there are no failures, the Hook will pass.

The following example is a Guard rule that evaluates if there are any `AWS::S3::Bucket` resource types containing a property called `BucketEncryption`, with the `SSEAlgorithm` set to either `aws:kms` or `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"
  >>
}
```

When the rule runs against the following template, it will `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}'
```

When the rule runs against the following template, it will `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
```

## Change set operation Guard rules
<a name="guard-hooks-write-rules-change-set-operations"></a>

When a CloudFormation change set is created, you can configure your Guard Hook to evaluate the template and changes proposed in the change set to block the change set execution.

**Topics**
+ [Guard change set input syntax](#guard-hooks-write-rules-change-set-operations-input)
+ [Example Guard change set operation input](#guard-hooks-write-rules-change-set-operations-example)
+ [Guard rule for change set operations](#guard-hooks-rules-change-set-operations)

### Guard change set input syntax
<a name="guard-hooks-write-rules-change-set-operations-input"></a>

The Guard change set input is the data that's made available to your Guard rules to evaluate.

The following is an example shape of a change set input:

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

The `ResourceChange` model syntax is:

```
logicalResourceId: String 
resourceType: String
action: 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>
The ID of the AWS account containing the resource.  
`StackId`  <a name="guard-hook-change-set-stackid"></a>
The stack ID of the CloudFormation stack that is part of the stack operation.  
`HookTypeName`  <a name="guard-hook-change-set-hooktypename"></a>
The name of the Hook that's running.  
`HookTypeVersion`  <a name="guard-hook-change-set-hooktypeversion"></a>
The version of the Hook that is running.  
`InvocationPoint`  <a name="guard-hook-change-set-invocationpoint"></a>
The exact point in the provisioning logic where the Hook runs.  
*Valid values*: (`CREATE_PRE_PROVISION` \$1 `UPDATE_PRE_PROVISION` \$1 `DELETE_PRE_PROVISION`)  
`TargetName`  <a name="guard-hook-change-set-targetname"></a>
The name of the stack being evaluated.  
`TargetType`  <a name="guard-hook-change-set-targettype"></a>
This value will be `CHANGE_SET` when running as a change set-level Hook.  
`TargetLogicalId`  <a name="guard-hook-change-set-targetlogicalid"></a>
This value will be the ARN of the change set.  
`ChangeSetId`  <a name="guard-hook-change-set-changesetid"></a>
The change set ID that was executed to cause the Hook invocation. This value is empty if the stack operation was initiated by a `create-stack`, `update-stack`, or `delete-stack` operation.

`Proposed CloudFormation Template`  <a name="guard-hook-change-set-current-template"></a>
The full CloudFormation template that was provided to a `create-change-set` operation. It can be a JSON or YAML string depending on what was provided to CloudFormation.

`Previous`  <a name="guard-hook-change-set-previous-template"></a>
The last successfully deployed CloudFormation template. This value is empty if the stack is being created or deleted.

`Changes`  <a name="guard-hook-change-set-changes"></a>
The `Changes` model. This lists the resource changes.

Changes    
logicalResourceId  <a name="guard-hook-change-set-change-logicalresourceid"></a>
The logical resource name of the changed resource.  
resourceType  <a name="guard-hook-change-set-change-resourcetype"></a>
The resource type that will be changed.  
action  <a name="guard-hook-change-set-change-action"></a>
The type of operation being performed on the resource.  
*Valid values*: (`CREATE` \$1 `UPDATE` \$1 `DELETE`)  
lineNumber  <a name="guard-hook-change-set-change-linenumber"></a>
The line number in the template associated with the change.  
beforeContext  <a name="guard-hook-change-set-change-beforecontext"></a>
A JSON string of properties of the resource before the change:  

```
{"properties": {"property1": "value"}}
```  
afterContext  <a name="guard-hook-change-set-change-aftercontext"></a>
A JSON string of properties of the resource after the change:  

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

### Example Guard change set operation input
<a name="guard-hooks-write-rules-change-set-operations-example"></a>

The following example input shows a Guard Hook that will receive a full template, the previously deployed template, and a list of resource changes. The template in this example is using the JSON format.

```
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\"}}}"
  }
]
```

### Guard rule for change set operations
<a name="guard-hooks-rules-change-set-operations"></a>

The following example is a Guard rule that evaluates changes to Amazon S3 buckets, and ensures that `VersionConfiguration` is not disabled.

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

# Prepare to create a Guard Hook
<a name="guard-hooks-prepare-to-create-hook"></a>

Before you create a Guard Hook, you must complete the following prerequisites:
+ You must have already created a Guard rule. For more information, see the [Write Guard rules for Hooks](guard-hooks-write-rules.md).
+ The user or role that creates the Hook must have sufficient permissions to activate Hooks. For more information, see [Grant IAM permissions for CloudFormation Hooks](grant-iam-permissions-for-hooks.md).
+ To use the AWS CLI or an SDK to create a Guard Hook, you must manually create an execution role with IAM permissions and a trust policy to allow CloudFormation to invoke a Guard Hook. 

## Create an execution role for a Guard Hook
<a name="guard-hooks-create-execution-role"></a>

A Hook uses an execution role for the permissions that it requires to invoke that Hook in your AWS account.

This role can be created automatically if you create a Guard Hook from the AWS Management Console; otherwise, you must create this role yourself.

The following section shows you how to set up permissions to create your Guard Hook. 

### Required permissions
<a name="guard-hooks-execution-role-permissions"></a>

Follow the guidance at [Create a role using custom trust policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-custom.html) in the *IAM User Guide* to create a role with a custom trust policy.

Then, complete the following steps to set up your permissions:

1. Attach the following minimum privilege policy to the IAM role you want to use to create the Guard Hook.

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "s3:ListBucket",
           "s3:GetObject",
           "s3:GetObjectVersion"
         ],
         "Resource": [
           "arn:aws:s3:::my-guard-output-bucket/*",
           "arn:aws:s3:::my-guard-rules-bucket"
         ]
       },
       {
         "Effect": "Allow",
         "Action": [
           "s3:PutObject"
         ],
         "Resource": [
           "arn:aws:s3:::my-guard-output-bucket/*"
         ]
       }
     ]
   }
   ```

------

1. Give your Hook permission to assume the role by adding a trust policy to the role. The following shows an example trust policy you can use.

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": [
             "hooks.cloudformation.amazonaws.com"
           ]
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

------

# Activate a Guard Hook in your account
<a name="guard-hooks-activate-hooks"></a>

The following topic shows you how to activate a Guard Hook in your account, which makes it usable in the account and Region it was activated in.

**Topics**
+ [Activate a Guard Hook (console)](#guard-hooks-activate-hook-console)
+ [Activate a Guard Hook (AWS CLI)](#guard-hooks-activate-hooks-cli)
+ [Related resources](#related-resources-guard-hooks)

## Activate a Guard Hook (console)
<a name="guard-hooks-activate-hook-console"></a>

**To activate a Guard Hook for use in your account**

1. Sign in to the AWS Management Console and open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. On the navigation bar at the top of the screen, choose the AWS Region where you want to create the Hook in.

1. In the navigation pane on the left, choose **Hooks**.

1. On the **Hooks** page, choose **Create a Hook**, and then choose **With Guard**.

1. If you *haven't* created any Guard rules yet, create your Guard rule, store it in Amazon S3, and then return to this procedure. Refer to the example rules in [Write Guard rules to evaluate resources for Guard Hooks](guard-hooks-write-rules.md) to get started.

   If you have already created your Guard rule and stored it in S3, proceed to the next step. 
**Note**  
The object stored in S3 must have one of the following file extensions: `.guard`, `.zip`, or `.tar.gz`.

1. For **Guard Hook source**, **Store your Guard rules in S3**, do the following:
   + For **S3 URI**, specify the S3 path to your rules file or use the **Browse S3** button to open a dialog box to browse for and select the S3 object.
   + (Optional) For **Object version**, if your S3 bucket has versioning enabled, you can select a specific version of the S3 object. 

     The Guard Hook downloads your rules from S3 every time the Hook is invoked. To prevent accidental changes or deletions, we recommend using a version when configuring your Guard Hook.

1. (Optional) For **S3 bucket for Guard output report**, specify an S3 bucket to store the Guard output report. This report contains the results of your Guard rule validations.

   To configure the output report destination, choose one of the following options:
   + Select the **Use the same bucket my Guard rules are stored in** check box to use the same bucket where your Guard rules are located.
   + Choose a different S3 bucket name for storing the Guard output report.

1. (Optional) Expand **Guard rule input parameters**, and then provide the following information under **Store your Guard rule input parameters in S3**:
   + For **S3 URI**, specify the S3 path to a parameter file or use the **Browse S3** button to open a dialog box to browse for and select the S3 object.
   + (Optional) For **Object version**, if your S3 bucket has versioning enabled, you can select a specific version of the S3 object. 

1. Choose **Next**.

1. For **Hook name**, choose one of the following options:
   + Provide a short, descriptive name that will be added after `Private::Guard::`. For example, if you enter *`MyTestHook`*, the full Hook name becomes `Private::Guard::MyTestHook`.
   + Provide the full Hook name (also called an alias) using this format: `Provider::ServiceName::HookName` 

1. For **Hook targets**, choose what to evaluate:
   + **Stacks** — Evaluates stack templates when users create, update, or delete stacks.
   + **Resources** — Evaluates individual resource changes when users update stacks.
   + **Change sets** — Evaluates planned updates when users create change sets.
   + **Cloud Control API** — Evaluates create, update or delete operations initiated by the [Cloud Control API](https://docs.aws.amazon.com/cloudcontrolapi/latest/userguide/what-is-cloudcontrolapi.html).

1. For **Actions**, choose which actions (create, update, delete) will invoke your Hook.

1. For **Hook mode**, choose how the Hook responds when rules fail their evaluation:
   + **Warn** — Issues warnings to users but allows actions to continue. This is useful for non-critical validations or informational checks.
   + **Fail** — Prevents the action from proceeding. This is helpful for enforcing strict compliance or security policies.

1. For **Execution role**, choose the IAM role that the Hook assumes to retrieve your Guard rules from S3 and optionally write a detailed Guard output report back. You can either allow CloudFormation to automatically create an execution role for you or you can specify a role that you've created. 

1. Choose **Next**.

1. (Optional) For **Hook filters**, do the following:

   1. For **Resource filter**, specify which resource types can invoke the Hook. This ensures that the Hook is only invoked for relevant resources.

   1. For **Filtering criteria**, choose the logic for applying stack name and stack role filters:
      + **All stack names and stack roles** – The Hook will only be invoked when all specified filters match.
      + **Any stack names and stack roles** – The Hook will be invoked if at least one of the specified filters match.
**Note**  
For Cloud Control API operations, all **Stack names** and **Stack roles** filters are ignored.

   1. For **Stack names**, include or exclude specific stacks from Hook invocations.
      + For **Include**, specify the stack names to include. Use this when you have a small set of specific stacks you want to target. Only the stacks specified in this list will invoke the Hook.
      + For **Exclude**, specify the stack names to exclude. Use this when you want to invoke the Hook on most stacks but exclude a few specific ones. All stacks except those listed here will invoke the Hook.

   1. For **Stack roles**, include or exclude specific stacks from Hook invocations based on their associated IAM roles.
      + For **Include**, specify one or more IAM role ARNs to target stacks associated with these roles. Only stack operations initiated by these roles will invoke the Hook.
      + For **Exclude**, specify one or more IAM role ARNs for stacks you want to exclude. The Hook will be invoked on all stacks except those initiated by the specified roles.

1. Choose **Next**.

1. On the **Review and activate** page, review your choices. To make changes, choose **Edit** on the related section.

1. When you're ready to proceed, choose **Activate Hook**.

## Activate a Guard Hook (AWS CLI)
<a name="guard-hooks-activate-hooks-cli"></a>

Before you continue, confirm that you have created the Guard rule and the execution role that you'll use with this Hook. For more information, see [Write Guard rules to evaluate resources for Guard Hooks](guard-hooks-write-rules.md) and [Create an execution role for a Guard Hook](guard-hooks-prepare-to-create-hook.md#guard-hooks-create-execution-role).

**To activate a Guard Hook for use in your account (AWS CLI)**

1. To start activating a Hook, use the following [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/activate-type.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/activate-type.html) command, replacing the placeholders with your specific values. This command authorizes the Hook to use a specified execution role from your AWS account.

   ```
   aws cloudformation activate-type --type HOOK \
     --type-name AWS::Hooks::GuardHook \
     --publisher-id aws-hooks \
     --type-name-alias Private::Guard::MyTestHook \
     --execution-role-arn arn:aws:iam::123456789012:role/my-execution-role \
     --region us-west-2
   ```

1. To finish activating the Hook, you must configure it using a JSON configuration file.

   Use the **cat** command to create a JSON file with the following structure. For more information, see [Hook configuration schema syntax reference](hook-configuration-schema.md).

   ```
   $ cat > config.json
   {
     "CloudFormationConfiguration": {
       "HookConfiguration": {
         "HookInvocationStatus": "ENABLED",
         "TargetOperations": [
           "STACK",
           "RESOURCE",
           "CHANGE_SET"
         ],
         "FailureMode": "WARN",
         "Properties": {
           "ruleLocation": "s3://amzn-s3-demo-bucket/MyGuardRules.guard",
           "logBucket": "amzn-s3-demo-logging-bucket"
         },
         "TargetFilters": {
           "Actions": [
             "CREATE",
             "UPDATE",
             "DELETE"
           ]
         }
       }
     }
   }
   ```
   + `HookInvocationStatus`: Set to `ENABLED` to enable the Hook.
   + `TargetOperations`: Specify the operations that the Hook will evaluate.
   + `FailureMode`: Set to either `FAIL` or `WARN`.
   + `ruleLocation`: Replace with the S3 URI where your rule is stored. The object stored in S3 must have one of the following ﬁle extensions: `.guard`, `.zip`, and `.tar.gz`.
   + `logBucket`: (Optional) Specify the name of an S3 bucket for Guard JSON reports.
   + `TargetFilters`: Specify the types of actions that will invoke the Hook.

1. Use the following [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/set-type-configuration.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/set-type-configuration.html) command, along with the JSON file you created, to apply the configuration. Replace the placeholders with your specific values.

   ```
   aws cloudformation set-type-configuration \
     --configuration file://config.json \
     --type-arn "arn:aws:cloudformation:us-west-2:123456789012:type/hook/MyTestHook" \
     --region us-west-2
   ```

## Related resources
<a name="related-resources-guard-hooks"></a>

We provide template examples that you can use to understand how to declare a Guard Hook in a CloudFormation stack template. For more information, see [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-guardhook.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-guardhook.html) in the *AWS CloudFormation User Guide*.

# View logs for the Guard Hooks in your account
<a name="guard-hooks-view-logs"></a>

When you activate a Guard Hook, you can specify an Amazon S3 bucket as the destination for the Hook output report. Once activated, the Hook automatically stores the results of your Guard rule validations in the specified bucket. You can then view these results in the Amazon S3 console.

## View Guard Hook logs in the Amazon S3 console
<a name="guard-hooks-view-logs-console"></a>

**To view the Guard Hook output log file**

1. Sign-in to the [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/).

1. On the navigation bar at the top of the screen, choose your AWS Region.

1. Choose **Buckets**.

1. Choose the bucket you selected for your Guard output report.

1. Choose the desired validation output report log file.

1. Choose whether you want to **Download** the file or **Open** it to view.

# Delete Guard Hooks in your account
<a name="guard-hooks-delete-hooks"></a>

When you no longer need an activated Guard Hook, use the following procedures to delete it in your account.

To temporarily disable a Hook instead of deleting it, see [Disable and enable CloudFormation Hooks](hooks-disable-enable.md).

**Topics**
+ [Delete a Guard Hook in your account (console)](#guard-hooks-delete-hook-console)
+ [Delete a Guard Hook in your account (AWS CLI)](#guard-hooks-delete-hook-cli)

## Delete a Guard Hook in your account (console)
<a name="guard-hooks-delete-hook-console"></a>

**To delete a Guard Hook in your account**

1. Sign in to the AWS Management Console and open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. On the navigation bar at the top of the screen, choose the AWS Region where the Hook is located.

1. From the navigation pane, choose **Hooks**.

1. On the **Hooks** page, find the Guard Hook you want to delete.

1. Select the check box next to your Hook and choose **Delete**. 

1. When prompted for confirmation, type out the Hook name to confirm deleting the specified Hook and then choose **Delete**.

## Delete a Guard Hook in your account (AWS CLI)
<a name="guard-hooks-delete-hook-cli"></a>

**Note**  
Before you can delete the Hook, you must first disable it. For more information, see [Disable and enable a Hook in your account (AWS CLI)](hooks-disable-enable.md#hooks-disable-enable-cli).

Use the following [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deactivate-type.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deactivate-type.html) command to deactivate a Hook, which removes it from your account. Replace placeholders with your specific values.

```
aws cloudformation deactivate-type \
  --type-arn "arn:aws:cloudformation:us-west-2:123456789012:type/hook/MyTestHook" \
  --region us-west-2
```