Terrascan exit status and failing only on high severity vulnerabilities

I've noticed that exit status of the terrascan command is always 3 if a violation of any level of severity thus fails the pipeline if there's even just single low one
I was trying to find a way to only fail if there are high severity problems, is it at all possible?

You're right that Terrascan will return 3 in cases where any violations are found. If you want to be more sophisticated about how the findings are handled, you have a few options:

  1. You could leverage a tool like jq or yq to parse the results.count in the output and take action from there.
  2. You could process the YAML or JSON output in a custom script/program to implement your desired logic.
  3. You could prepare a custom profile directory which excludes the policies that you don't care about (like Low severity ones), and use the -p option to use those policies. In that case, the return code of 3 would indicate that you actually want to fail.

Let me put together a little example to illustrate.

I'm not sure how you are running Terrascan, but let's say you are using Docker. Maybe with a command something like this:

docker run --rm -v $(pwd):/iac -w /iac accurics/terrascan scan

This will scan the current directory using the latest container build and the default values. If any violations are found, even low severity ones, code 3 will be returned.

Let's say you only want to return a non-zero code if a high severity violation is found. In that case, you could pipe the output to yq to test the value of results.count.high. The following example shows what that might look like. Note that I don't have yq installed locally so I'll run it via Docker. For clarity, I've replaced the Terrascan command line with ${TERRASCAN_CMD}. It doesn't matter if that runs under Docker or is installed locally. Note that you could also store the Terrascan output in a file and then run yq on that file if that makes more sense than using a pipe.

${TERRASCAN_CMD} | docker run --rm -i mikefarah/yq:4 -e eval ".results.count.high==0" -

This will run Terrascan as usual and pipe the output to yq. I'm using version 4 of the image because different versions have different command line options. yq uses the convention of reading from standard input if the filename - is specified. The command will test whether results.count.high==0 exists in the output. If more than one high severity violation was found, it will evaluate to false. The -e option will set the exit code if the expression evaluates to false or is not found. The end result is that the exit code will be 0 if the number of high severity findings is 0, and the exit code will be non-zero if there are more than 0 high severity findings.

If you wanted to test both high and medium severity findings, you could replace the expression with something like .results.count.high==0 and .results.count.medium==0. In that case, the command will return a non-zero code if either the high or medium severity violation count is non-zero.

You are of course limited to the processing supported by yq in this case. You could always build your own script or program to process the output of Terrascan if you want more control over how the output is treated. Terrascan's YAML or JSON output is probably the easiest to work with, because it is easily parsable and those formats are widely supported.