How Terraform and Jenkins Transform the Way We Work
Today, the vast majority of software products live in the cloud. It is increasingly rare to find an application running on a physical server inside an office. Instead, applications are typically supported by remote infrastructure, as for most companies it is far more cost-effective to rent computing capacity than to maintain their own servers.
But using cloud services does not simply mean accessing a space where code can be hosted and run. Providers such as Microsoft (Azure) and Amazon (AWS) offer an entire catalogue of ready-to-use components: databases, messaging systems, storage, networks and many other services. Development teams can select and configure the ones that best fit each project, taking advantage of resources that have already been built, tested and maintained by the provider rather than creating them from scratch.
At WeGen, we experience this first-hand. Our products rely on a range of cloud services that support their operation, and all these services need to evolve and adapt at the same pace as we introduce new functionality. It was precisely this need for software development and infrastructure to evolve in parallel that led us to encounter our first challenges.
The first challenge: infrastructure that diverges without warning
When each piece of infrastructure is created and configured manually, environments may start out identical but gradually diverge over time. This happened to us frequently: any member of the team could apply a small fix directly to an environment which, although it solved the immediate problem, was neither tested nor recorded anywhere.
Each manual change therefore became a silent risk, often forgotten until something unexpected failed in production.
The second challenge: code that never reaches production
Every day, the team integrates new changes and tests them in internal environments. As the project grows, so does the number of versions running in parallel. The larger it becomes, the harder it is to keep track of which version is deployed in each environment.
As a result, some changes that have been successfully tested in one environment may never reach production, simply because no one realised they had not yet been deployed.
These two challenges point to two different but complementary solutions: Terraform and Jenkins.
Terraform: infrastructure as code
Terraform makes it possible to describe the entire infrastructure as code. It defines which resources should exist and how they should be configured, and then creates, modifies or removes them so that the actual state of the cloud always matches what has been defined in the repository.
Infrastructure stops being a collection of scattered manual decisions and becomes something version-controlled, reviewable and reproducible, where nothing exists without leaving a trace.
In our case, Terraform allows us to provision and maintain all the cloud services our products rely on. Each one is described in code, with its configuration explicitly defined, so adding a new service is as straightforward as adding its definition block and applying it.
It requires a little more time upfront and a certain level of discipline to maintain, but the project gains consistency: every environment can be rebuilt in the same way, changes are documented and nothing exists “outside” the defined infrastructure.
Jenkins: deployment that runs itself
Jenkins is a continuous integration and continuous deployment (CI/CD) orchestration tool that allows us to define a pipeline: a sequence of automated steps that always runs in the same way, regardless of who initiates it.
Instead of each person deploying changes in their own way, we define the steps required to build, test and deploy code changes once, and Jenkins takes care of executing them in any environment.
The process always follows the same sequence: it retrieves the code from the repository and builds each service, creates a container image for each one and publishes it to the corresponding registry, and finally redeploys those services to the cluster where the product actually runs.
Deployment no longer depends on each person’s memory or habits. Instead, it becomes a reproducible process that everyone can use and that is continuously reviewed and improved. At any given time, we know which version is deployed, who deployed it and what the outcome was.
The combination that changes everything
The real step forward comes from combining both technologies. By incorporating the infrastructure defined in Terraform into the Jenkins pipeline itself, we can manage through code operations that would otherwise be manual and costly: modifying a database more safely, adding or adjusting API routes more efficiently, or creating and maintaining infrastructure with the same traceability we already apply to application code.
The difference is significant. We spend less time putting out fires and more time building products.
What we have learned
After implementing these tools, there are three key lessons we would highlight:
1) Initial discipline is everything. Defining infrastructure as code requires a real investment of effort at the beginning, and the temptation to make a quick change “by hand” is always there. But every exception creates technical debt that will need to be paid later, usually at the worst possible time.
2) Visibility changes everything. Knowing at all times what is deployed, who changed it and why is not simply a matter of convenience. It helps us detect problems before they reach production and makes onboarding new team members much easier.
3) The pipeline is a product in its own right. It is not enough to define it once and forget about it. It needs to be maintained, improved and reviewed just like application code. When the team treats it this way, the return is significant.