DEV Community

Cover image for Deploying a Simple NodeJS Microservice using CDK8s
 Aatman
Aatman

Posted on • Updated on

Deploying a Simple NodeJS Microservice using CDK8s

Writing 200+ lines of YAML code just to deploy a Microservice on Kubernetes is a massive pain for a DevOps engineer.

CDK8s can be used to remove all that duplicate code, and make it easier to deploy your Microservice without having to write massive YAML manifests.

We also get the ability to write code using our favorite object-oriented languages.

We will be writing a sample CDK8s chart using TypeScript and opensource CDK8s constructs.

Constructs used :

@opencdk8s/cdk8s-redis-sts v0.0.7
cdk8s-plus-17 v1.0.0-beta.8
Enter fullscreen mode Exit fullscreen mode
  • Initialize CDK8s project
mkdir cdk8s-node-app && cd cdk8s-node-app
cdk8s init typescript-app
Enter fullscreen mode Exit fullscreen mode
  • Install construct libraries
npm install @opencdk8s/cdk8s-redis-sts 
Enter fullscreen mode Exit fullscreen mode
  • Edit main.ts to include our Redis db, and NodeJS app
import { Construct } from 'constructs';
import { App, Chart, ChartProps } from 'cdk8s';
import { MyRedis } from '@opencdk8s/cdk8s-redis-sts';
import { Deployment } from 'cdk8s-plus-17';

export class MyChart extends Chart {
  constructor(scope: Construct, id: string, props: ChartProps = { }) {
    super(scope, id, props);
const redis = new MyRedis(this, 'redis', {
      image: 'redis',
      namespace: 'default',
      volumeSize: '10Gi',
      replicas: 3,
      createStorageClass: false,
    });
new Deployment(this, "deployment", {
      metadata: {
        namespace: 'default',
      },
      containers: [{
        image: "hunterthompson/node-redis-counter:latest",
        name: "hello",
        env: {
          'REDIS_URI': {
            value: redis.name
          }
        }
      }]
    })
  }
}

const app = new App();
new MyChart(app, 'microservice');
app.synth();
Enter fullscreen mode Exit fullscreen mode
  • Run Compile and Synth
npm run compile && npm run synth
Enter fullscreen mode Exit fullscreen mode

The end result of the npm run synth command is a YAML manifest that you can apply using kubectl

apiVersion: v1
data:
  master.conf: |-

    bind 0.0.0.0
    daemonize no
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    supervised no
  slave.conf: |-

    slaveof redis 6379
kind: ConfigMap
metadata:
  name: redis-redis-conf
  namespace: default
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: redis
  name: redis
  namespace: default
spec:
  ports:
    - port: 6379
      targetPort: 6379
  selector:
    app: redis
  type: ClusterIP
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app: redis
  name: redis
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: redis
  serviceName: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - command:
            - bash
            - -c
            - |-
              [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
              ordinal=${BASH_REMATCH[1]}
              if [[ $ordinal -eq 0 ]]; then
              redis-server /mnt/redis/master.conf
              else
              redis-server /mnt/redis/slave.conf
              fi
          env: []
          image: redis
          name: redis
          ports:
            - containerPort: 6379
          resources:
            limits:
              cpu: 400m
              memory: 512Mi
            requests:
              cpu: 200m
              memory: 256Mi
          volumeMounts:
            - mountPath: /data
              name: redis
            - mountPath: /mnt/redis/
              name: redis-redis-conf
      terminationGracePeriodSeconds: 10
      volumes:
        - configMap:
            name: redis-redis-conf
          name: redis-redis-conf
  volumeClaimTemplates:
    - metadata:
        name: redis
        namespace: default
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 10Gi
        storageClassName: gp2
--------
apiVersion: apps/v1
kind: Deployment
metadata:
  name: microservice-deployment-c89e8760
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      cdk8s.deployment: microservice-deployment-c87f6fea
  template:
    metadata:
      labels:
        cdk8s.deployment: microservice-deployment-c87f6fea
    spec:
      containers:
        - env:
            - name: REDIS_URI
              value: redis
          image: hunterthompson/node-redis-counter:latest
          imagePullPolicy: Always
          name: hello
          ports: []
          volumeMounts: []
      volumes: []
Enter fullscreen mode Exit fullscreen mode

We just synthesized a 130 line YAML manifest by writing 33 lines of CDK8s code.

Top comments (2)

Collapse
 
nideveloper profile image
Matt Coulter

Hey, have you considered submitting a cdk8s talk to CDK Day? The cfp is at sessionize.com/cdkday

Collapse
 
hunterthompson profile image
Aatman

Hey Matt, thanks for the link, I will definitely register for this event :)