How Gympass’ New Hires Deploy on Their First Day: an Automation Story

Victor "Vito" Gama
Wellhub Tech Team (formerly Gympass)
6 min readSep 27, 2021

--

One may ask developers around the globe how it was to board a new company, and most of them will probably tell how long it took to get used to codebases, which is a somewhat natural process, but there’s a detail that must not go unmentioned: How they get used to specifics of a new company regarding infrastructure? Well, whilst being reductive to a fault, everything may boil down to Kubernetes, but what happens between a commit, and code being actually run by a production server?

Here at Gympass, we have a team specialized in solving this kind of problem. In this article I will be showing the tooling that allows new-hires to deploy code during their onboarding. You read it right, dear reader: They are able to create a brand new project, change it, commit, and deploy during an operation that takes less than 5 minutes. Got your attention? Great, so let’s get to it.

Creating a new Project

For common daily activities that range from a myriad of operations, our engineers have a CLI called “Josie”; The name is a reference to a character in the old TV series “Beakman’s World”, as Josie was one of Beakman’s assistants. Once authenticated through SSO, using their Google account, one may execute any command they have access to.

Creating a project can be summarised to a single command:

josie new Gympass/go-api-template.g8 dear-reader

So we’re invoking the new command from josie, our CLI, and asking it to use a template to render a new project called dear-reader.

So far so good, but how about that second argument? Glad you asked!

The second argument points to a Giter8 template, which is a special format for templating used by the Scala folks in their SBT tool. That template has a number of arguments that are then replaced within files contained in the template repository. Indeed a super clever and useful tool.

But there’s a catch: our CLI is not written in Scala, but Golang (as we want to provide a single binary for our engineers). One option would be changing our templates to use Go’s templating functions, but that would be a waste of all effort folks had on writing those templates, not to mention the amount of work we would have to port all 15+ templates already present in Gympass’ GitHub organisation (we have templates for Scala, JavaScript, Kotlin, Go, Ruby, and pretty much any other language used here). To solve this problem, a Giter8 template parser for Golang was developed and integrated into Josie. Presto! Templating without runtime dependencies for all engineers.

Then, Josie asks the user for some details about their new project, which includes, for instance, a description, on which cluster they want to host their new application, and so and so.

Josie’s “new” command asking user for input required to create a new project

Josie will then execute a few operations that include (but are not limited to) creating new repositories, rendering the template into the brand-new repo, creating Helm charts for deployment, configuring security options such as CODEOWNERS and other interesting defaults to keep members of our SecOps team happy. 😬

After the CLI completes its job, the user will have a clone of the new repository already present on their machine, so they can start hacking away. But that’s not all. Once Josie pushes the first commit to the repository, which is by itself a complete application, with all dependencies and boilerplates in place, this already triggers our CI pipelines. So let’s dig into that before coming back to change the application’s code.

The CI Pipeline

Writing software without testing is no fun (nor safe), so that’s a required step for every project here. The CI is responsible for executing all tests within the application, pushing coverage information to a third-party service, and finally building and pushing an updated image to our container registry. While I write this article, we have an ongoing effort to replace our Jenkins pipelines with GitHub Actions, so let’s focus on the new pipeline.

Gympass hosts its own Actions runners, which keeps us in check with compliance and security, since all sensitive operations take place in our cluster. This change makes even more sense to our engineers, since the majority already had some experience with Actions, and having CI and Code in the same place makes checking the pipeline progress and responding to any failed build a seamless experience — as you may have noticed, DX (or Developer Experience) is a big deal for us.

Once tests are green, a custom internal Action is responsible for building container images for both Staging and Production environments, pushing them to our container registry, and bumping Helm charts. This change is then picked up by Argo CD, which leads us to the last step in our application development lifecycle: CD, or Continuous Deployment.

Drop it Like it’s Hot: Deploying Applications to our Servers

Gympass makes extensive use of Kubernetes, Kubernetes Operators, and other shiny things (that will be mentioned in depth by a future post). To keep everything working and to automate our operation, Argo CD was chosen to do the heavy lifting.

So, rewinding a bit, our CI pipeline created and pushed new container images, and made two important steps towards pushing the new code into our cluster:

  • First, the Staging environment of our application was automatically updated to use the new version generated during our CI pipeline. This means that charts for the Staging environment were automatically updated, a new Pull Request was opened with those changes, and also automatically merged by the CI. We do this to keep tabs on automated changes.
  • Then, the Production environment was also automatically updated, and a PR was opened. But this one has not been automatically merged, as we require a true Human™ to acknowledge the change and deployment by approving and merging the PR.

Those changes are then picked up by Argo CD, which automagically updates the application deployment, and makes all required changes, which for instance, invokes controllers that prepare a new DNS entry for the application, making it instantly available for access.

This means that a single command, and a few inputs later, any engineer here is able to have a fully working application available in a real endpoint. No need to provision charts manually, no chance of forgetting a specific detail and having to diagnose a weird problem caused by a typo. Pure magic.

Working on the New Application

All the steps I mentioned up to this point were automatic. No human intervention, no fiddling with large YAML files. Now we get to the part everyone was waiting for: writing some code.

Since our fictitious (or may I say virtual?) engineer have their application all set-up and ready, they are able to focus on the problem at hand, and start hacking on the new application. This means that code gets written, tests are implemented, and once they are done, they are able to create a new Pull Request, have their code reviewed by their peers, and once everything looks good, merged into the upstream branch of their project, which will then trigger our CI/CD pipelines. Now it’s just a matter of rinse and repeat.

Epilogue

As here at Gympass we have an ever-growing number of engineers with diverse backgrounds, providing an environment that helps them focus on what they do best is extremely important for us. Abstracting repetitive tasks, or tasks involving steps they are not used to do in their daily activities, allows us to streamline our software engineering pipelines, which leads to fast, robust, and safe releases of new features to our customers with a great quality.

--

--