Write custom AWS Config rules using Guard

Zeina Thabet
4 min readJul 9, 2023

--

Objective

The objective of this article is to create a custom AWS Config rule using Guard.

Introduction

Guard is a DSL (Domain Specific Language) provided by AWS that was first used with CloudFormation and is known as cfn-guard. It is used to ensure that CloudFormation adheres to specifc requirements and does not stray away from it, in order to ensure that CloudFormation resources do not drift away from the requirements.

The same language, Guard, can also be used with AWS Config in order to evaluate AWS Configuration items which is in JSON format. Guard ensures that the configuration items (json) adhere to specific formats or rules specified.

The diagram above illustrates how AWS Config rules evaluate the resources in order to ensure that they are compliant.

The following is an example of a configuration item for EC2 security groups:

Guard in Config

The purpose of Guard in the context of AWS Config custom rules, is to validate whether the resources configuration items (json format) adheres to specific requirements set by the rule.

Overview

In this article, we will be creating a custom config rule to evaluate and check for open ports on EC2 security groups. In this article we will check for port 22, however it can be any port as per the requirement.

Creating Security groups

First of all, lets create sample security groups for the sake of testing the config rule. We will create one compliant rule and one non-compliant rule.

First security group (compliant)
Second security group (non compliant)

Creating Custom rule

Now we’ll start by creating a custom rule. In the AWS Config console, click on Add Rule and select “Custom rule using Guard”.

We will then set the name of the AWS Config rule

Enable debug logs

Then we will enable debug logs.

Debug logs are crucial in order to know if the rules are evaluating the resources correctly or not. If there are any errors in the evaluation then they would show up in the CloudWatch logs.

Benefit of debug logs

We will start by writing a faulty Guard rule and debug it using the debug logs.

Faulty Guard rule

For demonstration purposes, we will create a faulty rule and see what happens.

If the rule does not evaluate correctly, logs could result in the rule being under “not applicable” array, or an error could be present in the logs.

Here is an example of both:

Here we can understand that it is not recognizing “ipPermissions” as an array. The correct way to write it is as the following:

Fixing the Guard rule

So now we will use the correctly syntax-ed rule.

rule ssh_open_ports {
this.configuration.ipPermissions[*] {

when this.fromPort != null {
this.fromPort != 22
}

this.ipProtocol != -1

}

}

The rule will have the EC2 security groups configuration item as input, and will check and evaluate for ports that are open on an EC2 security group. In our case we selected the SSH Port 22, however any port can be selected.

What the rule does is it loops over “configuration.ipPermissions” array, then checks if “fromPort” attribute is available. If it is, then it will check if the value is equal to 22. Then it also checks if the “ipProtocol” is equal to -1. Because if it is, this means that the security group rule allows all ports to be open.

Rule triggers

We will select Detective Evaluation for this rule. Detective evaluation can trigger evaluations when the resource configuration changes, and/or periodically such as once every 24 hours.

Then under resources, you can select the types of resources that you would like this rule to trigger on, for our case we selected EC2 Security groups since we are interested in the security groups only.

After that, click Save.

Resource evaluation results

The following are example results for the evaluation of the EC2 security groups.

We can see that the resources that have evaluated to compliant, actually satisfy the config rule, and the non-compliant resources break the config rule.

--

--