Microservice Builder Input Specification

In this section, we will go through the specification of the input to the UCF Microservice Builder (msbuider) tool used for creating and building UCF Microservices.

For more information, on what a UCF Microservice is refer to - UCF Microservice.

Note

A template input directory for the msbuilder can be generated using - Generate scaffolding.

Input Directory Structure

A typical input directory structure for msbuilder would contain:

<msbuilder-input-directory>
  ├── changelog.txt
  ├── configs
  ├── containers
  │   └── cb_config.yaml
  ├── endpoints
  │   ├── http-api.yaml
  │   └── myservice-endpoint-name.yaml
  ├── LICENSE.txt
  ├── manifest.yaml
  ├── manual_compliance_test_results.yaml
  ├── README.md
  ├── scripts
  ├── tests
  │   └── dev
  │       ├── app.yaml
  │       └── params1.yaml
  └── values.yaml

Some of the files / directories are not used when using a particular type of msbuilder input. Individual sections below will clarify if the file / directory is not used.

Manifest file - manifest.yaml

The manifest file manifest.yaml contains information for describing the microservice, the helm chart implementation and container build config details.

The template manifests generated for each of the three use cases differ slightly.

Following is an example of the template manifest.yaml file:

type: msapplication
specVersion: 2.0.0
name: ucf.svc.myservice
chartName: myservice
description: default description
version: 0.0.1
tags: []
keywords: []

publish: false

egress-endpoints:
  - name: myservice-endpoint-name
    description: Short description of endpoint
    protocol: TCP # Or UDP
    scheme: asyncio # Or grpc / rtsp / asyncio / none
    mandatory: True # Or False
    data-flow: in-out # Or in or out

ingress-endpoints:
  - name: http-api
    description: Short description of http-api ingress endpoint
    scheme: http
    data-flow: in-out # Or in or out

secrets:
  - name: some-secret-name
    description: Description for the secret
    mandatory: True
    mountPath: /secrets
    fileName: someSecretFileName

params:
  stringToEcho: someString
  #> type: string
  #> enum_values: someString, someOtherString
  #> description: String to echo in init container
  timeToSleep: 1000000
  #> type: integer
  #> maximum: 2000000
  #> minimum: 1000000
  #> description: String to echo in init container
  #> flags: mandatory

# Files and directories will be mounted with prefix /opt/ext-files/
externalFiles:
- name: some-config.yaml # File will be available in containers at /opt/ext-files/some-config.yaml
  description: Some Configuration file
  mandatory: True
  isDirectory: False

tests:
  - name: dev-params1
    app: tests/dev/app.yaml
    params: tests/dev/params1.yaml
    ciTrigger: false
    timeout: 10
    duration: 10
    installPreReqs: true  # Wether to install foundational services
    namespace: default  # Kubernetes namespace
    gpuNodeLabels: ""
    watchAllPods: true # OR set to false and set list of pods to watch below
    watchPods:
    - <pod-name-regex>
    testerPods:  # At least one tester pod is required
    - name: testpod1  # Name of the test pod
      startSignature: <START>  # Signature to look for in the logs indicating start of tests. Regex is accepted
      endSignature: <END>  # Signature to look for in the logs indicating end of tests. Regex is accepted
      errorSignatures:  # Signatures that indicate test failures.  Regex is accepted
      - <REGEX1>
      - <REGEX2>


