DEV Community

loading...
Cover image for Adding Some Sweetness to your Infra-as-Code with Confectionery

Adding Some Sweetness to your Infra-as-Code with Confectionery

Anthony Barbieri
・4 min read

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:

Conftest version command

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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):

contents of testdrive directory

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
Enter fullscreen mode Exit fullscreen mode

Upon running the command you should see the following:

Conftest test command

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",
    }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

Conftest test command with exception

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.

Discussion (0)