1 Local Components & Services (same module)

This tutorial shows how to:

  • Create a module (kumori.mod.json)
  • Define a component interface (*.h.kumori) and implementation (*.kumori)
  • Define a service that references that component locally (no external dependency)
  • Create a deployment that targets the service

1.1 Project layout

A minimal layout can live entirely in one folder (one module, one package):

my-module/
  kumori.mod.json
  component.h.kumori
  component.kumori
  service.h.kumori
  service.kumori
  deployment.kumori

1.2 Module manifest (kumori.mod.json)

{
  "spec": "kumori/module/v1",
  "module": "kumori.tutorials/local-artifacts",
  "kumori": "0.0.1",
  "version": "0.0.1",
  "requires": []
}

Typical command to create this file:

kdsl mod init kumori.tutorials/local-artifacts 0.0.1

1.3 Component interface (component.h.kumori)

This is the public contract of the component (srv/config/resource/types).

import "kumori"

component EchoServer {
    srv {
        server {
            server { protocol "http", port 8080 }
        }
    }

    config {
        Whatever {
            Response: string = "hello"
            Scale:    number = 1
        }
    }
}

1.4 Component implementation (component.kumori)

The implementation contains runtime details (code, size, var, etc). It can reference:

  • interface.* for interface-defined values
  • self.* for implementation-only values
import (
    "strconv"
)

component EchoServer {
    var (
        Port = strconv.Concat([":", strconv.Format(interface.srv.server.server.port, 10)])
    )

    size {
        bandwidth    10G
        minbandwidth 1000M
        mincpu       400m
    }

    code {
        EchoServer {
            cmd   ["-listen", var.Port, "-text", interface.config.Whatever.Response]
            image "docker.io/hashicorp/http-echo:latest"
            size {
                memory 500M
                cpu    400m
                mincpu 400m
            }
        }
    }
}

1.5 Service interface (service.h.kumori)

This is the public contract for the service.

import "kumori"

service EchoService {
    config {
        Scale: number
    }

    resource {
        Port: kumori.Port
    }
}

1.6 Service implementation (service.kumori)

The key point: the role EchoServer references the artifact by its local name (artifact EchoServer).

import (
    "kumori"
    "kumori/builtin"
)

service EchoService {
    role {
        EchoServer {
            artifact EchoServer
            config {
                Whatever {
                    Response "b"
                    Scale    interface.config.Scale
                }
            }
        }

        Inbound {
            artifact builtin.TCPInbound
            resource {
                port interface.resource.Port
            }
        }
    }

    connect {
        ExampleConnection kumori.LoadBalancer({
            from {
                target  "Inbound"
                channel "inbound"
            }
            to {
                target  "EchoServer"
                channel "server"
            }
        })
    }
}

1.7 Deployment (deployment.kumori)

The deployment selects the top-level artifact to deploy (EchoService) and provides values for its config/resource interface.

import "kumori"

deployment {
    name       "local-echo"
    artifact   EchoService
    resilience 1

    config {
        Scale 2
    }

    resource {
        Port kumori.Port("my-port")
    }
}

1.8 Running it

From the module directory:

  • kdsl check validates types/structure.
  • kdsl build produces the deployment spec / solution output.