Skip to content

Latest commit

 

History

History
668 lines (563 loc) · 28.1 KB

README.md

File metadata and controls

668 lines (563 loc) · 28.1 KB

Tfchkr is a Python Terraform testing framework.

Introduction

Tfchkr is a Python Terraform testing framework that allows us to isolate our infrastructure as code to test for errors and compliance. A lot of the time, we blindly create resources with Terraform hoping the commands will work smoothly and security vulnerabilities are none. We can now test this process before moving forward without throwing it over the wall hoping for the best. With running tfchkr you can now test the Terraform code base for any syntax errors, as well as vulnerability errors. It logs each command and returns the results at the end whether they were successful or failed. This serves as a repeatable process that can be ran locally or with a CICD pipeline.

Setup

The first thing you will need to do before installing tfchkr is configure a local virutal environment. If you currently don't have a virtual environment installed, I would highly recommend pyenv.

Once you have a local virtual environment configured you only need to do a quick pip install of the tfchkr package.

Install and set up tfchkr for development

$ cd tfchkr

$ pip install --editable .
Obtaining file:///Users/tucker.m.mccoy/Github/tmccoy14/tfchkr
Requirement already satisfied: Click==7.0 in /Users/tucker.m.mccoy/.pyenv/versions/3.7.3/envs/tfchkrcli/lib/python3.7/site-packages (from tfchkr==0.1) (7.0)
Requirement already satisfied: colorama==0.4.3 in /Users/tucker.m.mccoy/.pyenv/versions/3.7.3/envs/tfchkrcli/lib/python3.7/site-packages (from tfchkr==0.1) (0.4.3)
Installing collected packages: tfchkr
  Found existing installation: tfchkr 0.1
    Uninstalling tfchkr-0.1:
      Successfully uninstalled tfchkr-0.1
  Running setup.py develop for tfchkr
Successfully installed tfchkr

Note: the --editable flag will provide you with a way to hot reload changes while you are working on new features.

If you are trying to install the package for usage just run: pip install ..

Getting Started

Once you have successfully installed tfchkr, you can confirm by running tfchkr

$ tfchkr
Usage: tfchkr [OPTIONS] COMMAND [ARGS]...

  tfchkr is a tool to run tests on Terraform modules and files.

Options:
  --home DIRECTORY  Project folder to operate on.
  -v, --verbose     Enables verbose mode.
  --version         Print the current version of tfchkr.
  --help            Show this message and exit.

Commands:
  run  Run the tests and compliance checks on Terraform file.

tfchkr run has two commands, tfchkr run test and tfchkr run compliance, that will run the tests and compliance checks on the specified Terraform modules or files.

$ tfchkr run --help
Usage: tfchkr run [OPTIONS] COMMAND [ARGS]...

  tfchkr test and compliance.

Options:
  --help  Show this message and exit.

Commands:
  compliance  Run the compliance checks.
  test        Run the tests.

TFCHKR RUN TEST

The tfchkr run test command accepts two parameters, the path to the Terraform directory and variables needed for the Terraform files.

This command will run through the terraform init, terraform plan, terraform apply, and terraform destroy commands to ensure the Terraform files are syntactically valid as well as the provider resources are set up correctly.

$ tfchkr run test --help
Usage: tfchkr run test [OPTIONS]

  Run the tests for the Terraform modules and files

  Ex. tfchkr run -p path/to/tf_directory

  Ex. tfchkr run -p path/to/tf_directory --var key=value --var key=value

Options:
  -p, --path TEXT  Path to Terraform directory.  [required]
  --var TEXT       Variables for Terraform files.
  --help           Show this message and exit.
