terraform-compliance / cli

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

When directive searching entire module instead of explicit key #495

Open craigthackerx opened 3 years ago

craigthackerx commented 3 years ago

General Info:

Host OS - RedHat 8.4. Terraform-Compliance Version - Latest. Terraform Version - v15.4 AzureRM Provider - v2.61.0 Python Version - v3.9.5. Using Azure DevOps as CI/CD tool.

I am also using modules for some of my terraform.


Hi,

I am looking to get some help with an issue I'm having. Full disclosure - I don't really have much experience with QA, BDD or testing in general.

I am trying to follow the examples on the website to write an Azure based naming convention. The example you have for AWS works in Azure as follows:

    Feature: Cloud Naming Convention

    Scenario Outline: Naming Standard on all available resources
        Given I have <resource_name> defined
        When it contains <name_key>
        Then its value must match the "lb-.*" regex

        Examples:
            | resource_name | name_key |
            | azurerm_lb    | name     |

This results in the following:

   Scenario Outline: Naming Standard on all available resources
        Given I have <resource_name> defined
        When it contains <name_key>
        Then its value must match the "lb-.*" regex

    Examples:
        | resource_name | name_key |
    ! WARNING: "When it contains name" step functionality will be changed on future versions and the functionality will be same as "When it has name" step. Please use the latter.
        | azurerm_lb    | name     |

As you can see and as per the docs, I have a depreciation error for using When it contains instead of When it has. The above works great, and when I try to change my naming convention to something like hello-lb then it fails the build - exactly what I want.

I convert the .feature file to represent this to fix the warning:

  Scenario Outline: Naming Standard on all available resources
        Given I have <resource_name> defined
        When it has name <name_key>
        Then its value must match the "lb-.*" regex

        Examples:
            | resource_name | name_key |
            | azurerm_lb    | name     |

And I get the following error:

   Scenario Outline: Naming Standard on all available resources
        Given I have <resource_name> defined
        When it has name <name_key>
        Then its value must match the "lb-.*" regex

    Examples:
        | resource_name | name_key |
        Failure: name property in module.load_balancer.azurerm_lb.lb resource does not match with lb-.* case insensitive regex. It is set to dynamic.
        Failure: name property in module.load_balancer.azurerm_lb.lb resource does not match with lb-.* case insensitive regex. It is set to IPv4.
        Failure: name property in module.load_balancer.azurerm_lb.lb resource does not match with lb-.* case insensitive regex. It is set to 1.

.....more

I initially thought this was a syntax error on my part, and changed my .feature to as follows:

 Scenario Outline: Naming Standard on all available resources
        Given I have <resource_name> defined
        When it has <name_key>
        Then its value must match the "lb-.*" regex

With the main difference being I am not specifying name before <name_key>

 Examples:
        | resource_name | name_key |
        Failure: name property in module.load_balancer.azurerm_lb.lb resource does not match with lb-.* case insensitive regex. It is set to dynamic.
        Failure: name property in module.load_balancer.azurerm_lb.lb] resource does not match with lb-.* case insensitive regex. It is set to IPv4.
        Failure: name property in module.load_balancer.azurerm_lb.lb resource does not match with lb-.* case insensitive regex. It is set to 1.

...more

As you will see, after the syntax error, my name key isn't being filtered, and instead, all the properties such as as the Azure Load Balancer private_ip_address_version (which is defined as IPv4 in the module) is being searched as part of the policy, when I only really care about the name key.

Any ideas as to what's going on?

craigthackerx commented 3 years ago

Update, looks like I have raised a duplicate issue on better inspection.... #458

Happy to close unless anyone has any feedback or questions!

Kudbettin commented 3 years ago

@craigthackerx,

When it contains something drills down, while When it has something does not.

Only THEN steps should drill down, hence the deprecation of "When it has something." I see that this's not reflected well in the documentation, as we have this issue come up every once in a while. I will add more information about it.

Meanwhile, can you try using the following:

    Scenario Outline: Naming Standard on all available resources
        Given I have <resource_name> defined
        When it has name <name_key>
        Then it must have <name_key>
        Then its value must match the "lb-.*" regex

        Examples:
            | resource_name | name_key |
            | azurerm_lb    | name     |

Here, I first filter with the WHEN step, then I drill down to the value with the appropriate THEN step.