Contact Information

7154 N University Dr #95,
Tamarac, FL 33321, USA

We Are Available 24/ 7. Email Us.

Constructs are the fundamental building block of cdk8s (Cloud Development Kit for Kubernetes) – an open-source framework (part of CNCF) with which you can define your Kubernetes applications using regular programming languages (instead of yaml). In Getting started with cdk8s, you saw how to use the core cdk8s library.

You can also use the cdk8s-plus library (also covered this in a previous blog) to reduce the amount of boilerplate code you need to write. With cdk8s-plus, creating a Kubernetes Deployment, specifying its container (and other properties) and exposing it via a Service is three function calls away?

For example, to set up and access Nginx, you simply need this:

deployment := cdk8splus22.NewDeployment(chart, jsii.String("deployment"), &cdk8splus22.DeploymentProps{Metadata: &cdk8s.ApiObjectMetadata{Name: jsii.String("nginx-deployment-cdk8s-plus")}})

        Name:  jsii.String("nginx-container"),
        Image: jsii.String("nginx"),
        Port:  jsii.Number(80)})

        Name:        jsii.String("nginx-container-service"),
        ServiceType: cdk8splus22.ServiceType_LOAD_BALANCER,
        Ports:       &[]*cdk8splus22.ServicePort{{Port: jsii.Number(9090), TargetPort: jsii.Number(80)}}})

But things can get even better!

Instead of writing the same logic over and over, you can package it in the form of a reusable component that can be invoked just like other built-in cdk8s functions (e.g. NewDeployment, NewService etc.). Although it might not sound as useful for simple application(s), this approach is invaluable for a large project, team, or organization that wants to scale its engineering efforts. In fact, there is already a pool of ready-to-use components available at These include constructs contributed by the community, AWS, and others as well, across multiple programming languages.

To Better Understand How This Might Look in Practice

… let’s look at the code. I will continue to use WordPress as an example, as I did in the previous blog post. Here is a code snippet that shows how everything is wired together (with an implementation walk-through in the next section):

You can refer to the complete code on Github


