terraform-compliance / cli

a lightweight, security focused, BDD test framework against terraform.
https://terraform-compliance.com
MIT License
1.36k stars 152 forks source link

Verification of environment variables for a Kubernetes deployment #332

Open UncleIS opened 4 years ago

UncleIS commented 4 years ago

Hi and thanks for an amazing tool.

Question : We are actively using Terraform for deploying applications to Kubernetes and would like to check these for compliance matters. As an example, we need to check the presence of a number of environment variables and check that the value of each of them matches a particular regex.

Here is an example resource definition:

provider "kubernetes" {
  version = "~> v1.11.1"
}

variable "system_name" {
  default = "demoapp"
}

variable "environment" {
  default = "build"
}

variable "app_image_tag" {
  default = "latest"
}

resource "kubernetes_deployment" "app" {
  metadata {
    name      = var.system_name
    namespace = kubernetes_namespace.app.metadata[0].name
    annotations = {
      "kubernetes.io/change-cause" = "jenkins_build_${var.app_image_tag}"
    }
    labels = {
      name = var.system_name
    }
  }

  spec {
    replicas = 1
    selector {
      match_labels = {
        "app" = var.system_name
      }
    }
    template {
      metadata {
        labels = {
          "app" = var.system_name
        }
        annotations = {
          "app_build_number" = "${var.app_image_tag}"
        }
      }
      spec {
        container {
          name  = "app"
          image = "nginx:1.17.9"
          env {
            name  = "DYMMY_VAR0"
            value = "demoapp_${var.environment}-nginx"
          }
          env {
            name  = "DUMMY_VAR1"
            value = "5"
          }
          env {
            name  = "DUMMY_VAR2"
            value = "demoapp"
          }
          env {
            name  = "DUMMY_VAR3"
            value = "DUMMY_VALUE"
          }
        }
        security_context {
          run_as_non_root = true
        }
      }
    }
  }
}

We would like to check that:

It is clear that a scenario outline is needed for this, but not exactly clear how to write a rule that would do proper checks.

Thank you for any input!

eerkunt commented 4 years ago

Hello @UncleIS,

Sorry for the late response.

I tried your case and I think this is the feature you want ;

Feature: test feature

  Scenario Outline: Check for Environment Variables
    Given I have kubernetes_deployment defined
    Then it must have spec
    And it must have template
    And it must have spec
    And it must have container
    And it must have env
    When it has <key>
    Then its <key> must be <value>

    Examples:
    | key | value |
    | name | DUMMY_VAR0 |
    | name | DUMMY_VAR1 |
    | name | DUMMY_VAR2 |
    | name | DUMMY_VAR3 |
    | name | DUMMY_VAR4 |

Let me know if this is working for you.

eerkunt commented 4 years ago

By the way this is the result I got ;

         | key  | value      |
        Failure: Can not find DUMMY_VAR0 in name property of kubernetes_deployment.app.
        Failure: Can not find DUMMY_VAR0 in name property of kubernetes_deployment.app.
        | name | DUMMY_VAR0 |

        | name | DUMMY_VAR1 |
        | name | DUMMY_VAR2 |
        | name | DUMMY_VAR3 |
        Failure: Can not find DUMMY_VAR4 in name property of kubernetes_deployment.app.
        Failure: Can not find DUMMY_VAR4 in name property of kubernetes_deployment.app.
        | name | DUMMY_VAR4 |
UncleIS commented 4 years ago

Hi and thanks for looking into that!

What about matching the value (not only the name) of the variable to a regular expression

Meaning, that ideally it would be nice to have something like this:

...
Then its name must be <name>
And its value must match the "<regex>" regex

Examples:
|name|regex|
|DUMMY_VAR0|demoapp|
|DUMMY_VAR1|^[0-9]+$|
...

The problem for me is grasping the syntax of how ensure that we do not only have a variable that has a particular name and, possibly, another variable that matches a particular value, but how to ensure that a variable has both name and value matching the requirements of a particular example row.

Btw, in the example that I provided DUMMY_VAR4 is absent indeed, but DUMMY_VAR0 is in place.