Skip to content

Instantly share code, notes, and snippets.

@rafaribe
Created May 3, 2020 22:48
Show Gist options
  • Save rafaribe/3a9697699824207c2cc6ccffc0296794 to your computer and use it in GitHub Desktop.
Save rafaribe/3a9697699824207c2cc6ccffc0296794 to your computer and use it in GitHub Desktop.
Example of Using CDK8s for a Java App with Deployment, Service, and ServiceMonitor (Prometheus Operator)
import { App, Chart } from 'cdk8s';
import { Construct } from 'constructs';
import { JavaApp } from '../lib/java-app';
import { Quantity } from '../imports/k8s';
import { Environment } from '../lib/utils';
import * as dotenv from 'dotenv';
import { EXAMPLE_APP_NAME } from './constants';
dotenv.config();
export class ExampleJavaApp extends Chart {
constructor(scope: Construct, name: string) {
super(scope, name);
const constructId: string = 'example-app';
const namespace: string = 'dev';
new JavaApp(this, constructId, {
namespace: namespace,
name: EXAMPLE_APP_NAME,
image:
'examplejavaapp:latest',
replicas: 1,
containerPort: 3000,
secretName: constructId + '-secrets',
limits: {
memory: Quantity.fromString('1024Mi'),
cpu: Quantity.fromString('750m'),
},
environment: Environment.INTEGRATION,
});
}
}
const app = new App();
new ExampleJavaApp(app, EXAMPLE_APP_NAME);
app.synth();
import { Construct } from 'constructs';
import {
Deployment,
IntOrString,
Quantity,
Service,
ServicePort,
} from '../imports/k8s';
import { ServiceMonitor } from '../imports/servicemonitor';
import {
Environment,
GetAnnotationsByEnvironment,
GetPodLabelKeysAsArray,
} from './utils';
export interface JavaAppOptions {
/**
* The Docker image to use for this service.
*/
readonly image: string;
/**
* The Namespace that should be used for the resources
*/
readonly namespace: string;
/**
* The Service name
*/
readonly name: string;
/**
* Number of replicas.
*
* @default 1
*/
readonly replicas?: number;
/**
* External port.
*
* @default 80
*/
readonly port?: number;
/**
* Internal port.
*
* @default 8080
*/
readonly containerPort?: number;
/**
* Secrets.
*
* @default null
*/
readonly secretName: string;
/**
* Resource limits for the pods
*/
readonly limits?: { [key: string]: Quantity };
/**
* Environment in which the app will run
*/
readonly environment: Environment;
}
export class JavaApp extends Construct {
constructor(
scope: Construct,
constructId: string,
options: JavaAppOptions,
) {
super(scope, constructId);
const port = options.port || 80;
const containerPort =
options.containerPort || 8080;
const label = { app: options.name };
const limits = options.limits || {
memory: Quantity.fromString('1024Mi'),
cpu: Quantity.fromString('750m'),
};
const servicePort: ServicePort = {
port,
targetPort: IntOrString.fromNumber(
containerPort,
),
name: 'app',
};
const podLabels: { [key: string]: string } = {
['app']: label.app,
['language']: 'java',
['framework']: 'spring',
['logframework']: 'logback',
['environment']: options.environment,
};
new Service(this, 'service', {
metadata: {
name: options.name,
namespace: options.namespace,
labels: label,
},
spec: {
selector: label,
ports: [servicePort],
},
});
new Deployment(this, options.name, {
metadata: {
namespace: constructId,
name: options.name,
annotations: GetAnnotationsByEnvironment(
options.environment,
options.name,
),
},
spec: {
replicas: 1,
selector: {
matchLabels: label,
},
template: {
metadata: {
labels: podLabels,
},
spec: {
containers: [
{
name: options.name,
image: options.image,
ports: [{ containerPort }],
resources: {
limits: limits,
},
envFrom: [
{
secretRef: {
name: options.secretName,
optional: false,
},
},
],
},
],
},
},
},
});
new ServiceMonitor(
this,
options.name + '-sm',
{
metadata: {
namespace: constructId,
name: options.name,
labels: {
['prometheus']: 'monitoring',
},
},
spec: {
selector: {
matchLabels: label,
},
endpoints: [
{
port: servicePort.name,
path: 'actuator/prometheus',
interval: '30s',
},
],
podTargetLabels: GetPodLabelKeysAsArray(
podLabels,
),
},
},
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment