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 located in https://github.com/ballerina-platform/ballerina-lang/tree/master/examples/resources/ to the security folder.

For more information, see How to Deploy Ballerina Programs and Services in the Cloud.

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}