---
spec:
  - name: myservice-deployment
    type: ucf.k8s.app.deployment
    parameters:
      apptype: stateless

  - name: myservice-init-container
    type: ucf.k8s.initcontainer
    parameters:
      image: ubuntu
      imagePullPolicy: IfNotPresent
      args: [echo, $params.stringToEcho]
  - name: "myservice-container"
    type: ucf.k8s.container
    parameters:
      image:
        repository: ubuntu
        tag: "latest"
      command: ["sleep", "$params.timeToSleep"]
      ports:
      - containerPort: 0 # <PORT>
        name: http
      startupProbe:
        httpGet:
          path: /healthz
          port: http
        failureThreshold: 30
        periodSeconds: 10
      livenessProbe:
        httpGet:
          path: /healthz
          port: http
      readinessProbe:
        exec:
          command:
          - cat
          - /tmp/healthy
        initialDelaySeconds: 5
        periodSeconds: 5

  - name: myservice-service
    type: ucf.k8s.service
    parameters:
      annotations:
        test-svc-annotation: annotation-value
      labels:
        test-svc-label: label-value
      ports:
      - port: 0 # <OUT_PORT>
        name: http-api
      #externalTrafficPolicy: # Cluster / Local. Allowed when service type is NodePort or LoadBalancer

Basic Information

The following table lists basic information that must be specified in the manifest file.

Field

Description

specVersion

The UCF MS Specification version that the manifest / MS adheres to. Current specVersion is 2.0.0

name

Unique string identifier for the microservice. Must start with ucf.svc. prefix

chartName

A unique name for the microservice helm chart. Must follow convention at https://helm.sh/docs/chart_best_practices/conventions/#chart-names. Ignored if using a prebuilt helm chart

chart

Link to a prebuilt helm chart

description

A short description of the microservice

displayName

User friendly name for the microservice

category.functional

Functional category for the microservice e.g. Database, Vision AI etc

category.industry

Industry category for the microservice e.g. General, Retail, Smart Space etc

version

Microservice version. Must follow semantic versioning https://semver.org/

tags

A list of strings for categorizing the microservice

keywords

A list of strings that maybe helpful when searching for this microservice

Ingress Endpoints

Ingress endpoints are specified as a list under the ingress-endpoints field. The attributes for an Ingress endpoint are:

Field

Description

name

A string identifier for the ingress endpoint

description

A short description of the endpoint

scheme

Scheme the endpoint follows. One of http, grpc, rtsp, asyncio, ucx, resp, mongodb-wire or none

data-flow

Flow of data through the egress endpoint. One of in, out or in-out

service

Kubernetes service abstraction name for the endpoint. Can be skipped if it should be inferred from a ucf.k8s.service component. The ingress endpoint name and the port name in ucf.k8s.service must match for this.

port

Port number for the ingress endpoint. Can be skipped if it should be inferred from a ucf.k8s.service component. The ingress endpoint name and the port name in ucf.k8s.service must match for this.

protocol

The network protocol the endpoint must use. Either TCP or UDP. Can be skipped if it should be inferred from a ucf.k8s.service component. The ingress endpoint name and the port name in ucf.k8s.service must match for this.

For more information on endpoints refer to Endpoints.

Egress Endpoints

Egress endpoints are specified as a list under the egress-endpoints field. The attributes for an Egress endpoint are:

Field

Description

name

A string identifier for the egress endpoint

description

A short description of the endpoint

protocol

The network protocol the endpoint must use. Either TCP or UDP

scheme

Scheme the endpoint follows. One of http, grpc, rtsp, asyncio, ucx, resp, mongodb-wire or none

mandatory

Boolean indicating if connecting the egress endpoint is mandatory for the microservice to work correctly

data-flow

Flow of data through the egress endpoint. One of in, out or in-out

multi

Boolean indicating if the egress endpoint can be connected to multiple ingress endpoints. Assumed to be false if not specified.

Placeholders $egress.<egress-endpoint-name>.address and $egress.<egress-endpoint-name>.port can be used where these egress connection parameters are needed. These placeholders can be used anywhere in spec section of manifest.yaml or in the files inside configs directory. These placeholders will get overridden by actual address and port during application build.

For example, microserviceServer implements an HTTP API server, creates a kubernetes service resource for it with name server-http-api-svc and port 8000 and creates a corresponding ingress endpoint named http-api.

