hashicorp / vscode-terraform

HashiCorp Terraform VSCode extension
https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform
Mozilla Public License 2.0
919 stars 178 forks source link

Autocomplete stops working from one file to another in the same module #1793

Open life5ign opened 1 month ago

life5ign commented 1 month ago

Extension Version

~v0.2.5~ EDIT v2.30.1

VS Code Version

Version: 1.84.0 Commit: d037ac076cee195194f93ce6fe2bdfe2969cc82d Date: 2023-11-01T11:28:21.782Z Electron: 25.9.2 ElectronBuildId: 24603566 Chromium: 114.0.5735.289 Node.js: 18.15.0 V8: 11.4.183.29-electron.0 OS: Linux x64 6.9.3-76060903-generic

Operating System

Linux myhost 6.9.3-76060903-generic #202405300957~1718348209~22.04~7817b67 SMP PREEMPT_DYNAMIC Mon J x86_64 x86_64 x86_64 GNU/Linux

Terraform Version

Terraform v1.6.6 on linux_amd64 + provider registry.terraform.io/alekc/kubectl v2.0.4 + provider registry.terraform.io/hashicorp/aws v5.26.0 + provider registry.terraform.io/hashicorp/helm v2.14.0 + provider registry.terraform.io/hashicorp/http v3.4.3 + provider registry.terraform.io/hashicorp/kubernetes v2.29.0 + provider registry.terraform.io/hashicorp/local v2.5.1 + provider registry.terraform.io/hashicorp/random v3.6.2 Your version of Terraform is out of date! The latest version is 1.9.2. You can update by downloading from https://www.terraform.io/downloads.html

Steps to Reproduce

  1. open project
  2. try to autocomplete e.g. a var or resource from file_a.tf in file_b.tf
  3. observe no autocompletion even when pressing Ctrl+Space

Expected Behavior

Autocompletion works.

Actual Behavior

It doesn't work all (most of) the time; it does work intermittently. Syntax highlighting also doesn't work..e.g. in aws_vpc.myresource, e.g., "myresource" will be white, not red, when the autocomplete doesn't work.

Terraform Configuration

Project Structure

