Recently the Confectionery tool was open-sourced after some internal iterations within Cigna. The project was a combined effort from multiple teams and we're excited to see the wider community be able to leverage it.
So what is Confectionery anyways? It is a rule library for the Conftest tool. By leveraging Conftest, teams can validate various configuration files via static scanning and policies written in the Rego language. The Confectionery ruleset as of the writing of this article is focused on Terraform. We plan to expand to other formats in the near future (Dockerfiles and Kubernetes manifests). I've previously written about how Conftest can be used to scan Terraform files, please see my article from last year on the topic.
Trying out Confectionery
As noted in our Getting Started Guide Conftest is a pre-requisite to being able to consume the Confectionery rule library. Feel free to use the install option that makes the most sense for you. You can confirm it successfully installed by running the version command as shown below:
Next lets set up a directory that will house our terraform files and rules. These command should work across Windows(Powershell), Mac, and Linux
cd ~ #switching to our home directory
mkdir testdrive #making a directory
cd testdrive # switching into our directory
Next, lets save the contents of one of our test files as kms.tf
in our testdrive
directory. The contents can be found here
Reviewing the file we can see that we're planning to creating three KMS keys, and expecting two of the three to fail our rules.
Before invoking Conftest, lets generate our terraform plan. These steps assume Terraform is installed, and AWS credentials (with at least ReadOnlyAccess) are saved in ~/.aws/credentials
. If that is not the case please skip to next section where alternate instructions will be provided. Before we begin, I am changing the profile
on line 7 of kms.tf to default
since that is the name of my aws profile as it appear on ~/.aws/credentials
. It is also the default when setting up credentials via the aws cli. If you use a different profile please feel free to change it to that value.
terraform init
terraform plan -out tf-plan.binary
terraform show -json tf-plan.binary > tf-plan.json
Running these three commands should download the AWS provider, generate a binary representation, and produce a JSON version as well. The output will note that there the three keys would be created.
Alternate Commands
If you do not have the ability to leverage terraform/AWS but would still like to follow along, we can grab a pre-generated plan from one of the other test files. In this file You can save the value of mock_plan_input
(include the starting and closing brackets as tf-plan.json
in our testdrive
directory.
First Run
At this point our testdrive
directory should have the following files (no binary file if the alternate commands were used):
The command we'll run is shown below. By running the test sub command with the update flag, Conftest will download the Confectionery rule files into a policy
directory (inside the testdrive
directory) then run the rules against the tf-plan.json file. The command is also specifying the tag/release to use, which in this case is v1.0.0
conftest test --update "git::https://github.com/cigna/confectionery.git//rules/terraform?ref=v1.0.0" tf-plan.json
Upon running the command you should see the following:
As expected we see that our two invalid keys were flagged while the one with rotation enabled was not. The command also returns a non-zero exit code, which should trigger a failure in a pipeline in most CI systems.
Exceptions
In order to give some flexibility to consumers of the library, exceptions are also supported. As noted in the documentation this leverages Regula's implementation. This allows waiving or disabled of rules on a number of factors. Let's try waiving the rule that is failing on our two keys
Inside our testdrive
directory lets make an exceptions
directory using the mkdir
command. Inside the exceptions
directory please make a file called config.rego
with the following contents:
package fugue.regula.config
waivers[waiver] {
waiver := {
"rule_name": "kms_rotate",
}
}
As you can see we're specifying the rule name as it appears in the above output. Let's switch back to our testdrive
directory and run the following command:
conftest test -p policy -p exceptions --update "git::https://github.com/cigna/confectionery.git//rules/terraform?ref=v1.0.0" tf-plan.json
This command is similar to our first run, but we've specified both our policy
and exceptions
directories, to allow for the waiver to be process successfully. After executing the command the output should look something like this:
Conclusion
Confectionery provides a great way to enable a fast feedback loop to infrastructure-as-code developers. It can easily be consumed locally on a laptop or from within a CI system to prevent misconfigurations from reaching a live environment. We'll continue to add more rules over time, and will expand to other configuration file formats to gain additional coverage. If you have any rules/feature requests you'd like to see please feel free to Submit an issue.
Top comments (0)