Another microserviceClient contains a client for the HTTP API and creates a corresponding egress endpoint named http-api. It specifies an environment variable SERVER_ENDPOINT in the container section with placeholders in the value http://$egress.http-api.address:$egress.http-api.port/ e.g:

# microserviceClient manifest.yaml
...
egress-endpoints:
  - name: myservice-endpoint-name
    description: Short description of endpoint
    protocol: TCP # Or UDP
    scheme: asyncio # Or grpc / rtsp / asyncio / none
    mandatory: True # Or False
    data-flow: in-out # Or in or out
...
spec:
- name: "client-container"
    type: ucf.k8s.container
    parameters:
      image:
        repository: client-container-repo
        tag: client-container-tag
      env:
      - name: SERVER_ENDPOINT
        value: http://$egress.http-api.address:$egress.http-api.port/

In the UCF application, http-api egress endpoint of microserviceClient is connected to http-api egress endpoint of microserviceServer, then during app build all occurrences of $egress.http-api.address and $egress.http-api.port will be overridden with server-http-api-svc and 8000 respectively. Thus environment variable SERVER_ENDPOINT in the container of microserviceClient will be set to http://server-http-api-svc:8000/.

For more information on endpoints refer to Endpoints.

Parameters

Parameters for microservice can be described under params field. Supported parameter types are primitives like Boolean, numbers and string as well as lists and objects. Nested structures are supported.

Default values can provided for the parameters. Parameters maybe annotated using comments beginning at the next line after the parameter. The lines must start with the prefix #> followed by a keyword and a value for the keyword. Example:

params:
  someParam: 100
  #> type: number
  #> description: Description for someParam
  #> minimum: 10
  #> maximum: 1000
  #> flags: mandatory
  someStringParam: someDefaultValue
  #> type: string
  #> description: Description for someStringParam
  #> enum_values: someDefaultValue, someOtherValue
  someObjectParam:
  #> type: object
  #> description: Description for someObjectParam
    someSubParamInSomeObjectParam: false
    #> type: boolean
    #> description: Description for someSubParamInSomeObjectParam

Supported annotations for annotation keywords are:

Keyword

Description

type

Type of parameter. One of boolean, number, integer, string, object, array or null

description

A short description of the parameter

minimum

Minimum allowed value if the parameter type is number

maximum

Maximum allowed value if the parameter type is number

enum_values

Comma separated list of allowed values

flags

Comma separated list of flags for the parameter. Currently supported flags are mandatory

Parameters can be referenced in the manifest.yaml or in the files inside the configs directory using the $params placeholders. These placeholder get overridden by the user set value or the default value during app build time. Example:

spec:
...
- name: app-container
  type: ucf.k8s.container
  parameters:
    ...
    env:
    - name: SOME_ENV_VAR
      value: $params.someObjectParam.someSubParamInSomeObjectParam

Parameter values are also set in the values of the microservice helm chart. And hence they can be referenced using helm templates as well. Example:

{{- if .Values.someObjectParam.someSubParamInSomeObjectParam }}
...
{{- end }}

Secrets

Secret requirements for the microservice can be described under the secrets field. The secrets get mounted as files inside the microservice containers.

A list of secret requirements can be added under secrets field. Supported attributes are:

Field

Description

name

A string identifier for the secret

description

A short description of the secret requirement

mountPath

Path inside the microservice containers to mount the secret file under

fileName

Name of the file to use when mounting the secret file. Files are mounted at <mountPath>/<fileName>

mandatory

Boolean indicating if it is mandatory for the app using the microservice to set the secret

For details on how secrets works in UCF and requirements from microservice and application developers refer to Secrets Management.

External Files

External file requirements for the microservice can be described under the externalFiles field. With this application builder can pass entire files/directories from the local system to microservice when building the application. The files get mounted inside the microservice containers with prefix /opt/ext-files. Supported attributes are:

Field

Description

name

Name for the file. File is expected to be mounted at /opt/ext-files/<name>

description

A short description of the expected file and contents

