Atlantis is an application used for collaborating on a Terraform code base using pull requests and one of the feature that it has is to run conftest and test a set of defined OPA policies. At the moment I’m writing this article, Atlantis only supports using local sources i.e. local filesystem as the source of the policy. In this article, I’ll show an example of how to use an S3 bucket instead as the source for the policies.
Custom workflow and run
step
Atlantis supports using custom workflows to override the default commands that it runs and as part of that feature, it supports defining any custom commands to run as part of the steps for each stage. We will be abusingusing this feature to override the default conftest
command that Atlantis uses and specify our policy through the --update
flag of conftest
conftest --update
flag
By using --update
you can tell conftest
to pull the policy first every time it wants to run the tests. We will be using an S3 bucket as our source but before we can pull from S3, you have to make sure that wherever the Atlantis server is running, it can access and have permission to pull objects from the bucket. In my case, Atlantis is running as a StatefulSet inside a Kubernetes cluster so I have already configured the IAM permission needed for it to access the bucket.
conftest
is using the go-getter package underneath to pull these packages so technically it should be possible to also pull from other sources that go-getter
supports, other than just S3.
Result
Combining both of the features described above, here’s an example of a simplified repo config that I use:
|
|
In the example above, under the workflows
key, I’m defining a custom workflow named custom
and inside that custom workflow, I’m overriding the default policy_check
steps with my own. My custom policy_check
steps consists of the show
step and the custom run
step. The show
step is crucial since this is when Atlantis will run terraform show
to convert your Terraform planfile to a JSON formatted file.
When using the custom run
step, Atlantis will store the path to this JSON formatted file in variable $SHOWFILE
so when I ran my conftest command you can see that I’m using $SHOWFILE
to run conftest
against the file. Optional: if you want to run conftest
against the Terraform files too, you can add *.tf
after $SHOWFILE
and it will include all the *tf
files in that project directory.
Next comes the --update
flag, to specify the S3 bucket, I’m using a URL format that is specified by the go-getter
package replacing $BUCKET_NAME
with the bucket name that I have configured with the correct permission and network access. Inside the S3 bucket, this is how I structured the files. I put all the OPA policies inside a folder policy
since conftest
complains when I just put all the policies directly at the root level inside the bucket. YMMV.
$BUCKET_NAME/
├─ policy/
│ ├─ stop_it.rego
│ ├─ dont_kill_server.rego
After defining our custom workflow, we can specify the custom worklow as the default workflow for a repo. This is done by setting the repos[].workflow
value to the name of our custom workflow, in my case it’s custom
.
Next, as part of the using the policy check feature in Atlantis, you are required to set the policies
values. You can refer to the docs for the full configuration required. Inside the policies
key, there is a required policy_check
key that is used to specify where Atlantis can find the OPA policies to use when running conftest
. Usually, this is a folder on a local filesystem already containing the policies but in our case, since we’re using the --update
flag, we just need to specify any folder on the local filesystem that will be writable by the Atlantis user. You can see in the example above that I’m using /home/atlantis/policy
.
Conclusion
That’s all you need to do configure to make Atlantis pulls policies from S3 (and include Terraform source code files in your contest
run). Shoutout to a DoorDash engineering blog post which mentioned briefly that they pulled their policies from S3 and made me curios how to do the same using Atlantis. You can mention me on Twitter (@pokgak73) if this article has helped you. That would most definitely made my day :)