Using Terraform for container security as code with Sysdig Secure

By Jorge Salamero Sanz - DECEMBER 2, 2018


In the following tutorial you can learn how to implement container security as code. You probably have a CI/CD pipeline to automatically rebuild your container images. What if you could define your container security as code, push it into a Git repository to version control changes and then enforce your policy in your container orchestration tool like Docker or Kubernetes using Sysdig Secure? Terraform is an awesome tool to deploy and update your infrastructure using code. You might be using it already to automate your clusters deployment in cloud providers like AWS, Google Cloud, Azure or IBM. The good news is that now you can configure your container security as code with Terraform and Sysdig Secure.

Installing the Sysdig Secure Terraform provider

Installing the Sysdig Secure Terraform provider is really easy. Some pre-requirements that you need to have installed in your system are Terraform (>see here how) and Go (>1.9) to compile the provider code (the easiest is to install Go runtime using a package manager like apt or yum). Then:
  1. Go to our the Sysdig Secure Terraform provider repository and clone the code with git clone
  2. From the repository directory run go build.
  3. Once built you will find a binary terraform-provider-sysdig, move it under $HOME/.terraform.d/plugins (you might have to create that directory).
And you are ready to go! Terraform uses descriptive files that contain the resources definition (in this case your security policies). The provider will parse these definitions and will execute the required actions in the remote infrastructure (Sysdig Secure for us) so the described configuration matches with what’s actually deployed. These files can use either Terraform format (.tf) or JSON (.tf.json). If you are completely new to Terraform snyax might be a good idea to have a look at the syntax documentation. How to implement #container #security as code with #Terraform and @sysdig Secure Click to tweet

Quickstart your container security as code with Sysdig Secure Terraform provider

