terraform-compliance / cli

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

tagging feature - false positive for aws_lambda_function's "environment" argument #699

Open ch-e-mistry opened 1 year ago

ch-e-mistry commented 1 year ago

Description

latest (and older like 1.4.32 as well) version of terraform compliance has an issue? Not sure, as it is more related to the testing (bdd) method I think.

The issue:

$ terraform-compliance -f ${FEATURES_ROOT}/${SELF_FEATURES_DIR} --junit-xml TFCompliance-Report.xml --planfile plan.compliance.json_just_env_var
terraform-compliance v1.3.42 initiated

🚩 Features     : /features/self-features/
🚩 Plan File    : /code/plan.compliance.json_just_env_var

🚩 Running tests. πŸŽ‰

Feature: Check tags property was defined for all resource and its has proper tag keys.  # /features/self-features/aws/tagging.feature

    Scenario: Ensure all resources have tags_all
        Given I have resource that supports tags_all defined
        Then it must contain tags_all
        And its value must not be null

    Scenario Outline: Ensure that specific tags are defined
        Given I have resource that supports tags_all defined
        Then it must contain <tags>
        And its value must match the "<value>" regex

    Examples:
        | tags        | value                                          |
        | Project     | .+                                             |
                Failure: Environment property in aws_s3_bucket.single_cost_extractor resource does not match with ^(development|test|uat|production|management)$ case insensitive regex. It is set to aws_lambda_function.single_cost_extractor.    
                Failure: Environment property in aws_lambda_function.single_cost_extractor resource does not match with ^(development|test|uat|production|management)$ case insensitive regex. It is set to var.s3_source_bucket_name.
                Failure: Environment property in aws_lambda_function.single_cost_extractor resource does not match with ^(development|test|uat|production|management)$ case insensitive regex. It is set to aws_s3_bucket.single_cost_extractor.id. 
                Failure: Environment property in aws_lambda_function.single_cost_extractor resource does not match with ^(development|test|uat|production|management)$ case insensitive regex. It is set to aws_s3_bucket.single_cost_extractor.    
                Failure: Environment property in aws_lambda_function.single_cost_extractor resource does not match with ^(development|test|uat|production|management)$ case insensitive regex. It is set to var.dsl.
        | Environment | ^(development|test|uat|production|management)$ |
          Failure:

    Scenario: Ensure all resources have tags, even with tags_all not used
        Given I have resource that supports tags defined
        πŸ’‘ SKIPPING: All objects (resource that supports tags) coming from previous step has tags_all property.

The related tf code snippet:

# Lambda function 
resource "aws_lambda_function" "single_cost_extractor" {
  filename      = data.archive_file.zip_single_cost_extractor.output_path
  function_name = join("_", [var.single_cost_extractor_function_name, var.short_dsl])
  role          = aws_iam_role.lambda_role.arn
  handler       = "single_cost_extractor.lambda_handler"
  runtime       = var.runtime
  timeout       = var.timeout
  description   = var.lambda_description

  environment {
    variables = {
      SOURCE_BUCKET      = var.s3_source_bucket_name
      DESTINATION_BUCKET = aws_s3_bucket.single_cost_extractor.id
      DSL                = var.dsl
    }
  }

  depends_on = [aws_s3_bucket.single_cost_extractor]
}

I think, my tagging feature check everything, which has "environment" property. Like this lambda function. While the lambda function itself has the necessary tags, thanks to the following snippet:

#https://www.hashicorp.com/blog/default-tags-in-the-terraform-aws-provider
provider "aws" {
  default_tags {
    tags = var.dsl_tags
  }
}

I attached the plan jsonfile, created by /code # gitlab-terraform show -json plan.cache > plan.compliance.json

versions:

/code # gitlab-terraform -v
Terraform v1.2.9
on linux_amd64
+ provider registry.terraform.io/hashicorp/archive v2.3.0
+ provider registry.terraform.io/hashicorp/aws v4.66.1

Your version of Terraform is out of date! The latest version
is 1.4.6. You can update by downloading from https://www.terraform.io/downloads.html

Workaround

I changed the feature as:

Feature: Check tags property was defined for all resource and its has proper tag keys.

    Scenario: Ensure all resources have tags_all
        Given I have resource that supports tags_all defined
        Then it must contain tags_all
        And its value must not be null

    @exclude_aws_lambda_function.*
    Scenario Outline: Ensure that specific tags are defined
        Given I have resource that supports tags_all defined
        Then it must contain <tags>
        And its value must match the "<value>" regex

        Examples:
            | tags        | value                                              |
            | Project     | .+                                                 |
            | Environment | ^(development\|test\|uat\|production\|management)$ |

But It will exclude all lambda function.

Please let me know, if you have a better solution / any way, how to solve this issue.

Thank you and Best Regards,

ch-e-mistry commented 1 year ago

plan.compliance.zip

ch-e-mistry commented 1 year ago

Just a comment: If the tagging rule itself is case sensitive I think, this issue can be eliminated, see:

        Examples:
            | tags        | value                                              |
            | Project     | .+                                                 |
            | Environment | ^(development\|test\|uat\|production\|management)$ |

Also I noticed the same issue with step functions in AWS.