Development

Pulumi or Terraform for applications? Maybe, both?

TL;DR

Cloud-native is an evolving architecture. Existing vendors will keep on evolving their offerings and different teams inside your organization should be able to use the tool that will support them better in delivering their desired outcome fast.

By implementing a standard application layer, you enable teams to adopt what works best for them while the DevOps team can focus on adopting the infrastructure components they believe to be best to support their organization.

The IaC Market

The infrastructure-as-code space (IaC) market size was valued at $38.9 billion in 2019 and is projected to reach $201.83 billion by 2027. Impressive, right?

In short, IaC solves real challenges and is a key piece of every team’s strategy around automation. It allows teams to create a declarative and repeatable model where the desired state of your objects can be declared and stored in Git.

Over the last few years, we saw different products tackling this problem, and if you are in the DevOps space, the chances are high that you have worked with or at least heard about, Terraform.

Terraform is probably one of the most used IaC tools today, but we expect to see other players entering the market with such a growing market opportunity. One of the recent ones is Pulumi.

Pulumi or Terraform?

Although conceptually, Pulumi and Terraform may have similarities, they are different in declaring the desired state of your infrastructure.

Terraform requires the user to use a domain-specific language, HCL, or HashiCorp Configuration Language. In contrast, Pulumi allows you to use familiar programming languages, such as Python, JavaScript, etc.

One of the common questions I see users asking these days is: Should we move to Pulumi or continue using Terraform?

One of the drivers for this question is the migration of applications to cloud-native infrastructures, such as Kubernetes. As teams move more applications, and their application owners/developers, to Kubernetes, it opens up the opportunity for different teams to experiment with different tools. As a result, this question comes up.

The answer? Why not both?

If you are part of a mid to large organization, you will see different teams request different tools. That is a very common scenario, and teams want to use the tools they believe will enable them to deliver the desired outcome better and faster. In this case, their application deployments.

The challenge is that different tools may introduce pipeline and automation complexity because of their differences, and as you onboard more teams and applications, differences in how applications are deployed, managed, and secured at scale, can become a mess.

Defining Common Ground

The reality is that your infrastructure will continue to evolve and to deliver applications fast, different teams will use different tools. So, how can you allow this to happen without creating a pipeline nightmare?

By exposing a standard application definition that both Pulumi and Terraform (and other IaC tools) can use to deploy, manage, and secure cloud-native applications.

By connecting the different IaC and pipeline tools you have to a standard application API that exposes application-level constructs, you can enable developers to create, manage, and onboard their applications while reducing the burden on the DevOps team.

That approach detaches the application definition from the underlying infrastructure, so DevOps teams can choose which cluster provider they want to use, version, ingress controllers, and others without impacting how applications are deployed, managed, and secured.

Sample Application

Here is a quick example of implementing that approach. For this, you will need:

Assuming you connected your cluster to Shipa Cloud, let’s deploy a sample application called Bulletin Board.

The Terraform code below will have the application deployed:

terraform {
  required_providers {
    shipa = {
      version = "0.0.8"
      source = "shipa-corp/shipa"
    }
  }
}
provider "shipa" {
  host = "https://target.shipa.cloud:443"
  token = "<your-shipa-token>"
}
resource "shipa_app" "app1" {
  app {
    name = "terraform-app"
    teamowner = "dev"
    framework = "dev-framework"
  }
}
resource "shipa_app_deploy" "deploy1" {
  app = "terraform-app"
  deploy {
    image = "docker.io/shipasoftware/bulletinboard:1.0"
  }
}

That’s it! Notice that in the example above, the developer is not involved in the underlying infrastructure complexity or choices made by the DevOps team. Instead, they only define application-centric details.

Now, if a different team wants to use Pulumi instead to manage their application lifecycle, this is what they would use:

import * as pulumi from "@pulumi/pulumi";
import * as shipa from "@shipa-corp/pulumi";


const app = new shipa.App("app", {
    app: {
        name: "pulumi-app-1",
        framework: "policy-fw-name",
        teamowner: "shipa-team"
    }
});

export const appName = app.app.name;

const appDeploy = new shipa.AppDeploy("app-deploy", {
    app: "pulumi-app-1",
    deploy: {
        image: "docker.io/shipasoftware/bulletinboard:1.0"
    }
});

export const appName = appDeploy.app;

Like the previous Terraform example, this definition is very application-focused. Aside from the IaC tool boilerplate required for the tool to “read” the definition, the way developers define their applications is the same.

The Benefits

Standardizing the application pipeline is a tremendous benefit, especially in a large organization with many teams and applications deployed frequently.

But the benefits certainly don’t stop there. 

In addition to standardizing application definition, Shipa’s application API enables you to define application policies. Defining policies are also application-centric and detached from the underlying infrastructure, so you don’t have to worry about defining policies for a 1.20 cluster vs. a 1.22 or Istio vs. NGINX.

Another benefit is that as developers move to different teams in the organization or new developers are onboarded, regardless of their level of experience with Kubernetes or the IaC tools used by their new team, they can quickly understand this application definition and start contributing.

Conclusion

Cloud-native is an evolving architecture. Existing vendors will keep evolving their offerings, and different teams inside your organization should be able to use the tool that will support them better in delivering their desired outcome fast.

By implementing a standard application layer, you enable teams to adopt what works best for them while the DevOps team can focus on adopting the infrastructure components they believe to be best to support their organization.

Resources