func NewMyChart(scope constructs.Construct, id string, props *MyChartProps) cdk8s.Chart {
    NewWordpressStack(chart, jsii.String("wordpress-stack"), &WordpressProps{//....)
    return chart

func main() {
    app := cdk8s.NewApp(nil)
    NewMyChart(app, "wordpress-custom-stack", nil)

  • NewWordpressStack gives us a construct that represents an entire WordPress installation (single line of code!)
  • We simply configure it as per our requirements (with WordPressProps)
  • Include this as part of a cdk8s.Chart which is then included in the cdk8s.App (as with any other cdk8s application)

There is a lot of flexibility in terms of how you want to build a custom construct, depending on your requirements. But, at its very core, the basic concept is to define a way to create a new construct.Construct. You would want to provide a way to add metadata to further configure/refine your Construct – typically, that’s done through properties (cdk8s.ChartProps).

First, we define WordPressProps – this encapsulates/externalizes the attributes of the WordPress installation. Since this is just an example, I have provided limited attributes such as MySQL/WordPress Docker images, MySQL password, and required storage.

type WordPressProps struct {
    MySQLImage    *string
    MySQLPassword *string
    MySQLStorage  *float64

    WordPressImage   *string
    WordPressStorage *float64

Then we have a function that will allow other charts/constructs to instantiate WordPress. This is where the entire implementation resides.

func NewWordpressStack(scope constructs.Construct, id *string, props *WordpressProps) constructs.Construct {

The props *WordpressProps parameter allows other constructs to influence the WordPress stack creation e.g. you can define how much storage you need, maybe use a different Docker image for WordPress/MySQL. The actual code for this function is similar to the one you saw here (with required adjustments), so there is no point repeating it here. I will simply highlight the important bits – specifically the ones that use the props to configure the required components.

This sample construct used cdk8splus22 library. The reason for this naming convention is because each cdk8s-plus library is separately vended to target a specific Kubernetes version – the 22 at the end signifies that this dependency will work with Kubernetes 1.22. You can use the library corresponding to your Kubernetes version and refer to the FAQs for more info.

We use the MySQL password from props and use that to create the Secret.

password := props.MySQLPassword
mysqlSecret := cdk8splus22.NewSecret(wordpressConstruct, jsii.String("mysql-secret"),
    Metadata: &cdk8s.ApiObjectMetadata{Name: jsii.String(secretName)}}) 
secretKey := "password"
mysqlSecret.AddStringData(jsii.String(secretKey), password)

The container images for MySQL and WordPress are referenced via their respective Deployments:

    containerImage := props.MySQLImage

    mysqlContainer := dep.AddContainer(&cdk8splus22.ContainerProps{
        Name:  jsii.String("mysql-container"),
        Image: containerImage,
        Port:  jsii.Number(3306),

    wordpressContainer := wordPressDeployment.AddContainer(&cdk8splus22.ContainerProps{
        Name:  jsii.String("wordpress-container"),
        Image: props.WordpressImage,
        Port:  jsii.Number(80),

We also use the passed-in storage as well – this is used to configure the PersistentVolumeClaim request.

    mysqlPVC := cdk8splus22.NewPersistentVolumeClaim(wordpressConstruct, jsii.String("mysql-pvc"), &cdk8splus22.PersistentVolumeClaimProps{
        AccessModes: &[]cdk8splus22.PersistentVolumeAccessMode{cdk8splus22.PersistentVolumeAccessMode_READ_WRITE_ONCE},
        Storage:     cdk8s.Size_Gibibytes(props.MySQLStorage)})

    wordpressPVC := cdk8splus22.NewPersistentVolumeClaim(wordpressConstruct, jsii.String("wordpress-pvc"), &cdk8splus22.PersistentVolumeClaimProps{
        AccessModes: &[]cdk8splus22.PersistentVolumeAccessMode{cdk8splus22.PersistentVolumeAccessMode_READ_WRITE_ONCE},
        Storage:     cdk8s.Size_Gibibytes(props.WordpressStorage)})

Finally, we call NewWordpressStack from another cdk8s.Chart and pass in the attributes we want to configure.

func NewMyChart(scope constructs.Construct, id string, props *MyChartProps) cdk8s.Chart {
    var cprops cdk8s.ChartProps
    if props != nil {
        cprops = props.ChartProps
    chart := cdk8s.NewChart(scope, jsii.String(id), &cprops)

    NewWordpressStack(chart, jsii.String("wordpress-stack"), &WordpressProps{
        MySQLImage:       jsii.String("mysql"),
        MySQLPassword:    jsii.String("Password123"),
        MySQLStorage:     jsii.Number(3),
        WordPressImage:   jsii.String("wordpress:4.8-apache"),
        WordPressStorage: jsii.Number(2)})

    return chart

Use this to install WordPress

To test it locally…

… you can use minikube, kind, etc.

# make sure cluster is running
minikube start

git clone
cd part4-custom-construct

Create manifest and inspect all the resources (see dist directory):

To deploy them:

kubectl apply -f dist/

# output (might differ in your case)

secret/mysql-pass created
deployment.apps/mysql-mysql-deployment-cdk8splus-c83762d9 created
persistentvolumeclaim/mysql-mysql-pvc-c8799bba created
service/mysql-service created
deployment.apps/wordpress-wordpress-deployment-cdk8splus-c8252da7 created
service/wordpress-service created
persistentvolumeclaim/wordpress-wordpress-pvc-c8334a29 created

Check the Kubernetes Service (called wordpress-service) which exposes the WordPress Deployment.

kubectl get svc wordpress-service

If you’re using minikube, in a different terminal run (if not already running):

Use your browser to navigate to http://localhost:80. You should see the familiar WordPress installation screen.

Go ahead, finish the installation and log into your WordPress instance. Feel free to experiment with it.


cdk8s is a powerful tool itself but it also provides you the ability to extend and build other abstractions on top of it. You saw how to write a custom construct Go and used it to deploy WordPress on Kubernetes. This can be further used as a foundation for other reusable components.

Happy coding!

Source link



Leave a Reply

Your email address will not be published. Required fields are marked *