As you may have guessed, the engineering team at Garden relies on Garden to support our own developer workflows. And with the Garden community growing and many new users in the process of figuring out how to apply Garden to their own use cases, we thought it was time to share our experience as everyday Garden users.
First, a little bit about us. Team Garden is currently made up of six developers, all of whom are working remotely (as are most dev teams around the world right now). We divide our time between two products: the open source Garden Core and Garden Enterprise.
Our stack consists of three core services plus supporting services such as Postgres, Vault, and Jaeger. We work on both GCP and AWS so that we gain some hands-on experience with two different cloud offerings that are popular amongst our user base. All of our infrastructure is provisioned with Terraform, and we use kaniko for in-cluster builds.
What we're working with at Garden.
A few other details about our setup
We use Garden in CI to run tests and to deploy to staging. From a DevOps perspective, one of the major advantages of Garden is that it codifies the entire stack and makes it easily portable across different contexts. The same test and deploy commands we run in CI can be run from a developer’s own machine and when switching across branches, which makes debugging a lot easier for us.
We don’t ever want to go back to debugging by pushing code to GitHub and waiting for a CI pipeline—it’s simply a much less efficient way to develop.
Each developer has their own namespace and unique hostnames. As a DevOps engineer working with Garden, you can easily set up all necessary services and give developer on the team their own instance. For example, we just added Jaeger as our tracing backend, and as soon as any of our developers pulls from the latest main branch and runs garden deploy, they’ll have their own instance of Jaeger. Whenever we add something new to our stack, we can make sure it’s available for our developers right away.
This namespace approach also makes it easy for us to share our work and check out what others are doing. A dev can share a link to the state of their project at any point in time so that a teammate can interact with it and see what’s going on—and automating this process is a core feature of Garden Enterprise.
We write a lot of integration tests. Developers have all the services they need running in their own namespace, which enables them to write, run, and debug integration tests across service boundaries with minimal effort. Again, being able to run and debug tests without going through the CI pipeline is really powerful.
Garden has empowered us to write integration tests without having to think of all the dependencies involved and in general has changed the way we write tests for the better. As a developer, it’s so nice to know that all of the services that need to be up and running for an integration test are available to you in your namespace. And you can run these tests right in the same namespace that you use for development.
Using Garden has changed the way we do integration testing for the better
Garden for back-end engineers
Next, let’s get into what the day-to-day developer experience is like when using Garden, first from the perspective of a back-end engineer working on a cloud native application.
We can think about this in terms of what a back-end engineer needs to be productive and how Garden provides those things.
Number 1: You need to hide complexity unless you want to deep-dive into something in your stack. As a developer, you want to just wake up in the morning, open up your laptop, and start writing code.
And when you join a new team or company, you just want to check out a branch without having to worry about which database you need to connect to, what else you have to run besides the service you’re working on, what your service depends on, how to build it, how to test it, and so on. Cloud native applications come with a huge amount of context that you have to load and keep in your head and document, and especially if you’re a new hire, this can be really difficult.
Garden codifies your entire stack, so as a dev, you can check out a branch and run garden deploy, and you’re ready to go. This getting started process is incredibly easy with Garden.
Number 2: You need to develop and run code in an isolated environment that’s as close as possible to a production cluster. The idea of “it works on my machine” doesn’t really apply to cloud native development, and so the Garden team has moved fully to in-cluster development. Each dev has their own namespace in the cluster and deploys the full stack there, including database instrumentation and everything else that’s needed.
That means we don’t have to do things like double-check whether we’re developing against a the incorrect version of a dependency. And the environment is always reproducible in case you want to check how something works on a different branch.
Collaboration is easier, because you have access to your coworkers’ namespaces. And simply running on a cluster is important to ensure the application behaves the same way for you as it will behave for end users. Sure, there are always going to be differences between the dev and production clusters, but there’ll be fewer differences than between your laptop and the production cluster. And when developing locally, you’ll inevitably waste a lot of time trying to match your local configuration to a remote environment.
Number 3: You need a fast feedback loop while developing. We use hot reload quite a bit, and it’s a really nice way to try out new ideas and see the changes quickly, without rebuilding containers or redeploying. With no extra steps, you just get to see the changes up and running, as fast as possible.
Number 4: You need to run integration tests easily and early. That’s right. We want to talk about integration testing again. This really is one of the coolest things about using Garden.
Normally, you need the entire stack deployed somewhere to be able to run integration tests, and that’s why integration tests are often run in CI—it’s the only place you have this shared staging or testing environment, and so that’s what you use to run your tests. But with Garden, you’re developing against a running cluster, so you can run tests directly in your namespace.
In some scenarios, we set up our tests in a way that we can shell inside the module where the tests are defined and run them from there. This is possible because our integration tests are set up in a way that we use the same database in our dev cluster for testing and running the application. Each test suite creates its own temporary schema, populates it with data, and cleans itself up afterward.
We found this to be less expensive than setting up and managing an integration database instance to be spun up and torn down only when needed for testing.
Garden for front-end engineers
Front-end engineers can use Garden as much or as little as they need to. There are a few capabilities that are particularly useful, and in a lot of ways similar to the benefits that back-end engineers get from Garden.
With Garden, frontend developers can easily deploy any version of the backend while still running their frontend locally and using the tools they’re most familiar with.
Garden’s production-like preview environments allow for manual testing of features and for sharing the current state of your work for QA or code reviews, or even just for getting quick feedback throughout the development process—imagine a case where you’re implementing new designs and want to run something by the designer before you push it.
Having an entire stack running in Garden makes it possible to write end-to-end tests easily. We currently have a front-end test suite running with Cypress that we find really helpful.