This is generic aws provider resources and variable declarations to produce. The project has about 5 modules in /modules and several modules that call those reusable modules, in /envs/*; it is not massive.

No response

Gist

No response

Anything Else?

it works sometimes..I did a test on a small project with a main.tf, locals.tf, and vars.tf in one module, and autocomplete/intellisense works among the different files.

Workarounds

No response

References

No response

Help Wanted

Community Note

dbanck commented 1 month ago

Hi @life5ign,

Can you please check if you have the official HashiCorp Terraform extension installed? The version v0.2.5 indicates that you may be using another extension.

You can find the extension in the marketplace: https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform

life5ign commented 1 month ago

@dbanck sorry I accidentally copied the version from the wrong one; I do have the official extension installed, and I have version v2.30.1

image

dbanck commented 1 month ago

Thanks for checking!

Do you have multiple Terraform extensions installed? Can you share the full list of active extensions (use code --list-extensions to get it)?

We have gotten similar reports in the past from people who installed some other Terraform extensions and either never installed ours (hashicorp.terraform) or installed several that ended up conflicting with each other. With that in mind, if you could try to disable or uninstall any other non-HashiCorp Terraform/HCL extensions, or confirm that there aren't any such conflicting extensions, that would be great!

life5ign commented 1 month ago

Thanks @dbanck, I just checked and I have no other terraform extensions enabled:

code --list-extensions | grep -i 't.*f'
editorconfig.editorconfig
hashicorp.terraform
jeff-hykin.better-dockerfile-syntax

code --list-extensions output:

aaron-bond.better-comments
akamud.vscode-theme-onedark
anbuselvanrocky.bootstrap5-vscode
angular.ng-template
batisteo.vscode-django
bceskavich.theme-dracula-at-night
bmalehorn.shell-syntax
christian-kohler.npm-intellisense
christian-kohler.path-intellisense
dbaeumer.vscode-eslint
donjayamanne.githistory
dracula-theme.theme-dracula
ecmel.vscode-html-css
editorconfig.editorconfig
esbenp.prettier-vscode
evan-buss.font-switcher
formulahendry.auto-rename-tag
gerane.theme-dark-dracula
gerane.theme-dracula
ginfuru.ginfuru-better-solarized-dark-theme
github.copilot
github.copilot-chat
github.vscode-github-actions
hashicorp.terraform
jeff-hykin.better-dockerfile-syntax
johnpapa.angular-essentials
johnpapa.angular2
johnpapa.vscode-peacock
johnpapa.winteriscoming
kevinrose.vsc-python-indent
michijs.vscode-mathml
mikestead.dotenv
ms-azuretools.vscode-docker
ms-kubernetes-tools.vscode-kubernetes-tools
ms-python.debugpy
ms-python.isort
ms-python.python
ms-python.vscode-pylance
ms-toolsai.jupyter
ms-toolsai.jupyter-keymap
ms-toolsai.jupyter-renderers
ms-toolsai.vscode-jupyter-cell-tags
ms-toolsai.vscode-jupyter-slideshow
ms-vscode-remote.remote-containers
ms-vscode-remote.remote-ssh
ms-vscode-remote.remote-ssh-edit
ms-vscode-remote.remote-wsl
ms-vscode-remote.vscode-remote-extensionpack
ms-vscode.remote-explorer
ms-vscode.remote-server
muath-ye.composer-intelephense
nicolasvuillamy.vscode-groovy-lint
njpwerner.autodocstring
nrwl.angular-console
oouo-diogo-perdigao.docthis
p1c2u.docker-compose
pkief.material-icon-theme
redhat.ansible
redhat.vscode-yaml
ritwickdey.liveserver
samuelcolvin.jinjahtml
thekalinga.bootstrap4-vscode
timonwong.shellcheck
truman.autocomplate-shell
vscodevim.vim
wholroyd.jinja
xabikos.javascriptsnippets
xdebug.php-debug
xdebug.php-pack
yzane.markdown-pdf
yzhang.markdown-all-in-one
zobo.php-intellisense
jpogran commented 1 month ago

It doesn't work all (most of) the time; it does work intermittently. Syntax highlighting also doesn't work..e.g. in aws_vpc.myresource, e.g., "myresource" will be white, not red, when the autocomplete doesn't work.

These exact symptoms are the classic presentation of one or more extensions activating for the same language. VS Code, without prior configuration, allows any extension to provide support for any file.

If two extensions advertise Terraform support, which one "wins" is entirely up to which VS Code decides to activate first, which is non-deterministic in order. This can change order every time VS Code is opened, resulting in "intermittent" behavior. In addition one extension can offer just syntax highlighting and is activated, while the other offers language server support and never is activated, resulting in the user never seeing the language server support and thinking it's broken.

Differences in syntax highlighting indicate another source for the information to decide what token to highlight. We provide both TextMate based syntax highlighting as well as semantic token highlighting provided by terraform-ls. If we aren't activated, the token color you are used to seeing won't be there because terraform-ls was not started.

This is the reason why we're asking about other extensions.

code --list-extensions | grep -i 't.*f'

Unfortunately listing the names of extensions and searching for any text starting with one letter and ending with another is not going to reliably tell you if an extension is contributing features for a given language. Names of extensions are not guaranteed to have anything to do with the language they support. If you were to go this route, you would have to open each extension in the Extension Manager sidebar and examine the Features tab. Each extension has to advertise there what languages it provides features for.

An easier method would be to open a Terraform file and examine the lower right hand corner. If you click on Terraform, it should look something like this:

image

Another method is to examine your settings file and see if you configured VS Code to always use another extension for Terraform files:

"files.associations": {
  "*.tf": "some-other-extension",
  "*.tfvars": "some-other-extension"
}

You can alternately start VS Code with an empty Profile and just the HashiCorp extension to verify that it is our extension that is not working. If that is the case, we'd love to see your User Settings and the debug log generated from a session where things are not working, and we can provide private means of submittal of this information.

image
life5ign commented 1 month ago

Thank you @jpogran

I'm following your advice, thank you very much for your time. Does this explain how it all works fine for smaller projects though? The only thing that could be different is workspace settings I think?

Regardless, here is the output from your suggested steps.

Lower right terraform file format activated extensions

image

settings

Defaults

    // Configure [glob patterns](https://aka.ms/vscode-glob-patterns) of file associations to languages (for example `"*.extension": "html"`). Patterns will match on the absolute path of a file if they contain a path separator and will match on the name of the file otherwise. These have precedence over the default associations of the languages installed.
    "files.associations": {},

User settings

    "files.associations": {
        "*.yml": "yaml",
        "*.tf": "terraform"
    },

Workspace Settings

image

New Profile with only HC Terraform extension enabled

Extensions

code --profile terraform_extension_debug --list-extensions| clipcopy

hashicorp.terraform

Depiction of issue

image

Debug Log

I can't figure out how to generate one...all search results plus command pallete only show me stuff about the Debugger for writing code within vscode..I will happily upload it; can you tell me how?

Real-Gecko commented 1 month ago

Confirming with v2.32.1 of the extension and VSCode 1.91.1. I was working on project and autocomplete was working as expected for four providers. Then suddenly it stopped working, autocomplete suggestions are working for only one of four. I created a new project, added same four providers there and suddenly it started to work. So it works in new project and does not work in old one with the exact same providers. Maybe there's some kind of cache that needs to be cleared?

Real-Gecko commented 1 month ago

Just checked and it stopped working in new folder too after VSCode restart. My providers.tf

terraform {
  required_providers {
    yandex = {
      source  = "yandex-cloud/yandex"
      version = "0.124.0"
    }
    ansible = {
      source  = "ansible/ansible"
      version = "1.3.0"
    }
    gitlab = {
      source  = "gitlabhq/gitlab"
      version = "~>17.1"
    }
    swarm = {
      source  = "aucloud/swarm"
      version = "~> 1.2"
    }
  }
}

provider "yandex" {
}
provider "ansible" {
}
provider "gitlab" {
}
provider "swarm" {
}
Real-Gecko commented 1 month ago

Ok, some progress! As soon as I add HTTP backend configuration autocompletions break, remove backend and everything works again. I use GitLab HTTP backend to store state, setup is ordinary:

# backend.tf
terraform {
  backend "http" {
    address        = "https://gitlab.com/api/v4/projects/<project_id>/terraform/state/production"
    lock_address   = "https://gitlab.com/api/v4/projects/<project_id>/terraform/state/production/lock"
    unlock_address = "https://gitlab.com/api/v4/projects/<project_id>/terraform/state/production/lock"
    username       = "<username>"
    lock_method    = "POST"
    unlock_method  = "DELETE"
    retry_wait_min = 5
  }
}

TF_HTTP_PASSWORD env var is set, so terraform can access state from CLI with no issues.

dbanck commented 1 month ago

Thank you for providing additional context and further digging into this issue, @Real-Gecko!

Most of the completion in terraform-ls is powered by provider schemas. The schemas contain the provider configuration, data sources, and resources that a provider ships. The language server has two ways to get the schemas: bundled into the binary or via the Terraform CLI.

We bundle all official and provider schemas into the binary at build time. For the four providers mentioned, this only applies to gitlab. So in a minimal project with the four providers, you will only get completion for resources from the gitlab provider.

CleanShot 2024-07-29 at 12 10 38@2x

After running terraform init we can load the schemas for the other three providers with terraform providers schema -json. Without a backend in place, Terraform will simply download the providers to your workspace.

CleanShot 2024-07-29 at 12 12 21@2x

(Note also the underlined provider blocks. This indicates that we have a schema available and will show the version and a link to the documentation on hover)

Once you add a backend, the Terraform CLI will error when it tries to retrieve the provider schemas. So we can't load the schemas for the other three providers and are left with the bundled gitlab schema.

CleanShot 2024-07-29 at 12 15 58@2x

Can you check the logs to see if this is happening to you? (View -> Output -> Select HashiCorp Terraform in the top right and look for OpTypeObtainSchema)

Real-Gecko commented 1 month ago

Hi, my logs are: image

That's the only error related to OpTypeObtainSchema. TF_HTTP_PASSWORD is set for backend auth, I also tried terraform init -upgrade, it worked without errors. Any other ways to debug?

Real-Gecko commented 1 month ago

I've tried putting password in backend block:

terraform {
  backend "http" {
    address        = "https://gitlab.com/api/v4/projects/<project_id>/terraform/state/production"
    lock_address   = "https://gitlab.com/api/v4/projects/<project_id>/terraform/state/production/lock"
    unlock_address = "https://gitlab.com/api/v4/projects/<project_id>/terraform/state/production/lock"
    username       = "<username>"
    lock_method    = "POST"
    unlock_method  = "DELETE"
    retry_wait_min = 5
    password       = "<password>"
  }
}

And now autocompletion works, however it's not the solution, cause storing passwords in plaintext is not safe :D

life5ign commented 1 month ago

I figured out the primary problem I'm having: Autocomplete/intellisense doesn't work in nested keys inside objects; see my comment in this thread https://github.com/hashicorp/vscode-terraform/issues/1793#issuecomment-2243468133

In those screenshots, you can see I'm trying to autocomplete local.values_loki.foobar (which I'm building so I can pass it to templatefile, a pretty solid use-case); it does not work with any kind of completable item, e.g. variable, resource, module output, etc. But local.foobar' autocompletion of value would work... since it's not nested in another key.

Autocomplete also doesn't work inside nested HCL objects being used in resources, e.g. below: image

I tried multiple tests like @Real-Gecko where I changed my backed from remote S3 to local, and found that the same problem above persists across all situations; so I think we're dealing with different issues here: for me, autocomplete in all other ways than the nested issue I described above does work, for both local and remote state.

I did do a system reboot since I was having the last problem and OP'd here, and I swear other autocomplete situations weren't working, but now I can't demonstrate it. I'll post again if other scenarios stop working.

This is still a rather significant inconvenience, since a lot of the time we are building objects with nested keys. E.g. as above, using my various resources' and modules' attributes/outputs as values in my jsonencode'd HCL object to create a JSON IAM policy statement for an aws provider resource.

Thanks

jnesta-lh commented 1 month ago

I figured out the primary problem I'm having: Autocomplete/intellisense doesn't work in nested keys inside objects

I have the same problem. For example:

variable "foo" {
  type = object({
    value1 = string
  })
}

This will auto-complete "value1" as soon as I start typing "v". Furthermore, mistyping "value1" as "value11" will result in a red squiggly line, as expected.

However, when we change it to use a map:

variable "foo" {
  type = map(object({
    value1 = string
  }))
}

This ruins auto-complete. It also ruins type validation, meaning that I can actually mistype "value1" as "value11" and I don't get any red squiggly lines.

This is kind of heartbreaking, since I am coming from a TypeScript background where this kind of thing would always be type-safe.