Skip to content

Commit

Permalink
(TF-18674) Document Terraform Stacks support (#1802)
Browse files Browse the repository at this point in the history
* Document Terraform Stacks support
  • Loading branch information
jpogran authored and ansgarm committed Sep 23, 2024
1 parent 5cda7e1 commit 53cb152
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 116 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/ENHANCEMENTS-20240827-144543.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: ENHANCEMENTS
body: Document Terraform Stacks support
time: 2024-08-27T14:45:43.975259-04:00
custom:
Issue: "1802"
Repository: terraform-ls
207 changes: 109 additions & 98 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ The following filetypes are supported by the Terraform Language Server:

- `terraform` - standard `*.tf` config files
- `terraform-vars` - variable files (`*.tfvars`)
- `terraform-stack` - standard `*.tfstack.hcl` files
- `terraform-deploy` - standard `*.tfstack.hcl` files

*NOTE* Clients should be configured to follow the above language ID conventions
_NOTE:_ Clients should be configured to follow the above language ID conventions
and do **not** send `*.tf.json`, `*.tfvars.json` nor Packer HCL config
nor any other HCL config files as the server is not
equipped to handle these file types.
nor any other HCL config files as the server is not equipped to handle these file types.

In most clients with a dedicated Terraform extension/plugin this is
already the default configuration, so you should not need to worry about it.
Most clients with a dedicated Terraform extension/plugin
already have the default configuration, so you should not need to worry about it.

Instructions for popular IDEs are below and pull requests
for updates or addition of more IDEs are welcomed.
Expand All @@ -25,78 +26,53 @@ how you may configure the settings.

## Workspaces / Folders / Files

Most editors support opening folders. Such a root folder is commonly referred to
as "workspace". Opening folders is always preferred over individual files
as it allows the language server to index the whole folder and keep track
of changes more easily. We do however support "single-file mode" which provides
limited IntelliSense.
Most text editors allow you to open files to edit a single file, or a folder to
edit many files at once. When opening a folder, this is commonly referred to
as "workspace" or "root folder".

Indexing enables IntelliSense related to `module` blocks,
such as go-to-definition, completion of `module.*` references,
or workspace-wide symbol lookup.
Opening folders is always preferred over individual files as it allows
the language server to index the whole folder and keep track of changes
more easily. We do however support "single-file mode" which provides
limited IntelliSense.

Indexing enables IntelliSense related to `module` blocks, such as
go-to-definition, completion of `module.*` references, or workspace-wide
symbol lookup.

The server will _not_ index any folders or files above the workspace root
initially opened in the editor.

## Emacs
## Editors

If you are using `use-package`, you can put this in the [init.el](https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html)
file to install `lsp-mode`:
### Visual Studio Code

```emacs-lisp
(use-package lsp-mode
:ensure t
:hook ((terraform-mode . lsp-deferred)))
```
- Install the [Terraform VS Code Extension](https://marketplace.visualstudio.com/items?itemName=hashicorp.terraform) `>=2.24.0`
- The latest compatible version of [terraform-ls](https://github.com/hashicorp/terraform-ls) is bundled with the extension
- See [VS Code Configuration](https://github.com/hashicorp/vscode-terraform/blob/main/README.md#configuration) in case you need to tweak anything. Default settings should work for majority of users.

There are various other ways to install `lsp-mode` and they are
documented [here.](https://emacs-lsp.github.io/lsp-mode/page/installation/#installation)
### Sublime Text

The `lsp-mode` language client for Terraform supports various features
like semantic tokens, code lens for references etc. There is more
detailed documentation [here](https://emacs-lsp.github.io/lsp-mode/page/lsp-terraform-ls/).
- Install the [LSP package](https://github.com/sublimelsp/LSP#installation)
- Install the [LSP-terraform package](https://github.com/sublimelsp/LSP-terraform#installation)

## IntelliJ IDE
### Vim / NeoVim

- Install [LSP Support plugin](https://plugins.jetbrains.com/plugin/10209-lsp-support)
- Open Settings
- Go to `Languages & Frameworks → Language Server Protocol → Server Definitions`
- Pick `Executable`
- set `Extension` to `tf`
- set `Path` to `terraform-ls`
- set `Args` to `serve`
- Confirm by clicking `Apply`
#### coc.nvim

Please note that the [Terraform plugin](https://plugins.jetbrains.com/plugin/7808-hashicorp-terraform--hcl-language-support)
provides overlapping functionality (and more features at the time of writing).
As a result having both enabled at the same time may result in suboptimal UX,
such as duplicate completion candidates.

## Sublime Text

- Install the [LSP package](https://github.com/sublimelsp/LSP#installation)
- Install the [LSP-terraform package](https://github.com/sublimelsp/LSP-terraform#installation)

## Vim / NeoVim
### coc.nvim

- Install the [coc.nvim plugin](https://github.com/neoclide/coc.nvim)
- Add the following snippet to the `coc-setting.json` file (editable via `:CocConfig` in NeoVim)
- Install the [coc.nvim plugin](https://github.com/neoclide/coc.nvim)
- Add the following snippet to the `coc-setting.json` file (editable via `:CocConfig` in NeoVim)

```json
{
"languageserver": {
"terraform": {
"command": "terraform-ls",
"args": ["serve"],
"filetypes": [
"terraform",
"tf"
],
"initializationOptions": {},
"settings": {}
}
}
"languageserver": {
"terraform": {
"command": "terraform-ls",
"args": ["serve"],
"filetypes": ["terraform", "tf"],
"initializationOptions": {},
"settings": {}
}
}
}
```

Expand All @@ -107,14 +83,14 @@ Make sure to read through the [example vim configuration](https://github.com/neo
inoremap <silent><expr> <c-space> coc#refresh()
```

### vim-lsp
#### vim-lsp

- [Install](https://opensource.com/article/20/2/how-install-vim-plugins) the following plugins:
* [async.vim plugin](https://github.com/prabirshrestha/async.vim)
* [vim-lsp plugin](https://github.com/prabirshrestha/vim-lsp)
* [asyncomplete.vim plugin](https://github.com/prabirshrestha/asyncomplete.vim)
* [asyncomplete-lsp.vim plugin](https://github.com/prabirshrestha/asyncomplete-lsp.vim)
- Add the following to your `.vimrc`:
- [Install](https://opensource.com/article/20/2/how-install-vim-plugins) the following plugins:
- [async.vim plugin](https://github.com/prabirshrestha/async.vim)
- [vim-lsp plugin](https://github.com/prabirshrestha/vim-lsp)
- [asyncomplete.vim plugin](https://github.com/prabirshrestha/asyncomplete.vim)
- [asyncomplete-lsp.vim plugin](https://github.com/prabirshrestha/asyncomplete-lsp.vim)
- Add the following to your `.vimrc`:

```vim
if executable('terraform-ls')
Expand All @@ -126,10 +102,11 @@ if executable('terraform-ls')
endif
```

### YouCompleteMe
- [Install](https://opensource.com/article/20/2/how-install-vim-plugins) the following plugins:
* [YouCompleteMe plugin](https://github.com/ycm-core/YouCompleteMe)
- Add the following to your `.vimrc`:
#### YouCompleteMe

- [Install](https://opensource.com/article/20/2/how-install-vim-plugins) the following plugins:
- [YouCompleteMe plugin](https://github.com/ycm-core/YouCompleteMe)
- Add the following to your `.vimrc`:

```vim
" Remove this line if additional custom language servers are set elsewhere
Expand All @@ -147,21 +124,21 @@ if executable('terraform-ls')
endif
```

### LanguageClient-neovim
#### LanguageClient-neovim

- Install the [LanguageClient-neovim plugin](https://github.com/autozimu/LanguageClient-neovim)
- Add the following to your `.vimrc`:
- Install the [LanguageClient-neovim plugin](https://github.com/autozimu/LanguageClient-neovim)
- Add the following to your `.vimrc`:

```vim
let g:LanguageClient_serverCommands = {
\ 'terraform': ['terraform-ls', 'serve'],
\ }
```

### Neovim v0.5.0+
#### Neovim v0.5.0+

- Install the [nvim-lspconfig plugin](https://github.com/neovim/nvim-lspconfig)
- Add the following to your `.vimrc` or `init.vim`:
- Install the [nvim-lspconfig plugin](https://github.com/neovim/nvim-lspconfig)
- Add the following to your `.vimrc` or `init.vim`:

```vim
lua <<EOF
Expand All @@ -170,7 +147,9 @@ EOF
autocmd BufWritePre *.tfvars lua vim.lsp.buf.formatting_sync()
autocmd BufWritePre *.tf lua vim.lsp.buf.formatting_sync()
```
- If you are using `init.lua`:

- If you are using `init.lua`:

```lua
require'lspconfig'.terraformls.setup{}
vim.api.nvim_create_autocmd({"BufWritePre"}, {
Expand All @@ -179,10 +158,10 @@ vim.api.nvim_create_autocmd({"BufWritePre"}, {
})
```

### Neovim v0.8.0+
#### Neovim v0.8.0+

- Install the [nvim-lspconfig plugin](https://github.com/neovim/nvim-lspconfig)
- Add the following to your `.vimrc` or `init.vim`:
- Install the [nvim-lspconfig plugin](https://github.com/neovim/nvim-lspconfig)
- Add the following to your `.vimrc` or `init.vim`:

```vim
lua <<EOF
Expand All @@ -191,7 +170,9 @@ EOF
autocmd BufWritePre *.tfvars lua vim.lsp.buf.format()
autocmd BufWritePre *.tf lua vim.lsp.buf.format()
```
- If you are using `init.lua`:

- If you are using `init.lua`:

```lua
require'lspconfig'.terraformls.setup{}
vim.api.nvim_create_autocmd({"BufWritePre"}, {
Expand All @@ -204,31 +185,60 @@ vim.api.nvim_create_autocmd({"BufWritePre"}, {

Make sure to read through to [server_configurations.md#terraformls](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#terraformls) if you need more detailed settings.

## VS Code
### Emacs

If you are using `use-package`, you can put this in the [init.el](https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html)
file to install `lsp-mode`:

```emacs-lisp
(use-package lsp-mode
:ensure t
:hook ((terraform-mode . lsp-deferred)))
```

There are various other ways to install `lsp-mode` and they are
documented [here.](https://emacs-lsp.github.io/lsp-mode/page/installation/#installation)

The `lsp-mode` language client for Terraform supports various features
like semantic tokens, code lens for references etc. There is more
detailed documentation [here](https://emacs-lsp.github.io/lsp-mode/page/lsp-terraform-ls/).

- Install [Terraform VS Code Extension](https://marketplace.visualstudio.com/items?itemName=hashicorp.terraform) `>=2.24.0`
- Latest compatible version of the language server is bundled with the extension
- See [Configuration](https://github.com/hashicorp/vscode-terraform/blob/main/README.md#configuration) in case you need to tweak anything. Default settings should work for majority of users though.
### IntelliJ IDE

## BBEdit
- Install [LSP Support plugin](https://plugins.jetbrains.com/plugin/10209-lsp-support)
- Open Settings
- Go to `Languages & Frameworks → Language Server Protocol → Server Definitions`
- Pick `Executable`
- set `Extension` to `tf`
- set `Path` to `terraform-ls`
- set `Args` to `serve`
- Confirm by clicking `Apply`

*BBEdit 14 [added support](https://www.barebones.com/support/bbedit/lsp-notes.html) for the Language Server Protocol so you'll need to upgrade to version 14 to use; this won't work for older versions of BBEdit*.
Please note that the [Terraform plugin](https://plugins.jetbrains.com/plugin/7808-hashicorp-terraform--hcl-language-support)
provides overlapping functionality (and more features at the time of writing).
As a result having both enabled at the same time may result in suboptimal UX,
such as duplicate completion candidates.

### BBEdit

_BBEdit 14 [added support](https://www.barebones.com/support/bbedit/lsp-notes.html) for the Language Server Protocol so you'll need to upgrade to version 14 to use; this won't work for older versions of BBEdit_.

- Open Preferences > Languages
- In *Language-specific settings* section, add an entry for Terraform
- In the Server tab, Set *Command* to `terraform-ls` and *Arguments* to `serve`
- In _Language-specific settings_ section, add an entry for Terraform
- In the Server tab, Set _Command_ to `terraform-ls` and _Arguments_ to `serve`
- Once you've correctly installed `terraform-ls` and configured BBEdit, the status indicator on this settings panel will flip to green
- If you'd like to pass any [settings](./SETTINGS.md) to the server you can do so via the *Arguments* field.
- If you'd like to pass any [settings](./SETTINGS.md) to the server you can do so via the _Arguments_ field.

## Kate
### Kate

KDE [Kate editor](https://kate-editor.org/) supports LSP and is user configurable.

- Install the `terraform-ls` package (or the equivalent package name appropriate to your distro)
- Open Kate configuration (Settings Menu -> `Configure` Kate or Kate -> `Preferences` on macOS)
- Select *LSP Client* in the left pane
- Select *User Server Settings* tab
- Paste the following JSON and *Save*:
- Select _LSP Client_ in the left pane
- Select _User Server Settings_ tab
- Paste the following JSON and _Save_:

```json
{
"servers": {
Expand All @@ -241,4 +251,5 @@ KDE [Kate editor](https://kate-editor.org/) supports LSP and is user configurabl
}
}
```
- Restart of the editor should *not* be necessary.

- Restart of the editor should _not_ be necessary.
10 changes: 10 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ The `jobs` package of each feature contains all the different indexing jobs need
- `ObtainSchema` - obtains provider schemas via `terraform providers schema -json`
- `ParseProviderVersions` is a job complimentary to `ObtainSchema` in that it obtains versions of providers/schemas from Terraform CLI's lock file

### Stack Feature Jobs

- `ParseStackConfiguration` - parses `*.tfstack.hcl` and `*.tfdeploy.hcl` files to turn `[]byte` into `hcl` types (AST)
- `LoadStackMetadata` - uses [`earlydecoder`](https://pkg.go.dev/github.com/hashicorp/terraform-schema@main/stacks/earlydecoder) to do early TF version-agnostic decoding to obtain metadata (variables, outputs etc.) which can be used to do more detailed decoding in hot-path within `hcl-lang` decoder
- `PreloadEmbeddedSchema` – loads provider schemas based on provider requirements from the bundled schemas
- `DecodeReferenceTargets` - uses `hcl-lang` decoder to collect reference targets within `*.tfstack.hcl` and `*.tfdeploy.hcl`
- `DecodeReferenceOrigins` - uses `hcl-lang` decoder to collect reference origins within `*.tfstack.hcl` and `*.tfdeploy.hcl`
- `SchemaStackValidation` - does schema-based validation of module files (`*.tfstack.hcl` and `*.tfdeploy.hcl`) and produces diagnostics associated with any "invalid" parts of code
- `ReferenceValidation` - does validation based on (mis)matched reference origins and targets, to flag up "orphaned" references

### Adding a new feature / "language"

The existing `variables` feature is a good starting point when introducing a new language. Usually you need to roughly follow these steps to get a minimal working example:
Expand Down
Loading

0 comments on commit 53cb152

Please sign in to comment.