antonbabenko / pre-commit-terraform

pre-commit git hooks to take care of Terraform configurations 🇺🇦
MIT License
3.17k stars 535 forks source link

Question about Invalid value for variable because of a validation rule. #718

Closed dmattoninnovtech closed 2 weeks ago

dmattoninnovtech commented 2 weeks ago

Hello everyone,

I test the pre-commit hook for Terraform with terraform_validate. And I have this error Error: Invalid value for variable because of This was checked by the validation rule for var.publisher_name.

The files are in a directory that will be used as a Terraform module.

Error message

╷
│ Error: Invalid value for variable
│
│   on variables.tf line 81:
│   81: variable "publisher_name" {
│     ├────────────────
│     │ var.publisher_name is a string
│
│ Publisher name can't be empty. The length is between 3 and 65 characters.
│
│ This was checked by the validation rule at variables.tf:85,3-13.

In the main.tf

resource "azurerm_api_management" "az_apim" {
  name                = local.resource_name
  location            = var.location
  resource_group_name = var.resource_group_name
  publisher_name      = var.publisher_name
  ...
}

And in the variables.tf

variable "publisher_name" {
  type        = string
  description = "The name of publisher/company."

  validation {
    condition     = can(regex("^(?!\\s*$).{3,65}$", var.publisher_name))
    error_message = "Publisher name can't be empty. The length is between 3 and 65 characters."
  }
}

The resource will be used later as a module and the variable publisher_name will be required.

So is it possible to use mock data or may be there is another processs or method to avoid this kind of error ?

Thanks for your help. David

MaxymVlasov commented 2 weeks ago

How do you provide value to this variable now?

Because in current setup teraform plan will fail with same error

dmattoninnovtech commented 2 weeks ago

Actually I don't provide any value, as it is a Terraform module. I just want to validate that my development is OK for this TF module, but may be I shouldn't use terraform_validate.

Later I will use this module with Terragrunt and provide values.

MaxymVlasov commented 2 weeks ago

That's interesting, as we have similar validation options in module and never faced such errors.

Whatever, try https://github.com/antonbabenko/pre-commit-terraform?tab=readme-ov-file#all-hooks-set-env-vars-inside-hook-at-runtime

https://developer.hashicorp.com/terraform/language/values/variables#environment-variables

dmattoninnovtech commented 2 weeks ago

Well, I just try with these options and it doesn't work. I have the same error message

# TEST 1
- id: terraform_validate
  args:
    - --env-vars=TF_VAR_publisher_name=publisher_name

# TEST 2
- id: terraform_validate
  args:
    - --env-vars=TF_VAR_publisher_name='publisher_name'

# TEST 3
- id: terraform_validate
  args:
    - --env-vars=TF_VAR_publisher_name="publisher_name"

Actually, I have a monorepo for all my TF modules. May be, that's the problem. Here is the tree

.
├── .gitignore
├── .gitlab-ci.yml
├── .pre-commit-config.yaml
├── .terraform-docs.yml
├── .tflint.hcl
├── CHANGELOG.md
├── README.md
├── TODO.md
├── package-lock.json
├── package.json
├── release.config.js
├── scripts
│   ├── create_new_module.sh
│   └── update_tf_docs.sh
└── terraform
    ├── aks-cluster
    │   ├── README.md
    │   ├── main.tf
    │   ├── outputs.tf
    │   ├── providers.tf
    │   ├── variables.tf
    │   └── version.tf
    ├── api-management
    │   ├── README.md
    │   ├── main.tf
    │   ├── outputs.tf
    │   ├── providers.tf
    │   ├── variables.tf
    │   └── version.tf
yermulnik commented 2 weeks ago

Actually I don't provide any value, as it is a Terraform module.

It's every directory with Terraform code is "module". Terraform can't figure out when it is child module and when it is root module 🤷🏻 root module is where you run terraform binary, and child module is what you call via module "label" {} code block.

I just want to validate that my development is OK for this TF module, but may be I shouldn't use terraform_validate.

It's best to tf validate your TF code, especially when you develop TF modules. What I usually do to mock data in similar conditions to yours, is I add files with fake data. In your case it should be all fine to put terraform.tfvars file into module dir and add it to .gitignore so that it is taken into account only locally (else you'd need to wait for us to adjust pre-commit-terraform code to allow mixed-case var names — see below).

Whatever, try antonbabenko/pre-commit-terraform#all-hooks-set-env-vars-inside-hook-at-runtime

@MaxymVlasov We allow only uppercase vars: https://github.com/antonbabenko/pre-commit-terraform/blob/master/hooks/_common.sh#L131 Looks like we need to weaken requirements for var names despite https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html: «Uppercase and lowercase letters shall retain their unique identities and shall not be folded together.»

yermulnik commented 2 weeks ago

That's interesting, as we have similar validation options in module and never faced such errors.

Interestingly, that I haven't faced such issues too 🤔 TS might be having some bit of setup that we don't know of...

ps: ^(?!\\s*$).{3,65}$ — this regex's author went overcomplicating simple things =) The ^\\S{3,65}$ is probably what is simpler and more readable (3 to 65 non-whitespace chars).

dmattoninnovtech commented 2 weeks ago

Thanks for your help. I use a terraform.tfvars and the error has disappeared.

And I need to refactor all my regex, they seem not really working.

dmattoninnovtech commented 2 weeks ago

Quick update. I update the regex from ^(?!\\s*$).{3,65}$ (thanks ChatG*T) to ^\\S{3,65}$ (thanks @yermulnik), removed the terraform.tfvars. No more error.

So the main problem is, well are my regex. They seem to overcomplicated for TF.

MaxymVlasov commented 2 weeks ago

Well image

yermulnik commented 2 weeks ago

Quick update. I update the regex from ^(?!\\s*$).{3,65}$ (thanks ChatG*T) to ^\\S{3,65}$ (thanks @yermulnik), removed the terraform.tfvars. No more error.

So the main problem is, well are my regex. They seem to overcomplicated for TF.

Beware that I only guesstimated what your intent was re the regex. If you provide your requirement for the value, I'd provide a more precise regex (or TF var value validation in a broader meaning as regex isn't the only way to validate var values).