Building a Terraform Provider for Kasm Workspaces with AI Assistance
Introduction
As a DevOps engineer with years of experience but no prior knowledge of Go, I set myself an ambitious challenge: to create a Terraform provider for Kasm Workspaces (Kasm is a platform that lets users access virtual desktops and applications of many flavours through a web browser). This wasn't just about building a tool, it was a test of how far AI could assist in creating complex infrastructure code. Kasm, while powerful, presented unique challenges with its intricate UI and undocumented API behaviours. This is a bit about how I navigated these challenges, the lessons I learned, and the end result.
The Challenge
Kasm Workspaces is a robust platform for containerized desktop environments, but its API documentation is limited, as they state in their documentation, not all APIs are present in their Developer API Docs. Many UI interactions also aren't documented, making it difficult to automate workflows. My goal was to create a Terraform provider that could manage Kasm resources effectively, despite these hurdles. This project became a personal experiment in leveraging AI to bridge the gap between my DevOps expertise and the unfamiliar territory of Go development.
Using AI
Effective Prompting Strategies
One of the most crucial skills I developed during this project was learning how to effectively communicate with AI tools, in this case Claude. Initially, my prompts were too vague, resulting in code that wouldn't compile or missed important Terraform provider patterns, or it would unexpectedly rewrite code that was working previously.
For example, instead of asking “How do I create a Terraform provider?”, I learned to be specific:
"I want to create a terraform provider for kasm, in the docs directory i have provided a markdown version of the Kasm Developer API documentation. Look through that and analyse what should be a starting point. Kasm has a lot of UI interactions so remember to ask if you do not understand something"
This level of detail provided much more useful code that I could immediately apply.
Handling AI Hallucinations
Working with AI meant occasionally dealing with “hallucinations” — confidently presented but incorrect information. This was particularly challenging when working with Kasm's undocumented API features.
To combat this, I developed a verification workflow:
- Generate the initial code with AI assistance.
- Test against actual API responses.
- Document discrepancies.
- Export browser interactions as .har files and provide them to Claude.
- Explain in words what I did in those .har files.
- Feed those corrections back to AI for refinement.
This iterative approach helped create accurate implementations while still benefiting from AI's ability to generate boilerplate code and suggest structured approaches.
Without this approach, it would start changing cast_sessions code instead of kasm_session code etc. It would divert off track to something similar but not related.
The Journey
1. Learning Go on the Fly
With no prior Go experience, I relied heavily on AI to guide me through the language's intricacies. From understanding Go's syntax to structuring the provider's codebase, AI was my co-pilot. For example, generating boilerplate code for the provider's structure was made significantly easier with AI assistance:
package main
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func Provider() *schema.Provider {
return &schema.Provider{
ResourcesMap: map[string]*schema.Resource{
"kasm_workspace": resourceWorkspace(),
},
}
}
What would have taken weeks to learn through traditional methods, I was able to grasp in days through targeted AI-assisted learning. The key was focusing on the specific patterns needed for Terraform providers rather than trying to master all of Go at once.
2. Reverse Engineering the API
One of the most difficult challenges was reverse-engineering Kasm's API. Many endpoints had to be mapped by observing UI interactions and analysing network requests. For example, creating a session in Kasm involved undocumented API calls that I had to piece together, AI would try to be “smart” and do something that either did not exist or work.
resource "kasm_session" "example" {
workspace_id = kasm_workspace.example.id
user_id = kasm_user.example.id
# Additional configuration derived from UI observations
}
I used browser developer tools to monitor network requests while performing actions in the Kasm UI. This revealed the exact API calls, required parameters, and authentication mechanisms that weren't covered in the official documentation.
3. Managing a Growing Codebase
As the provider expanded to support more features, managing the codebase became increasingly complex. Being new to Go, I needed to establish practices to maintain quality as the project grew.
Some strategies that helped:
- Creating clear separation between API client code and Terraform resource implementations
- Implementing thorough error handling early
- Developing a consistent pattern for resource methods (Create, Read, Update, Delete)
- Using Go interfaces to standardize interactions with different Kasm resources.
- Having a file in the code base that would be updated when code was added, which endpoint it was for and where code lived. Then, by stating in the prompt to always look and update that file after each feature was added, it helped keep track of everything.
4. Building a Comprehensive Testing Framework
To test the provider, I created a GitHub Actions workflow that spins up Kasm Workspaces in a containerized environment. This allowed me to automate testing and ensure the provider worked as expected. At first when the repo was private, I used a self-hosted GitHub runner. This allowed me to run the test against a new, clean version of Kasm every time.
When the time came to making the repo public, there was a lot of tweaking done to get the same actions working on the public runners.
Manual Testing Approach
While automation was crucial, manual testing remained an essential part of the development process. Each new feature required careful verification, since Kasm's API behaviours didn't always match expectations.
My manual testing workflow included:
- Running the provider in debug mode to trace API interactions
- Comparing the provider's behaviour with direct API calls via curl
- Testing edge cases that were difficult to automate
- Verifying resource state management when faced with unexpected API responses
Guiding Users to Set Up Testing
For contributors and users wanting to test their implementations, I developed a standardized testing approach. This included:
- A containerized Kasm environment for consistent testing
- Example configurations for common scenarios
- Step-by-step verification procedures
- Documentation of known API endpoints that are integrated.
Key Features
The Terraform provider for Kasm Workspaces includes several powerful features:
- Resource Management: Manage workspaces, sessions, users, and more through Terraform.
- Automated Testing: A GitHub Actions workflow for continuous integration and testing.
- Documentation: Detailed docs and examples to help users get started.
- Error Handling: Robust error handling for Kasm's occasionally inconsistent API responses.
- State Management: Proper tracking of resource states to support Terraform's refresh and import workflows.
What did I learn?
1. AI as a Collaborator
AI was instrumental in bridging the gap between my DevOps expertise and Go's learning curve. From generating code snippets to debugging errors, AI acted as a real-time mentor. However, the relationship was most productive when I approached AI as a collaborative tool rather than expecting it to solve everything.
The most valuable AI interactions came from:
- Asking for explanations of generated code to deepen understanding
- Using AI to explore alternative implementations
- Learning Go idioms and best practices contextually
- Getting help debugging complex issues with clear error context
2. Persistence Pays Off
Reverse-engineering undocumented APIs was challenging but rewarding. It required patience, creativity, and a willingness to dive deep into the platform's behaviour. Many features took multiple iterations to implement correctly, especially where the API behaviour was inconsistent.
3. Community is Key
Releasing the provider publicly will lead to valuable feedback and contributions. This is the part I am excited about the most, getting the community that uses Kasm at scale to test out the current version of the provider.
Future Plans
- Expand Support: Add support for more Kasm features, such as advanced session configurations and user permissions.
- Improve Documentation: Add more examples and tutorials to help users get started.
- Enhance Testing: Expand the testing framework to cover more edge cases and scenarios.
- Performance Optimization: Refine the provider's performance, particularly for large Kasm deployments.
- Integration with Terraform Cloud: Ensure smooth operation with Terraform Cloud workflows.
- Enhance Security: Review and address potential vulnerabilities or security concerns in the codebase.
What now?
Give it a try, don't expect miracles as it needs a lot
Conclusion
Building a Terraform provider for Kasm Workspaces was a challenging yet fulfilling journey. It showcased the power of AI in software development and highlighted the importance of perseverance in tackling complex problems. While AI significantly accelerated the development process, human expertise in DevOps principles and systematic testing remained essential.
I hope this provider proves useful to the community and inspires others to take on similar challenges. Most importantly, I hope my experience demonstrates that with the right approach, it's possible to create professional-grade infrastructure as code tools even when venturing into unfamiliar programming languages.
I do intend to write more about the intricacies of how I used AI to build this, but that will be for another day.