TFLint VSCode Extension
A VSCode extension that automatically runs tflint when Terraform files are modified, providing real-time linting feedback directly in the editor.
Features
- Automatic linting of Terraform files (.tf and .tf.json) on save
- Real-time display of linting issues in the Problems panel
- Inline diagnostics in the editor with severity mapping (errors, warnings, information)
- Debounced execution to avoid redundant linting
- Graceful error handling and installation prompts
- Configurable timeout and debounce settings
Requirements
- tflint must be installed and available in your system PATH
- VSCode version 1.75.0 or higher
Installation
From VSCode Marketplace
- Install tflint: Follow the installation instructions
- Install this extension from the VSCode marketplace
- Open a workspace containing Terraform files
- The extension will activate automatically
From .vsix File
- Download the .vsix file from the releases page
- In VSCode, go to Extensions view (Ctrl+Shift+X)
- Click the "..." menu and select "Install from VSIX..."
- Select the downloaded .vsix file
Extension Settings
This extension contributes the following settings:
tflint.enabled: Enable/disable the TFLint extension (default: true)
tflint.tflintPath: Optional custom path to tflint binary (default: "")
- If not specified, tflint must be in your system PATH
tflint.timeout: Timeout in seconds for tflint execution (default: 30, range: 5-300)
tflint.debounceDelay: Debounce delay in milliseconds for file changes (default: 300, range: 0-5000)
Example Configuration
Add to your VSCode settings.json:
{
"tflint.enabled": true,
"tflint.tflintPath": "/usr/local/bin/tflint",
"tflint.timeout": 60,
"tflint.debounceDelay": 500
}
Usage
- Open a workspace containing Terraform files
- Save a .tf or .tf.json file
- The extension will automatically run tflint and display issues in:
- The Problems panel (View → Problems or Ctrl+Shift+M)
- Inline in the editor with squiggly underlines
Development
Setup
# Clone the repository
git clone https://github.com/alishah730/vscode-tflint.git
cd vscode-tflint
# Install dependencies
npm install
Build
# Compile TypeScript
npm run compile
# Watch mode for development
npm run watch
Test
# Run all tests (unit + property-based)
npm test
# Run specific test file
npx jest <test-file-name>
Run Extension
- Open the project in VSCode
- Press F5 to open a new Extension Development Host window
- Open a folder with Terraform files to test the extension
Package Extension
# Install vsce if not already installed
npm install -g @vscode/vsce
# Package the extension
npm run package
# This creates a .vsix file that can be installed manually
Publishing
Automated Publishing with GitHub Actions
This extension uses GitHub Actions to automate the build, test, and publish process. The workflow is defined in .github/workflows/publish.yml.
Required Secrets
Before using the automated workflow, you must configure the following repository secret:
VSCE_PAT (VSCode Extension Personal Access Token)
- Purpose: Authenticates with the VSCode Marketplace to publish the extension
- How to create:
- Go to https://dev.azure.com/
- Sign in with your Microsoft account (same account used for VSCode Marketplace publisher)
- Click on "User settings" (top right) → "Personal access tokens"
- Click "New Token"
- Configure the token:
- Name:
vsce-publish (or any descriptive name)
- Organization: Select "All accessible organizations"
- Expiration: Choose an appropriate duration (90 days, 1 year, or custom)
- Scopes: Select "Marketplace" → Check "Manage" (this includes publish permissions)
- Click "Create" and copy the token immediately (it won't be shown again)
- How to add to repository:
- Go to your GitHub repository
- Navigate to Settings → Secrets and variables → Actions
- Click "New repository secret"
- Name:
VSCE_PAT
- Value: Paste the token you created
- Click "Add secret"
- Security: Never commit this token to your repository or share it publicly
- Expiration: Set a calendar reminder to regenerate the token before it expires
GITHUB_TOKEN (automatically provided)
- Automatically provided by GitHub Actions
- Used to create GitHub releases and upload .vsix artifacts
- No manual setup required
Workflow Triggers
The publishing workflow is triggered automatically when you push a version tag to the repository:
Trigger Pattern: Tags matching v* (e.g., v1.0.0, v2.1.3, v1.0.0-beta.1)
Example workflow:
# 1. Update version in package.json
npm version patch # Increments patch version (1.0.0 → 1.0.1)
# or
npm version minor # Increments minor version (1.0.0 → 1.1.0)
# or
npm version major # Increments major version (1.0.0 → 2.0.0)
# 2. Push the changes and tag to GitHub
git push origin main --tags
# The workflow will automatically start when the tag is pushed
Note: The npm version command automatically creates a git commit and tag. If you prefer manual control:
# Manual version update
# 1. Edit package.json and update the "version" field
# 2. Commit the change
git add package.json
git commit -m "Bump version to 1.2.3"
# 3. Create and push the tag
git tag v1.2.3
git push origin main --tags
Workflow Behavior
When triggered, the workflow executes the following steps in order:
- Checkout code - Clones the repository at the tagged commit
- Setup Node.js - Installs Node.js 18 with npm caching for faster builds
- Install dependencies - Runs
npm ci for clean, reproducible installs
- Compile TypeScript - Runs
npm run compile to build the extension
- Run tests - Runs
npm test (includes unit and property-based tests)
- If tests fail, the workflow stops and publishing is prevented
- Install vsce - Installs the VSCode Extension CLI tool globally
- Package extension - Creates the .vsix file using
vsce package
- Publish to marketplace - Publishes the extension using the
VSCE_PAT secret
- If publishing fails (e.g., invalid token, version conflict), the workflow stops
- Create GitHub Release - Creates a release on GitHub with release notes
- Upload release asset - Attaches the .vsix file to the GitHub release
- Notify on failure - Logs an error message if any step fails
Success criteria: All steps must complete successfully for the extension to be published.
Failure handling: If any step fails, the workflow stops immediately and no publishing occurs. Check the Actions tab in GitHub for detailed error logs.
Manual Publishing
If you need to publish manually (e.g., for testing or if the workflow fails):
# 1. Login to vsce (one-time setup)
npx vsce login <publisher-name>
# You'll be prompted to enter your VSCE_PAT
# 2. Publish the extension
npm run publish
# or
npx vsce publish
# 3. (Optional) Create a GitHub release manually
# Go to GitHub → Releases → Draft a new release
# Upload the .vsix file from the project root
Manual release process:
- Ensure all tests pass:
npm test
- Build the extension:
npm run compile
- Package the extension:
npx vsce package
- Publish to marketplace:
npx vsce publish -p <your-pat>
- Create GitHub release with the .vsix file attached
Workflow Configuration Details
The workflow file (.github/workflows/publish.yml) includes:
- Runner:
ubuntu-latest (Linux environment)
- Node.js version: 18 (LTS)
- Trigger: Push to tags matching
v* pattern
- Secrets used:
VSCE_PAT (required), GITHUB_TOKEN (automatic)
- Artifacts: .vsix file attached to GitHub release
- Error handling: Workflow fails if any step fails, preventing partial publishes
Troubleshooting Publishing
Tests fail
- Run
npm test locally to identify failing tests
- Fix the tests before pushing the tag
- Delete the tag if already pushed:
git tag -d v1.0.0 && git push origin :refs/tags/v1.0.0
VSCE_PAT invalid or expired
- Error message: "Failed to publish: Unauthorized" or "401 Unauthorized"
- Solution: Regenerate the PAT in Azure DevOps and update the GitHub secret
- Verify the PAT has "Marketplace (Manage)" scope
Version conflict
- Error message: "Extension version X.Y.Z is already published"
- Solution: Increment the version in package.json and create a new tag
- Each published version must be unique and cannot be overwritten
Build errors
- Error message: TypeScript compilation errors or missing dependencies
- Solution: Run
npm run compile locally to identify issues
- Ensure all dependencies are listed in package.json
Package not found
- Error message: "ENOENT: no such file or directory, open './tflint-vscode-X.Y.Z.vsix'"
- Solution: Check that
vsce package step completed successfully
- Verify the version in package.json matches the tag version
GitHub release creation fails
- Error message: "Resource not accessible by integration"
- Solution: Ensure the repository has Actions enabled with write permissions
- Go to Settings → Actions → General → Workflow permissions → Select "Read and write permissions"
Architecture
The extension follows a modular architecture:
- Extension Entry Point (
extension.ts): Manages lifecycle and initialization
- TFLint Verifier (
tflintVerifier.ts): Checks tflint installation
- TFLint Executor (
tflintExecutor.ts): Executes tflint commands
- Output Parser (
outputParser.ts): Parses tflint JSON output
- Diagnostic Mapper (
diagnosticMapper.ts): Converts issues to VSCode diagnostics
- Diagnostic Manager (
diagnosticManager.ts): Manages diagnostic collection
- Linter Controller (
linterController.ts): Orchestrates the linting workflow
- File Watcher (
fileWatcher.ts): Monitors Terraform file changes
- Notification Service (
notificationService.ts): Displays user notifications
- Configuration Handler (
configurationHandler.ts): Manages extension settings
Testing
The extension uses a dual testing approach:
- Unit Tests: Verify specific scenarios and edge cases
- Property-Based Tests: Verify universal properties across randomized inputs using fast-check
All tests are run automatically in the CI/CD pipeline before publishing.
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Ensure all tests pass (
npm test)
- Submit a pull request
License
MIT
Support