import ballerina/config;
import ballerina/http;
import ballerina/log;
import ballerina/kubernetes;
@kubernetes:Service {
    serviceType: "NodePort"
}
@kubernetes:Ingress {
    hostname: "abc.com"
}
listener http:Listener helloWorldEP = new(9090, config = {
    secureSocket: {
        keyStore: {
            path: "./security/ballerinaKeystore.p12",
            password: "ballerina"
        },
        trustStore: {
            path: "./security/ballerinaTruststore.p12",
            password: "ballerina"
        }
    }
});
@kubernetes:ConfigMap {
    conf: "./ballerina.conf"
}
@kubernetes:Deployment {
    livenessProbe: true,
    image: "kubernetes:v.1.0"
}
@http:ServiceConfig {
    basePath: "/helloWorld"
}
service helloWorld on helloWorldEP {
    @http:ResourceConfig {
        methods: ["GET"],
        path: "/config/{user}"
    }
    resource function getConfig(http:Caller outboundEP, http:Request request, string user) {
        string userId = getConfigValue(user, "userid");
        string groups = getConfigValue(user, "groups");
        json payload = {
            userId: userId,
            groups: groups
        };
        var responseResult = outboundEP->respond(payload);
        if (responseResult is error) {
            error err = responseResult;
            log:printError("Error sending response", err);
        }
    }
}function getConfigValue(string instanceId, string property) returns (string) {
    string key = <@untainted string> (instanceId + "." + property);
    return config:getAsString(key, "Invalid User");
}# Create a `ballerina.conf` file with the following content in the same directory, which contains the kubernetes_deployment.bal file.
[john]
userid="john@ballerina.com"
groups="apim,esb"
[jane]
userid="jane3@ballerina.com"
groups="esb"

Kubernetes Deployment

Ballerina supports generating Kubernetes artifacts based on annotations. A single Ballerina module is mapped to a single Kubernetes deployment. Minikube or Docker for Mac/Windows should be configured and Kubernetes should be enabled to run the example. This example deploys an HTTPS service, which retrieves values from a config file to Kubernetes. Before running the sample, create a directory named security inside current working directory from where the ballerina build command will be issued. Then, copy the ballerinaKeystore.p12 and ballerinaTruststore.p12 files to the security folder.

For more information, see the Kubernetes Deployment Guide.

import ballerina/config;
import ballerina/http;
import ballerina/log;
import ballerina/kubernetes;
@kubernetes:Service {

Add the @kubernetes:Service to a listener endpoint to expose the endpoint as a Kubernetes Service.

    serviceType: "NodePort"
}

Service type is NodePort.

@kubernetes:Ingress {

Add the @kubernetes:Ingress to a listener endpoint to expose the endpoint as a Kubernetes Ingress.

    hostname: "abc.com"
}
listener http:Listener helloWorldEP = new(9090, config = {

Hostname of the service is abc.com.

    secureSocket: {
        keyStore: {
            path: "./security/ballerinaKeystore.p12",
            password: "ballerina"
        },
        trustStore: {
            path: "./security/ballerinaTruststore.p12",
            password: "ballerina"
        }
    }
});

Ballerina automatically creates Kubernetes secrets for the keystore and truststore when the @kubernetes:Service annotation is added to the endpoint.

@kubernetes:ConfigMap {

Add the @kubernetes:ConfigMap annotation to a Ballerina service to mount configs to the container.

    conf: "./ballerina.conf"
}

Path to the ballerina.conf file. If a releative path is provided, the path should be releative to where the ballerina build command is executed.

@kubernetes:Deployment {

Add the @kubernetes:Deployment annotation to a Ballerna service to generate Kuberenetes Deployment for a Ballerina module.

    livenessProbe: true,

Enable Kubernetes liveness probe to this service.

    image: "kubernetes:v.1.0"

Generate a Docker image with the name kubernetes:v1.0.

}
@http:ServiceConfig {
    basePath: "/helloWorld"
}
service helloWorld on helloWorldEP {
    @http:ResourceConfig {
        methods: ["GET"],
        path: "/config/{user}"
    }
    resource function getConfig(http:Caller outboundEP, http:Request request, string user) {
        string userId = getConfigValue(user, "userid");
        string groups = getConfigValue(user, "groups");
        json payload = {
            userId: userId,
            groups: groups
        };
        var responseResult = outboundEP->respond(payload);
        if (responseResult is error) {
            error err = responseResult;
            log:printError("Error sending response", err);
        }
    }
}

If you are using minikube, uncomment and change the following values accordingly. //dockerHost:“tcp://:2376”, //dockerCertPath:”/.minikube/certs”

function getConfigValue(string instanceId, string property) returns (string) {
    string key = <@untainted string> (instanceId + "." + property);
    return config:getAsString(key, "Invalid User");
}
# Create a `ballerina.conf` file with the following content in the same directory, which contains the kubernetes_deployment.bal file.
[john]
userid="john@ballerina.com"
groups="apim,esb"
[jane]
userid="jane3@ballerina.com"
groups="esb"
# Build the ballerina program
$ ballerina build kubernetes_deployment.bal
Compiling source
	kubernetes_deployment.bal
Generating executables
	kubernetes_deployment.jar
Generating artifacts...
	@kubernetes:Service 			 - complete 1/1
	@kubernetes:Ingress 			 - complete 1/1
	@kubernetes:ConfigMap 			 - complete 1/1
	@kubernetes:Deployment 			 - complete 1/1
	@kubernetes:Docker 			 - complete 2/2 
	@kubernetes:Helm 			 - complete 1/1
	Run the following command to deploy the Kubernetes artifacts: 
	kubectl apply -f ./kubernetes
	Run the following command to install the application using Helm: 
	helm install --name kubernetes-deployment-deployment ./kubernetes/kubernetes-deployment-deployment
# Verify the Docker image is generated
$ docker images
REPOSITORY  TAG      IMAGE ID            CREATED             SIZE
kubernetes  v1.0   6c0a26a62545        2 seconds ago       127MB
# Apply the Kubernetes artifacts.
$ kubectl apply -f ./kubernetes/
service/helloworldep-svc created
ingress.extensions/helloworldep-ingress created
secret/helloworldep-secure-socket created
configmap/helloworld-ballerina-conf-config-map created
deployment.extensions/kubernetes-deployment-deployment created
# Verify if the service, pods, & config-maps are deployed
$ kubectl get pods
NAME                                     READY     STATUS   RESTARTS   AGE
kubernetes-deployment-5858fd78d4-lnz8n   1/1       Running   0         20s
$ kubectl get svc
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
helloworldep-svc    NodePort    10.109.125.193   <none>        9090:32417/TCP   1m
$ kubectl get cm
NAME                                   DATA      AGE
helloworld-ballerina-conf-config-map   1         5m
# Access the service
# Change the port <32417> to Nodeport of the service.
$ curl https://localhost:<32417>/helloWorld/config/jane -k
{userId: jane3@ballerina.com, groups: esb}
$ curl https://localhost:<32417>/helloWorld/config/john -k
{userId: john@ballerina.com, groups: apim,esb}
# If you are using minikube, IP address should be changed according to the output of the `minikube ip` command.
$ minikube ip
192.168.99.100
$ curl https://192.168.99.100:<32417>/helloWorld/config/jane -k
{userId: jane3@ballerina.com, groups: esb}