mandatory

Boolean indicating if it is mandatory for the app using the microservice to set the file

isDirectory

Boolean indicating if microservice expects a directory to be provided instead of a file

Metrics

Information on the microservice metrics endpoint and metrics exported by the microservice are described under the metrics field as an array.

Tests

Tests for the microservice can be specified under tests section. Tests are basically UCF Applications tailored to test the microservice being developed. When the building the microservice, it’s test applications get built as well.

The tests can be executed locally by deploying the test application helm charts.

The tests are specified as a list under tests section. Supported attributes for a test are:

Field

Description

name

A string identifier for the test app

app

Path to a UCF application graph file. Can be specified as an absolute path or relative to the manifest.yaml file

params

Path to a UCF application params file to override parameters in the application graph file. Can be specified as an absolute path or relative to the manifest.yaml file

ciTrigger

Boolean to indicate if the test should be executed as part of UCF MS Validation

timeout

CI pipeline will stop the test after this time and mark it as fail if it does not complete after this time. Value is in minutes. This parameter is applicable to services which returns result and stop when finished.

duration

CI pipeline will stop the test after this time and mark test as pass. Value is in minutes. This is parameter is applicable to services which does not return result and does not stop. It can be used to test if a particular service is deployable and running for a particular time.

installPreReqs

Boolean to indicate if foundational services must be installed before the test application

namespace

Kubernetes namespace to install the test app helm chart under. Currently unused

gpuNodeLabels

Reserved for future use

watchAllPods

Boolean indicating if CI should watch all pods for failures

watchPods

List of regex for pod names that the CI should watch for failures

testerPods

Reserved for future use

For more details on creating UCF Applications refer to Creating an Application.

Spec

Implementation of the microservice (i.e. it’s helm chart) can be specified under the spec field. As part of the UCF Microservice Builder Tool, the microservice implementation must be done using composable components.

When using Pre-built Helm Chart, this section must be omitted. msbuilder ignores this field since it does not build the microservice helm chart.

Components

Components define a small part of the microservice implementation such as a container, a service, a volume.

Adding components to the spec

The components must be added under spec as a list along with their parameters. The parameter values must follow the parameter schema for the component which can be viewed using the component info command as shown above. Placeholders $params, $egress and $secrets can be used in parameter values to refer to the parameters, egress endpoint and secret respectively. These placeholders remain in the built microservice helm chart but are substituted during application build.

An example of adding components with placeholders is:

spec:
  - name: myservice-deployment
    type: ucf.k8s.app.deployment
    parameters:
      apptype: stateless

  - name: "myservice-container"
    type: ucf.k8s.container
    parameters:
      image:
        repository: ubuntu
        tag: "latest"
      env:
      - name: HTTP_API_CA_CERT_PATH
        value: $secrets.ca-cert.path
      command: ["curl", "$egress.http-api.address:$egress.http-api.port",
        "--connect-timeout", $params.connectTimeout, "--cacert", $(HTTP_API_CA_CERT_PATH)]
      startupProbe:
        httpGet:
          path: /healthz
          port: http
        failureThreshold: 30
        periodSeconds: 10
      livenessProbe:
        httpGet:
          path: /healthz
          port: http
      readinessProbe:
        exec:
          command:
          - cat
          - /tmp/healthy
        initialDelaySeconds: 5
        periodSeconds: 5

Note

For the components defined in spec, parameters must adhere to the component schema specific to each type as shown above.

Only one workload type (e.g stateless, stateful, job, cronjob, daemonset, static-pod) can be specified in one yamldoc. To add multiple workload types (e.g. two stateless (i.e. Deployment) ) to the microservice:

---
spec:
- name: app-deployment-1
  type: ucf.k8s.app.deployment
  parameters:
    apptype: stateless
...
---
spec:
- name: app-deployment-2
  type: ucf.k8s.app.deployment
  parameters:
    apptype: stateless
...

Configs Directory - configs

