Shipa Blog

Latest updates on our products, plus helpful articles relating to Kubernetes, container security, microservices and more

How deep is your love for YAML?

There is no doubt that YAML has developed a reputation for being a painful way to define and deploy applications on Kubernetes. The combination of semantics and empty spaces can drive some developers crazy. 

As Kubernetes advances, is it time for us to explore different options that can support both DevOps and Developers in deploying and managing applications on Kubernetes?

Common YAML Challenges

It is not hard to pinpoint one of the challenges people complain about the most when using YAML to define their applications: blank space.

It may sound like a simple challenge, but blank space is a real pain. Missing a couple of spaces can drastically change the definition of the resource you are deploying or updating while still being a valid YAML definition. 

As you grow your number of YAML-defined services, taking YAML lines from a few dozen to hundreds or thousands of lines, the challenge will continue to increase, and trust me when I say that you won’t feel any love from your developers!

Another complexity you can add to that is the way you can use YAML to cross-reference structures. While it can be handy, someone with malicious intent can exploit this structure and expand small data sets into something much more significant and affect your infrastructure and applications.

Here comes Kubernetes

If you are implementing Kubernetes and scaling it in your company, I’m sure you heard developers say that Kubernetes’ resources are complex. Kubernetes exposes a lot of infrastructure-related options, so defining and managing applications can become a daunting task.

While having the capability to define Kubernetes objects using YAML is powerful, as mentioned above, using the kubectly apply command with the wrong definition can disrupt your applications and infrastructure.

All these challenges make your development process longer, developer productivity goes down, and risks increase.

A different option

Pulumi: Modern infrastructure as code for developers, a.k.a the new kid on the block (at least here at Shipa).

Pulumi targets the widespread infrastructure as code (IaC) space but using a different approach. It allows developers to define infrastructure using their language of choice, such as TypeScript, JavaScript, Python, and others, instead of a proprietary language, such as HCL, from our friends at HashiCorp.

It is an exciting approach that can benefit teams when scaling the management and evolution of infrastructure since it’s easier to find folks in your group who can help write, manage, and extend the infrastructure as code definitions using existing languages.

Pulumi and Kubernetes

While Pulumi is an excellent option to define and manage infrastructure, when it comes to application deployment, management, and policies in Kubernetes, Pulumi is still tied to the underlying Kubernetes infrastructure-focused definitions.

You can deploy resources in Kubernetes through Pulumi using JavaScript or Python, and you are still pretty much repeating the same complexities presented by YAML, just in a different language, and maybe with a better situation around the spaces.

That scenario got us thinking about bringing Pulumi and Shipa together, giving developers a way to not only use their preferred language to deploy, manage, and secure applications in Kubernetes but do it using a much simpler and infrastructure-agnostic definition.

We decided then to put together an initial Shipa provider for Pulumi, which you can find detailed information about here: Pulumi (

Deploying a sample application

We have put together a sample WordPress application. The picture below shows the architecture we used when deploying this application.

You can find the code used here: brunoa19/wordpress-shipa-pulumi (

Here is what we are doing through this code:

  • We are deploying two applications, a MySQL database, and a WordPress image. Both are using the officially available Docker container images.
  • Defining a network policy for the MySQL database application, so only the WordPress application can communicate with it.

Let’s have a quick look at some of the sections of the code.

Here we are importing Shipa so we can use JavaScript to define our application as code.

The next part of our code creates the application and binds it to an existing policy framework called dev. It also defines shipa-team as the owner of the application:

You can find more information about Shipa’s policy frameworks here: Framework Management (

Here we are defining the environment variables required to have our MySQL application running. I’m defining clear variables here as an example, but you can replace those with GitHub secrets, Vault, and whichever method you use to store and load secrets:

With the application bound to a policy framework and the environment variables needed set, we can then proceed to deploy our application:

With the application deployed, we then took the step further to define and enforce an application-level network policy, so ingress and egress data can only happen with the WordPress app:

The next section of the code performs the same steps as the one above but for the WordPress application.

While defining application as code is powerful, it’s crucial to have an application platform bound to the approach, so developers, DevOps, and SREs can manage the application post-deployment:

From here, teams can have complete control and visibility over their applications, no matter if they are familiar with Kubernetes. Shipa exposes application-level management controls, making it easy for teams to manage, support, and audit applications.

Further to having complete visibility over the application status, dependency, and security, developers can integrate the application with their existing incident management stacks, such as PagerDuty and others.

All in all, we were able to deploy a complete WordPress application and define network policies for our MySQL application without dealing with the underlying Kubernetes infrastructure and YAML complexities. All done using simple JavaScript to define our application as code.

What’s Next?

We continue to extend Shipa and supporting multiple control planes and infrastructure as code solutions, helping you implement a standard application definition that any tool can use to deploy, manage, and secure applications across various infrastructures.

We would love to hear your feedback on this, as this will help us continue building Shipa as the leader in the Application as Code category.