cli icon indicating copy to clipboard operation
cli copied to clipboard

Exclude Tags for variables.

Open wesley-staples opened this issue 3 years ago • 2 comments

Question

We have 2 terraform projects that are nearly identical. (One is for Team A in us-east-1 and one is for team B in us-west-2). The issue we are running into is that the projects are so similar that we tend to copy code from one and paste it in the other. When we do we sometimes accidentally bring over an incorrect variable value (or variable name). Since I know that Team A's terraform config should never have the text "Team B" or "us-west-2" I thought I might be able to rig something up with terraform compliance. This is what I have so far:

Example terraform file for team a:

module "team-a-core" {
  source               = "../modules/core"
  project_config       = local.project_config
}

module "team-b-apps" {
   source = "../modules/ecs-service"
   app_config  = var.app_config
   project_config = var.project_config

   region                          = "us-west-2"
   fargate_cluster_id              = module.team-a-core.fargate_cluster_id
   loadbalancer_arn                = module.team-a-core.loadbalancer_arn
}

variable "aws_regions" {
  default = {
    "us-east-1" = {
      "region" = "us-east-1",
      "desc" = "US East (N. Virginia)"
    },
    "us-west-2" = {
      "region" = "us-west-2",
      "desc" = "US West (Oregon)"
    },
    # all of the regions are listed here
}

Lets say I made some changes for team b and then I copy / pasted into the file for team a. As you can see above I have now accidentally called the module "team-b-apps" which is incorrect. Another mistake is that the region now reads us-west-2.

I have a scenario file that reads like the following:

@exclude_variable.aws_regions
Scenario: Nothing should be named team-b
  Given I have variables defined
  Then its value must not match the ".*(us\-west\-2).*" regex

When I run this in the debugger it looks like the variables are all loosing there initial name:

variable property in
{
	'default': {
		'us-east-1': {
			'account_id': 127311923021,
			'desc': 'US East (N. Virginia)',
			'region': 'us-east-1'
		},
		'us-west-2': {
			'account_id': 797873946194,
			'desc': 'US West (Oregon)',
			'region': 'us-west-2'
		}
	}
}
variable matches with .*(us\-west\-2).* case insensitive regex. It is set to us-west-2.

You can see that the exclude tag does not appear to be excluding this variable. Another question is how can a search the terraform paths? I want to ensure that "module.team-b-apps" does not actually contain the text "team b".

Overall I'm really enjoying using terraform compliance. Thanks in advance for your help.

wesley-staples avatar Mar 25 '21 18:03 wesley-staples

@wesley-staples

in regard Another question is how can a search the terraform paths? I want to ensure that "module.team-b-apps" does not actually contain the text "team b".

I use referenced and I use it to flag on the RESOURCES that the module creates since with REFERENCED you can pull the address which holds the module path.

This is one of the few queries that touched metadata outside the actual values block of the resource. With the addition of the create/action metadata to allow for filtering based on create update no-op it opens the door to parse in more metadata.

Let me know if that helps, we are currently running our deploy with alot of out of the box thinking until hopefully these gents get some bandwidth to dig further into the json.

Given I have aws_s3_bucket defined
Then it must have "module.moduletester." referenced
              "address": "module.moduletester.aws_s3_bucket.main",
              "mode": "managed",
              "type": "aws_s3_bucket",
              "name": "main",
              "provider_name": "registry.terraform.io/hashicorp/aws",
              "schema_version": 0,
              "values": {
                "acl": "private",
                "bucket": "module-bucket-tester",
                "bucket_prefix": null,
                "cors_rule": [],
                "force_destroy": false,
                "grant": [],
                "lifecycle_rule": [],
                "logging": [],
                "object_lock_configuration": [],
                "policy": "",
                ***REDACTED FOR BREVITY

I am using a bunch of negative tests to quantify module use until we can hopefully get the additional metadata parsed like in my request here below. 456

essentially getting more metadata into the

mdesmarest avatar Mar 25 '21 19:03 mdesmarest

You can also use address property for your specific case where you can access to terraform internal resource reference/address (like module.team-b-apps).

Apart from those, I see 2 problems on your approach. Of course, its hard to see anything just by reading this issue, hence you might already address these or these could be non applicable for you as well for any other reason.

  1. IMHO, if you are going to use identical two terraform code, it should not be copied unless they have to live in two different repositories. Utilising different backend.conf, -backend-conf parameter or workspaces with a Makefile could possibly provide you to run the same code for both team with different configurations (like resource counts, sizes, parameters, provider regions, etc.) in an easier way. You might already considered this and discarded this idea due to a reson that I don't know, hence just saying :)

  2. Checking address of a terraform resource does not mean much from a security perspective. Since a Team A creating a module ;

  module "team-a-apps" {
    source = "/path/to/module/related/with/some/other-team"
  }

could still create a problem depending on your code structure. Hence, instead of focusing on How teams construct their modules ?, IMHO, we should focus on What kind of resources a specific Team can/can not create or similar scenarios where we are focusing on the end-product instead of bi-products. Modules are just bi-products for terraform.

eerkunt avatar Apr 11 '21 17:04 eerkunt