Project: Checkov (Provisioning / Security & Compliance)
File: Handling Variables.md

layout: default published: true title: Handling Variables nav_order: 8 Checkov supports the evaluation of variables found in Terraform expressions. Variables are declared in `.tf` files where each variable has an identifying name, description, and optional default value. Checkov collects the default values of variables and assigns them to their corresponding references in Terraform expressions. The advantage of variable evaluation is to cover optional scenarios in which a forbidden value of a variable is set inside a Terraform resource configuration. In that scenario, the resource may not comply to security standards. This example uses the `CKVAWS20` check which validates if an S3 Bucket has an ACL defined which allows public access: ```python class S3PublicACL(BaseResourceCheck): def init(self): name = "S3 Bucket has an ACL defined which allows public access." id = "CKVAWS20" supportedresources = ['awss3_bucket'] categories = [CheckCategories.GENERAL_SECURITY] super().init(name=name, id=id, categories=categories, supportedresources=supportedresources) def scanresourceconf(self, conf): """ Looks for ACL configuration at awss3bucket: https://www.terraform.io/docs/providers/aws/r/s3_bucket.html :param conf: awss3bucket configuration :return: <CheckResult> """ if 'acl' in conf.keys(): acl_block = conf['acl'] if acl_block in [["public-read"],["public-read-write"],["website"]]: return CheckResult.FAILED return CheckResult.PASSED ``` If we have the Terraform configuration and variable files below, Checkov evaluates the `var.acl` variable to `public-acl`, which results in the check failing: ```python resource "awss3bucket" "my_bucket" { region = var.region bucket = local.bucket_name acl = var.acl force_destroy = true } ``` ```python variable "bucket_name" { default = "MyBucket" } variable "acl" { default = "public-read" } variable "region" { default = "us-west-2" } ``` ```python checkov -d . ... Check: CKVAWS20: "S3 Bucket has an ACL defined which allows public access." FAILED for resource: awss3bucket.my_bucket File: /main.tf:24-29 24 | resource "awss3bucket" "my_bucket" { 25 | region = var.region 26 | bucket = local.bucket_name 27 | acl = var.acl 28 | force_destroy = true 29 | } Variable acl (of /variables.tf) evaluated to value "public-acl" in expression: acl = ${var.acl} Variable region (of /variables.tf) evaluated to value "us-west-2" in expression: region = ${var.region} ``` To pass the check, the value of `var.acl` needs to be set to `private` as follows: ```python ... variable "acl" { default = "private" } ``` The check result now passes: ```python Check: CKVAWS20: "S3 Bucket has an ACL defined which allows public access." PASSED for resource: awss3bucket.template_bucket File: /main.tf:24-29 Variable acl (of /variables.tf) evaluated to value "private" in expression: acl = ${var.acl} Variable region (of /variables.tf) evaluated to value "us-west-2" in expression: region = ${var.region} ``` If available, each `PASSED/FAILED` check contains the evaluation information, which contains all the variables that were evaluated. Each variable contains its variable source file path, the evaluated value, and the expressions in which it was referenced: ```json evaluations: { '<var_name>': { 'varfile': '<variablefilerelativepath>', 'value': '<value>', 'definitions': [ { 'definition_name': 'name', 'definitionexpression': '${var.customername}_group', 'definitionpath': 'resource/0/awscognitousergroup/user_group/name/0' }, { 'definition_name': 'description', 'definitionexpression': '${var.customername} user group', 'definitionpath': 'resource/0/awscognitousergroup/user_group/description/0' } ] }, ... } ```