# Run tests with with path only
$ tfchkr run test -p examples/tfstate
Initializing modules...
Downloading cloudposse/tfstate-backend/aws 0.25.0 for tfstate-backend...
- tfstate-backend in .terraform/modules/tfstate-backend
Downloading git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.17.0 for tfstate-backend.base_label...
- tfstate-backend.base_label in .terraform/modules/tfstate-backend.base_label
Downloading git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.17.0 for tfstate-backend.dynamodb_table_label...
- tfstate-backend.dynamodb_table_label in .terraform/modules/tfstate-backend.dynamodb_table_label
Downloading git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.17.0 for tfstate-backend.s3_bucket_label...
- tfstate-backend.s3_bucket_label in .terraform/modules/tfstate-backend.s3_bucket_label

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "null" (hashicorp/null) 2.1.2...
- Downloading plugin for provider "aws" (hashicorp/aws) 3.8.0...
- Downloading plugin for provider "template" (hashicorp/template) 2.1.2...
- Downloading plugin for provider "local" (hashicorp/local) 1.4.0...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

module.tfstate-backend.data.aws_region.current: Refreshing state...
module.tfstate-backend.data.aws_iam_policy_document.prevent_unencrypted_uploads[0]: Refreshing state...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
 <= read (data resources)

Terraform will perform the following actions:

  # module.tfstate-backend.data.template_file.terraform_backend_config will be read during apply
  # (config refers to values not yet known)
 <= data "template_file" "terraform_backend_config"  {
      + id       = (known after apply)
      + rendered = (known after apply)
      + template = <<~EOT
            terraform {
              required_version = ">= ${terraform_version}"

              backend "s3" {
                region         = "${region}"
                bucket         = "${bucket}"
                key            = "${terraform_state_file}"
                dynamodb_table = "${dynamodb_table}"
                profile        = "${profile}"
                role_arn       = "${role_arn}"
                encrypt        = "${encrypt}"
              }
            }
        EOT
      + vars     = {
          + "bucket"               = (known after apply)
          + "dynamodb_table"       = "test-tfstate-terra-testing-terraform-state-lock"
          + "encrypt"              = "true"
          + "profile"              = ""
          + "region"               = "us-east-2"
          + "role_arn"             = ""
          + "terraform_state_file" = "terraform.tfstate"
          + "terraform_version"    = "0.12.2"
        }
    }

  # module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0] will be created
  + resource "aws_dynamodb_table" "with_server_side_encryption" {
      + arn              = (known after apply)
      + billing_mode     = "PROVISIONED"
      + hash_key         = "LockID"
      + id               = (known after apply)
      + name             = "test-tfstate-terra-testing-terraform-state-lock"
      + read_capacity    = 5
      + stream_arn       = (known after apply)
      + stream_label     = (known after apply)
      + stream_view_type = (known after apply)
      + tags             = {
          + "Attributes"  = "terraform-state-lock"
          + "Name"        = "test-tfstate-terra-testing-terraform-state-lock"
          + "Namespace"   = "test-tfstate"
          + "Stage"       = "terra"
          + "environment" = "test"
          + "managed_by"  = "tfstate"
          + "poc"         = "tucker.m.mccoy"
          + "project"     = "terratesting"
        }
      + write_capacity   = 5

      + attribute {
          + name = "LockID"
          + type = "S"
        }

      + point_in_time_recovery {
          + enabled = false
        }

      + server_side_encryption {
          + enabled     = true
          + kms_key_arn = (known after apply)
        }
    }

  # module.tfstate-backend.aws_s3_bucket.default will be created
  + resource "aws_s3_bucket" "default" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "test-tfstate-terra-testing-terraform-state"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = true
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + policy                      = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "s3:PutObject"
                      + Condition = {
                          + StringNotEquals = {
                              + s3:x-amz-server-side-encryption = [
                                  + "aws:kms",
                                  + "AES256",
                                ]
                            }
                        }
                      + Effect    = "Deny"
                      + Principal = {
                          + AWS = "*"
                        }
                      + Resource  = "arn:aws:s3:::test-tfstate-terra-testing-terraform-state/*"
                      + Sid       = "DenyIncorrectEncryptionHeader"
                    },
                  + {
                      + Action    = "s3:PutObject"
                      + Condition = {
                          + Null = {
                              + s3:x-amz-server-side-encryption = "true"
                            }
                        }
                      + Effect    = "Deny"
                      + Principal = {
                          + AWS = "*"
                        }
                      + Resource  = "arn:aws:s3:::test-tfstate-terra-testing-terraform-state/*"
                      + Sid       = "DenyUnEncryptedObjectUploads"
                    },
                  + {
                      + Action    = "s3:*"
                      + Condition = {
                          + Bool = {
                              + aws:SecureTransport = "false"
                            }
                        }
                      + Effect    = "Deny"
                      + Principal = {
                          + AWS = "*"
                        }
                      + Resource  = [
                          + "arn:aws:s3:::test-tfstate-terra-testing-terraform-state/*",
                          + "arn:aws:s3:::test-tfstate-terra-testing-terraform-state",
                        ]
                      + Sid       = "EnforceTlsRequestsOnly"
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags                        = {
          + "Attributes"  = "terraform-state"
          + "Name"        = "test-tfstate-terra-testing-terraform-state"
          + "Namespace"   = "test-tfstate"
          + "Stage"       = "terra"
          + "environment" = "test"
          + "managed_by"  = "tfstate"
          + "poc"         = "tucker.m.mccoy"
          + "project"     = "terratesting"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + server_side_encryption_configuration {
          + rule {
              + apply_server_side_encryption_by_default {
                  + sse_algorithm = "AES256"
                }
            }
        }

      + versioning {
          + enabled    = true
          + mfa_delete = false
        }
    }

  # module.tfstate-backend.aws_s3_bucket_public_access_block.default[0] will be created
  + resource "aws_s3_bucket_public_access_block" "default" {
      + block_public_acls       = true
      + block_public_policy     = true
      + bucket                  = (known after apply)
      + id                      = (known after apply)
      + ignore_public_acls      = true
      + restrict_public_buckets = true
    }

Plan: 3 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.


module.tfstate-backend.data.aws_region.current: Refreshing state...
module.tfstate-backend.data.aws_iam_policy_document.prevent_unencrypted_uploads[0]: Refreshing state...
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Creating...
module.tfstate-backend.aws_s3_bucket.default: Creating...
module.tfstate-backend.aws_s3_bucket.default: Creation complete after 7s [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Creating...
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Creation complete after 0s [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Creation complete after 8s [id=test-tfstate-terra-testing-terraform-state-lock]
module.tfstate-backend.data.template_file.terraform_backend_config: Refreshing state...

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

module.tfstate-backend.data.aws_region.current: Refreshing state...
module.tfstate-backend.data.aws_iam_policy_document.prevent_unencrypted_uploads[0]: Refreshing state...
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Refreshing state... [id=test-tfstate-terra-testing-terraform-state-lock]
module.tfstate-backend.aws_s3_bucket.default: Refreshing state... [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Refreshing state... [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.data.template_file.terraform_backend_config: Refreshing state...
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Destroying... [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Destroying... [id=test-tfstate-terra-testing-terraform-state-lock]
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Destruction complete after 0s
module.tfstate-backend.aws_s3_bucket.default: Destroying... [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_s3_bucket.default: Destruction complete after 0s
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Destruction complete after 3s

Destroy complete! Resources: 3 destroyed.

RESULTS:
-------------------------

Passed checks: 4, Failed checks: 0

INIT -- SUCCESS
PLAN -- SUCCESS
APPLY -- SUCCESS
DESTROY -- SUCCESS
# Run tests with path and variables
$ tfchkr run test -p examples/tfstate_variables --var stage=terra --var name=testing
Initializing modules...
Downloading cloudposse/tfstate-backend/aws 0.25.0 for tfstate-backend...
- tfstate-backend in .terraform/modules/tfstate-backend
Downloading git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.17.0 for tfstate-backend.base_label...
- tfstate-backend.base_label in .terraform/modules/tfstate-backend.base_label
Downloading git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.17.0 for tfstate-backend.dynamodb_table_label...
- tfstate-backend.dynamodb_table_label in .terraform/modules/tfstate-backend.dynamodb_table_label
Downloading git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.17.0 for tfstate-backend.s3_bucket_label...
- tfstate-backend.s3_bucket_label in .terraform/modules/tfstate-backend.s3_bucket_label

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "null" (hashicorp/null) 2.1.2...
- Downloading plugin for provider "aws" (hashicorp/aws) 3.8.0...
- Downloading plugin for provider "template" (hashicorp/template) 2.1.2...
- Downloading plugin for provider "local" (hashicorp/local) 1.4.0...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

module.tfstate-backend.data.aws_region.current: Refreshing state...
module.tfstate-backend.data.aws_iam_policy_document.prevent_unencrypted_uploads[0]: Refreshing state...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
 <= read (data resources)

Terraform will perform the following actions:

  # module.tfstate-backend.data.template_file.terraform_backend_config will be read during apply
  # (config refers to values not yet known)
 <= data "template_file" "terraform_backend_config"  {
      + id       = (known after apply)
      + rendered = (known after apply)
      + template = <<~EOT
            terraform {
              required_version = ">= ${terraform_version}"

              backend "s3" {
                region         = "${region}"
                bucket         = "${bucket}"
                key            = "${terraform_state_file}"
                dynamodb_table = "${dynamodb_table}"
                profile        = "${profile}"
                role_arn       = "${role_arn}"
                encrypt        = "${encrypt}"
              }
            }
        EOT
      + vars     = {
          + "bucket"               = (known after apply)
          + "dynamodb_table"       = "test-tfstate-terra-testing-terraform-state-lock"
          + "encrypt"              = "true"
          + "profile"              = ""
          + "region"               = "us-east-2"
          + "role_arn"             = ""
          + "terraform_state_file" = "terraform.tfstate"
          + "terraform_version"    = "0.12.2"
        }
    }

  # module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0] will be created
  + resource "aws_dynamodb_table" "with_server_side_encryption" {
      + arn              = (known after apply)
      + billing_mode     = "PROVISIONED"
      + hash_key         = "LockID"
      + id               = (known after apply)
      + name             = "test-tfstate-terra-testing-terraform-state-lock"
      + read_capacity    = 5
      + stream_arn       = (known after apply)
      + stream_label     = (known after apply)
      + stream_view_type = (known after apply)
      + tags             = {
          + "Attributes"  = "terraform-state-lock"
          + "Name"        = "test-tfstate-terra-testing-terraform-state-lock"
          + "Namespace"   = "test-tfstate"
          + "Stage"       = "terra"
          + "environment" = "test"
          + "managed_by"  = "tfstate"
          + "poc"         = "tucker.m.mccoy"
          + "project"     = "terratesting"
        }
      + write_capacity   = 5

      + attribute {
          + name = "LockID"
          + type = "S"
        }

      + point_in_time_recovery {
          + enabled = false
        }

      + server_side_encryption {
          + enabled     = true
          + kms_key_arn = (known after apply)
        }
    }

  # module.tfstate-backend.aws_s3_bucket.default will be created
  + resource "aws_s3_bucket" "default" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "test-tfstate-terra-testing-terraform-state"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = true
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + policy                      = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "s3:PutObject"
                      + Condition = {
                          + StringNotEquals = {
                              + s3:x-amz-server-side-encryption = [
                                  + "aws:kms",
                                  + "AES256",
                                ]
                            }
                        }
                      + Effect    = "Deny"
                      + Principal = {
                          + AWS = "*"
                        }
                      + Resource  = "arn:aws:s3:::test-tfstate-terra-testing-terraform-state/*"
                      + Sid       = "DenyIncorrectEncryptionHeader"
                    },
                  + {
                      + Action    = "s3:PutObject"
                      + Condition = {
                          + Null = {
                              + s3:x-amz-server-side-encryption = "true"
                            }
                        }
                      + Effect    = "Deny"
                      + Principal = {
                          + AWS = "*"
                        }
                      + Resource  = "arn:aws:s3:::test-tfstate-terra-testing-terraform-state/*"
                      + Sid       = "DenyUnEncryptedObjectUploads"
                    },
                  + {
                      + Action    = "s3:*"
                      + Condition = {
                          + Bool = {
                              + aws:SecureTransport = "false"
                            }
                        }
                      + Effect    = "Deny"
                      + Principal = {
                          + AWS = "*"
                        }
                      + Resource  = [
                          + "arn:aws:s3:::test-tfstate-terra-testing-terraform-state/*",
                          + "arn:aws:s3:::test-tfstate-terra-testing-terraform-state",
                        ]
                      + Sid       = "EnforceTlsRequestsOnly"
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags                        = {
          + "Attributes"  = "terraform-state"
          + "Name"        = "test-tfstate-terra-testing-terraform-state"
          + "Namespace"   = "test-tfstate"
          + "Stage"       = "terra"
          + "environment" = "test"
          + "managed_by"  = "tfstate"
          + "poc"         = "tucker.m.mccoy"
          + "project"     = "terratesting"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + server_side_encryption_configuration {
          + rule {
              + apply_server_side_encryption_by_default {
                  + sse_algorithm = "AES256"
                }
            }
        }

      + versioning {
          + enabled    = true
          + mfa_delete = false
        }
    }

  # module.tfstate-backend.aws_s3_bucket_public_access_block.default[0] will be created
  + resource "aws_s3_bucket_public_access_block" "default" {
      + block_public_acls       = true
      + block_public_policy     = true
      + bucket                  = (known after apply)
      + id                      = (known after apply)
      + ignore_public_acls      = true
      + restrict_public_buckets = true
    }

Plan: 3 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.


module.tfstate-backend.data.aws_region.current: Refreshing state...
module.tfstate-backend.data.aws_iam_policy_document.prevent_unencrypted_uploads[0]: Refreshing state...
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Creating...
module.tfstate-backend.aws_s3_bucket.default: Creating...
module.tfstate-backend.aws_s3_bucket.default: Creation complete after 7s [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Creating...
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Creation complete after 0s [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Creation complete after 8s [id=test-tfstate-terra-testing-terraform-state-lock]
module.tfstate-backend.data.template_file.terraform_backend_config: Refreshing state...

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

module.tfstate-backend.data.aws_region.current: Refreshing state...
module.tfstate-backend.data.aws_iam_policy_document.prevent_unencrypted_uploads[0]: Refreshing state...
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Refreshing state... [id=test-tfstate-terra-testing-terraform-state-lock]
module.tfstate-backend.aws_s3_bucket.default: Refreshing state... [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Refreshing state... [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.data.template_file.terraform_backend_config: Refreshing state...
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Destroying... [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Destroying... [id=test-tfstate-terra-testing-terraform-state-lock]
module.tfstate-backend.aws_s3_bucket_public_access_block.default[0]: Destruction complete after 0s
module.tfstate-backend.aws_s3_bucket.default: Destroying... [id=test-tfstate-terra-testing-terraform-state]
module.tfstate-backend.aws_s3_bucket.default: Destruction complete after 0s
module.tfstate-backend.aws_dynamodb_table.with_server_side_encryption[0]: Destruction complete after 3s

Destroy complete! Resources: 3 destroyed.

RESULTS:
-------------------------

Passed checks: 4, Failed checks: 0

INIT -- SUCCESS
PLAN -- SUCCESS
APPLY -- SUCCESS
DESTROY -- SUCCESS

TFCHKR RUN COMPLIANCE

The tfchkr run compliance command accepts one parameter, the path to the Terraform directory. Below are examples of how to use the two commands.

This command will use a third party module called checkov to detect any security and compliance misconfigurations in the Terraform files.

$ tfchkr run compliance --help
Usage: tfchkr run compliance [OPTIONS]

  Run the compliance checks for the Terraform modules and files

  Ex. tfchkr compliance -p path/to/tf_directory

Options:
  -p, --path TEXT  Path to Terraform directory.  [required]
  --help           Show this message and exit.
$ tfchkr run compliance -p examples/tfstate_variables
terraform scan results:

Passed checks: 1, Failed checks: 0, Skipped checks: 0

Check: CKV_AWS_41: "Ensure no hard coded AWS access key and and secret key exists in provider"
	PASSED for resource: aws.default
	File: /main.tf:8-11
	Guide: https://docs.bridgecrew.io/docs/bc_aws_secrets_5