Platform-as-Code: how it relates to Infrastructure-as-Code and what it enables
In a previous post we outlined how PaaS systems are evolving towards Platform-as-Code in Kubernetes. In this post we look at how Platform-as-Code systems compare with Infrastructure-as-Code systems.
‘as-Code’ systems are those that provide declarative model for provisioning and managing elements in an application stack. Pioneered by Infrastructure-as-Code systems like Terraform and AWS CloudFormation, the ‘as-Code’ approach provides repeatability, shareability, versioning in managing the corresponding elements.
‘Platform’ systems are those that focus on providing platform-level functionality for application deployments. Pioneered by Heroku, Platform-level functionality is generally understood to include following:
(a) Representation of application and its required dependencies (like databases, load balancer) using high-level abstractions, and
(b) Deployment of application (from source code or pre-built container) with appropriate binding with its dependencies
Then, Platform-as-Code systems can be thought of as systems that support this platform-level functionality in ‘as Code’ manner. This means, such systems enable defining application and its platform dependencies using a high-level declarative representation; and support deployment of the application stack in repeatable manner using this definition.
Kubernetes with its API extension mechanisms (Custom Resources, Custom Controllers, and Operators) has made it possible to build true Platform-as-Code systems that offer creating application platforms in declarative manner bringing advantages of ‘as-Code’ systems to platform functionality.
Comparison of Platform-as-Code and Infrastructure-as-Code
Here we compare notion of Platform-as-Code with modern Infrastructure-as-Code systems like Terraform or Cloud Formation. While IaC and PaC models will complement each other just like IaaS and PaaS models, this comparison will help users understand the unique aspects that PaC system can bring.
- Similarities between Platform-as-Code and Infrastructure-as-Code
1) Declarative representation: Both type of implementations are based on using declarative definitions. This enables these systems to provide repeatability, shareability, versioning in managing corresponding (infrastructure or platform) elements.
2) Diff-based implementation: Both type of systems use ‘diff-based’ implementation to reconcile the current state to new state with the provided inputs.
- Difference between Platform-as-Code and Infrastructure-as-Code
The key difference between PaC and IaC is in regards to how each model implements its abstractions. Infrastructure-as-Code is implemented by writing abstractions as wrappers over APIs of underlying infrastructure layer. Platform-as-Code is implemented by writing abstractions as Kubernetes API extensions instead of writing wrappers over Kubernetes APIs.
This makes the PaC abstractions as first-class entities of the underlying Kubernetes layer. This in turn allows utilizing ‘kubectl’ to work with the abstractions (Custom Resources) rather than using a completely new CLI. In contrast, in Infrastructure-as-Code systems this is not possible. IaC abstractions are written as wrappers over the underlying IaaS layer and consequently, one has to use new CLI when using IaC systems.
Early manifestations of Platform-as-Code experience:
- There are Kubernetes Operators being built for platform elements like databases (MySQL), TLS certificate management, etc. The Operators define Custom Resources for platform elements (e.g.: MySQLCluster, Certificate, Issuer). If you use such Custom Resources in your application YAMLs along with native Kubernetes resources like Deployment, Service, ConfigMap, then you are essentially creating a custom Platform for your application as Code (the YAML files).
- The GitOps model of reconciling a cluster’s state based on artifacts in a Git repository is typically implemented using an Operator that monitors the Git repository for changes and then reconciles the cluster. A Custom Resource is used as the mechanism to trigger the reconciliation. The GitOps model is essentially providing ‘git push to deploy’ workflow, typical of many PaaS systems, using declarative Custom Resources.
- We are building a Kubernetes-based e-learning solution based on Moodle. This system needs to manage life-cycle actions of Moodle instances such as — installing Moodle, installing Moodle plugins, upgrading Moodle. We are creating a Moodle Operator for this. This is a Platform-as-Code system for Moodle application in which the Moodle Custom Resource is used to model the Moodle application and its life-cycle actions. The Moodle controller implements state reconciliation logic based on Moodle Custom Resource inputs.
Future of Platform-as-Code — Challenges and Opportunity
While the concept of Kubernetes Operator allows us to extend Kubernetes with new customer resources, complex application platforms will need multiple such Operators in a Kubernetes cluster. For instance, we will be using 3 Operators for — MySQL, LetsEncrypt and Moodle to deliver a PaC system for one of our clients building an e-learning solution.
In such multi-Operator world, following challenges arise.
1. Discovery of Custom Resources:
When using multiple Operators, it becomes a challenge for application developers to discover the capabilities of the various Custom Resources available in the Cluster — what are all the Custom Resources available? what are their attributes? how to use them? Application developers can go to each Operator’s documentation to find this information, but this is not a user-friendly approach. We need Kubernetes native way to find this information. For standard Kubernetes Objects, there is ‘kubectl explain’. We need something similar for Custom Resources.
2. Custom Resource composability:
Another challenge is how different Custom Resources can work together. For instance, a MySQL Custom Resource and a Backup Custom Resource both may work with Volumes. How to ensure that both these Custom Resources are using the same Volume in their operations? One approach might be to use resource names. Are they always going to work? If not, can we use labels? Currently there are no standards around what functionality an Operator needs to support. We are developing guidelines that can help in this regard.
3. Traceability of Custom Resources:
Kubernetes Custom Resources extend base API to manage third-party platform elements declaratively. It is important to track the various declarative operations performed on Custom Resources to understand how these operations affect underlying platform elements — e.g. for an instance of Postgres Custom Resource we may want to know: how many db users were created, when was password changed for a db user, etc. For this, we need a generic approach to maintain provenance information of Custom Resources.
What will Platform-as-Code enable?
Platform-as-Code model offers an opportunity for bridging the gap between Devs and Ops.

Over the years two types of toolings have evolved. One set, which can be broadly categorized as PaaS, focused on delivering end-to-end developer workflow trying to eliminate the need for Ops engineers. Another set, which can be broadly categorized as Infrastructure-as-Code, focused on simplifying Ops challenges in automation and provisioning. In practice, when teams comprised of developers and Ops engineers come together to build an application deployment workflow, they experience a communication gap due to lack of common tooling. This normally forces developers to learn at least basics of Ops systems and tools to be able to meaningfully contribute in the DevOps workflows. For instance, developers may require understanding of concepts like reverse proxy and how to configure systems like Nginx/Apache to deploy web applications. With Platform-as-Code (Kubernetes + Operators of required Platform elements), there is a possibility to bridge this gap with kubectl & Kubernetes YAML becoming the common language between Devs & Ops.
We anticipate that Ops teams will be involved in selecting Kubernetes Operators for Platform elements such as databases, loadbalancers, loggers, etc. that will be needed by applications. Leveraging their existing Ops knowledge, they will help application developers correctly configure and use Custom Resources corresponding to the various platform elements managed by the corresponding Kubernetes Operators. Application developers on their part will focus on consuming these Custom Resources to build their application platforms and can also add new Operators on top (e.g.: Moodle) as required. This collaboration would leverage Kubernetes YAML as the common language.