Let’s start getting our hands dirty and creating a basic Terraform configuration file for our container security policy configuration. First of all, you need to tell Terraform that we are going to use the Sysdig Secure provider and that all the following configuration will be handled by this module with:
provider "sysdig" { }
Now Terraform will use the provider to handle all the resource definitions in the file. You need the Sysdig Secure API token so Terraform can execute all the required actions against the Sysdig Secure backend:
provider "sysdig" {

 sysdig_secure_api_token = "<your_token>"

If you don’t want to save it in the file, Terraform will ask you to input it when executed interactively. Now we are going to create some resources. The provider currently supports creating and updating:

Creating advanced container security policies using Falco rules

Falco is a behavioral activity monitoring tool built for containers, microservices and Cloud Native applications. It’s an open source project started by Sysdig but now hosted under the umbrella of the CNCF foundation. The commercial product Sysdig Secure is built on the foundations of Falco and you can leverage Falco filtering rules to create advanced Sysdig Secure policies. In Falco you can group your rules in different files. Actually we created default security profiles or rulesets for different services/applications like Nginx, HAproxy, Traefik, MongoDB, PostgreSQL, Redis, Elasticsearch, etcd or the different Kubernetes components like api-server or kubelet. You can find them in the Falco extras repository. In order to include the rules within these files you just need to instance a resource that includes the content of each file:
resource "sysdig_secure_user_rules_file" "rules-traefik" {

 content = "${file("${path.module}/rules-traefik.yaml")}"

You can instance rules from multiple files as long as you use a different resource name. Note that the path of the YAML file is relative to the same folder as your Terraform definition files.

Sending container security alerts to a SIEM or forwarding events to a logging system

Typically you want to aggregate security events from different sources in your SIEM or log them for auditing and compliance purposes. This is accomplished through notification channels in Sysdig Secure. Container security event notification To define a new notification channel we will create a new resource with the desired name and options. Options actually match the ones available within the Secure configuration GUI.
resource "sysdig_secure_notification_channel" "sample-email" {

 name = "Example Channel - Email"
 enabled = true
 type = "EMAIL"
 recipients = "[email protected]"
 notify_when_ok = false
 notify_when_resolved = false

If you need to define notification channels that require OAuth authentication like Slack or PagerDuty, have a look at this little tool we built to automatically generate the resource definition from an existing channel created through the UI and configured using your browser.

Container security as code

Sysdig Secure allows you to create simple but very effective security policies using the UI. These define a behavior pattern and if the conditions are met, a security event is triggered. To respond to these events Sysdig can take multiple actions like isolating or killing the container, but also create a Sysdig capture with all the system activity for performing forensics and post-mortem analysis. Again, the options here match what’s available on Sysdig Secure UI, including name, description, severity, scope and then whitelists and blacklists for processes, container images, network activity, files activity or just system calls. We can also reference any rule created with Falco language. container security as code Here you can see a container security policy definition example including all possible options:
resource "sysdig_secure_policy" "sample2" {

 name = "Other example of Policy"
 description = "this is other example of policy"
 severity = 4
 enabled = true
 container_scope = true
 host_scope = true
 processes = {
   default = "accept"
   whitelist = ["mysql", "apache"]
   blacklist = ["ssh"]
 containers = {
   default = "none"
   whitelist = ["cassandra"]
   blacklist = ["mongo"]
 network = {
   inbound = "accept"
   outbound = "deny"
   listening_ports {
     default = "none"
     tcp {
       whitelist = [80, 443]
       blacklist = [8080, 5000]
     udp {
       whitelist = [53, 4000]
       blacklist = [3400, 543]
 filesystem = {
   read = {
     whitelist = ["/home"]
     blacklist = ["/etc"]
   readwrite = {
     whitelist = ["/home"]
     blacklist = ["/tmp"]
   other_paths = "none"
 syscalls = {
   default = "accept"
   whitelist = ["accept", "close"]
   blacklist = ["bind", "bpf"]
 notification_channels = ["${}"]
 falco_rule_name_regex = "Unexpected spawned process Traefik"

As you create your container security as code, multiple rules will have to be evaluated in a given priority order. This is just another resource that defines an ordered list rules referenced by their resource IDs:
resource "sysdig_secure_policies_priority" "priority" {

 policies = [


A real example of a container security as code

Creating a security policy that alerts if someone executes an interactive shell inside any container in your production environment is definitely a good idea. This could be either an external attacker running a reverse shell in your container or someone within your organization that decided to play within the production environment, not a good practice in any case. In response to this security event we will fire an alert and we will trigger a system call capture to analyze what happened after spawning the shell. We are going to create a bunch of files here, we will place all within the same directory: that indicates we are using the Sysdig Secure Terraform provider:
provider "sysdig" {
} that includes the definition of our notification channels:
resource "sysdig_secure_notification_channel" "elastic-search" {
  name = "ElasticSearch"
  enabled = false
  type = "WEBHOOK"
  url = ""
  notify_when_ok = true
  notify_when_resolved = true
} that defines the evaluation order of our policy rules, just one this time:
resource "sysdig_secure_policies_priority" "priority" {
  policies = [
} contains the policy rules definition:
resource "sysdig_secure_policy" "terminal-shell-in-container" {
  name = "Terminal shell in container"
  description = "A shell was spawned by a program in a container with an attached terminal."
  severity = 1
  enabled = true
  filter = "not in ('ping', 'default')"
  container_scope = true
  host_scope = false
  actions {
    capture {
      seconds_before_event = 10
      seconds_after_event = 20
  notification_channels = ["${}", "${}"]
  falco_rule_name_regex = "Terminal shell in container"
If we had to upload our own Falco language rules, we would have a file with:
resource "sysdig_secure_user_rules_file" "rules" {
  content = "${file("${path.module}/rules.yaml")}"
Now, in order to apply the changes, from within this directory we just need to run terraform apply and we are done! You can store all these files in Git and then let Jenkins or your favorite CI server to do the apply for you.


One of the most significant advantages of implementing container security as code with Sysdig Secure Terraform provider is having a reproducible version-controlled security policy. Additionally, this can be deployed within the same pipeline that you use for deploying your applications. Using Terraform for creating rules and notifications channels is extremely easy and if you already are using Terraform within your toolkit this can be a small step with a huge impact on how you handle security. We hope you find it useful, would love to hear your feedback and if you haven’t given Sysdig Secure a spin, do it now!

Subscribe and get the latest updates