This directory can be used for adding any configuration files for the microservice. Files added to this directory get automatically added to a configmap and mounted under /opt/configs directory in the containers that are part of the microservice.

Files used in this directory can contain the $params, $egress and $secrets placeholders. These placeholders and thus the mounted files under /opt/configs directory will have the placeholders substituted with the actual values when the application is built and deployed.

For example a file named app_cfg.yaml in the configs directory will get mounted at /opt/configs/app_cfg.yaml in containers that are part of the microservice with placeholders updated with actual values.

The files in this directory are NOT used when using a Pre-built Helm Chart.

Scripts Directory - scripts

This directory can be used for adding any script files used by applications running inside the microservice. Files added to this directory get automatically added to a configmap and mounted under /opt/scripts directory in the containers that are part of the microservice.

Placeholders $params, $egress and $secrets added to the files inside this directory will NOT get substituted.

For example a file named run.sh in the scripts directory will get mounted at /opt/scripts/run.sh in containers that are part of the microservice with exactly the same contents.

The files in this directory are NOT used when using a Pre-built Helm Chart.

Container Configs Directory - containers

This directory contains Container Build configuration files for containers used by the microservice. Containers are built using these configuration files during microservice build.

These configuration files follow the Container Build configuration specification. A separate file must be created for each container to be built. There is no restriction on the filenames.

The files in this directory are NOT used when using a Pre-built Helm Chart or when using Pre-built Container Images.

Endpoint Definition Files Directory - endpoints

This directory contains endpoint definition files for each endpoint Ingress or Egress that is part of the microservice. The expected file name is <endpoint-name>.<ext>. The file extension depends on the scheme of the endpoint.

Endpoint definition files are not mandatory for building the microservice, but required for a fully UCF-compliant microservice.

For more information on endpoints and endpoint definition files refer to Endpoints.

Customized Helm Template Directory - templates

User can put customized Helm template yaml files here and they’ll be copied to the final Helm templates folder verbatim。

Manual Compliance Test Results - manual_compliance_test_results.yaml

UCF Microservice compliance requires that microservice developers run some tests manually. The test results can be provided using the manual_compliance_test_results.yaml input file.

The expected format of the file is a map of <compliance-id>: <result-as-boolean>. Example contents of the file:

DEV-005: false
DEV-011: false
DEV-014: false
DEV-017: false
DEV-018: false
DEV-019: false
DEV-020: false
DEV-101: false

For more information on UCF Microservice Compliance and manual compliance checks refer to UCF Microservice Compliance.

Documentation - README.md

Detailed documentation for the microservice must be added to README.md. It must be in a specific format and list of sections is required to be included. The sections include:

  • Description - Detailed description of the microservice, functionality, features

  • Usage - Details on using the microservice in an application like any parameter / endpoint details that cannot be added to the manifest, examples on adding the microservice to an app and its connections.

  • Performance/KPIs - Details on expected performance / KPIs

  • Supported Platforms - Information on supported platforms / GPUs

  • Deployment requirements - Deployment requirements like CPU / memory / NICs / node host configuration

  • License - License the microservice uses

  • Known Issues / Limitations - List of known issues, limitations & workarounds

  • References - References / useful links like sample apps on GitHub, SDKs used, further reading.

Note

A template README.md can be created using the service create command. Refer to Generate scaffolding.

License - LICENSE.txt

Licenses of 3rdparty software used in the microservice

Changelog - changelog.txt

This file must contain the changelog for the current version of the microservice.

Tests Directory - tests

This directory contains the test applications for the microservice. The applications must be in UCF Application specification. These test applications get built along with the microservice.

Values file values.yaml

This file is used ONLY when using a Pre-built Helm Chart.

It is in the form of a standard Helm values.yaml and contains values of the pre-built helm chart that must be overridden. The file can contain the $params, $egress and $secrets placeholders which will get substituted with the actual values when the application is built and deployed.