CUE Components

    In this section, it will introduce how to use CUE to declare app components via ComponentDefinition.

    First, generate ComponentDefinition scaffolds via vela def init with existed YAML file.

    The YAML file:

    Generate ComponentDefinition based on the YAML file:

    1. vela def init stateless -t component --template-yaml ./stateless.yaml -o stateless.cue

    It generates a file:

    1. $ cat stateless.cue
    2. stateless: {
    3. annotations: {}
    4. attributes: workload: definition: {
    5. apiVersion: "<change me> apps/v1"
    6. kind: "<change me> Deployment"
    7. }
    8. description: ""
    9. labels: {}
    10. type: "component"
    11. }
    12. template: {
    13. output: {
    14. spec: {
    15. selector: matchLabels: "app.oam.dev/component": "name"
    16. template: {
    17. metadata: labels: "app.oam.dev/component": "name"
    18. spec: containers: [{
    19. name: "name"
    20. image: "image"
    21. }]
    22. }
    23. }
    24. apiVersion: "apps/v1"
    25. kind: "Deployment"
    26. }
    27. outputs: {}
    28. parameters: {}
    29. }

    In detail:

    • .spec.workload is required to indicate the workload type of this component.
    • .spec.schematic.cue.template is a CUE template, specifically:
      • The output filed defines the template for the abstraction.
      • The parameter filed defines the template parameters, i.e. the configurable properties exposed in the Applicationabstraction (and JSON schema will be automatically generated based on them).

    Add parameters in this auto-generated custom component file :

    1. stateless: {
    2. annotations: {}
    3. attributes: workload: definition: {
    4. apiVersion: "<change me> apps/v1"
    5. kind: "<change me> Deployment"
    6. }
    7. description: ""
    8. labels: {}
    9. type: "component"
    10. }
    11. template: {
    12. output: {
    13. spec: {
    14. selector: matchLabels: "app.oam.dev/component": parameter.name
    15. template: {
    16. metadata: labels: "app.oam.dev/component": parameter.name
    17. spec: containers: [{
    18. name: parameter.name
    19. image: parameter.image
    20. }]
    21. }
    22. }
    23. apiVersion: "apps/v1"
    24. }
    25. outputs: {}
    26. parameters: {
    27. name: string
    28. }
    29. }
    1. $ vela def vet stateless.cue
    2. Validation succeed.

    Declare another component named task which is an abstraction for run-to-completion workload.

    1. vela def init task -t component -o task.cue

    It generates a file:

    1. $ cat task.cue
    2. task: {
    3. annotations: {}
    4. attributes: workload: definition: {
    5. apiVersion: "<change me> apps/v1"
    6. kind: "<change me> Deployment"
    7. }
    8. description: ""
    9. labels: {}
    10. type: "component"
    11. }
    12. template: {
    13. output: {}
    14. parameter: {}
    15. }

    Edit the generated component file:

    Apply above ComponentDefinition files to your Kubernetes cluster:

    1. $ vela def apply stateless.cue
    2. ComponentDefinition stateless created in namespace vela-system.
    3. $ vela def apply task.cue
    4. ComponentDefinition task created in namespace vela-system.

    Declare an Application

    The ComponentDefinition can be instantiated in Application abstraction as below:

    1. apiVersion: core.oam.dev/v1alpha2
    2. kind: Application
    3. metadata:
    4. name: website
    5. spec:
    6. components:
    7. - name: hello
    8. type: stateless
    9. properties:
    10. image: crccheck/hello-world
    11. name: mysvc
    12. - name: countdown
    13. type: task
    14. properties:
    15. image: centos:7
    16. cmd:
    17. - "bin/bash"
    18. - "-c"
    19. - "for i in 9 8 7 6 5 4 3 2 1 ; do echo $i ; done"

    Above application resource will generate and manage following Kubernetes resources in your target cluster based on the output in CUE template and user input in Application properties.

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. name: backend
    5. ... # skip tons of metadata info
    6. spec:
    7. template:
    8. spec:
    9. containers:
    10. - name: mysvc
    11. image: crccheck/hello-world
    12. metadata:
    13. labels:
    14. app.oam.dev/component: mysvc
    15. matchLabels:
    16. app.oam.dev/component: mysvc
    17. ---
    18. apiVersion: batch/v1
    19. kind: Job
    20. metadata:
    21. name: countdown
    22. ... # skip tons of metadata info
    23. spec:
    24. parallelism: 1
    25. completions: 1
    26. template:
    27. metadata:
    28. name: countdown
    29. spec:
    30. containers:
    31. - name: countdown
    32. image: 'centos:7'
    33. command:
    34. - bin/bash
    35. - '-c'
    36. - for i in 9 8 7 6 5 4 3 2 1 ; do echo $i ; done
    37. restartPolicy: Never

    KubeVela allows you to reference the runtime information of your application via context keyword.

    The most widely used context is application name(context.appName) component name(context.name).

    1. context: {
    2. appName: string
    3. name: string
    4. }
    1. parameter: {
    2. image: string
    3. }
    4. output: {
    5. ...
    6. spec: {
    7. containers: [{
    8. name: context.name
    9. image: parameter.image
    10. }]
    11. }
    12. ...
    13. }

    Full available information in CUE context

    Composition

    It’s common that a component definition is composed by multiple API resources, for example, a webserver component that is composed by a Deployment and a Service. CUE is a great solution to achieve this in simplified primitives.

    KubeVela requires you to define the template of workload type in output section, and leave all the other resource templates in outputs section with format as below:

    1. outputs: <unique-name>:
    2. <full template data>

    Below is the example for webserver definition:

    Apply to your Kubernetes cluster:

    1. $ vela def apply webserver.cue
    2. ComponentDefinition webserver created in namespace vela-system.

    The user could now declare an Application with it:

    1. apiVersion: core.oam.dev/v1beta1
    2. kind: Application
    3. metadata:
    4. name: webserver-demo
    5. namespace: default
    6. spec:
    7. components:
    8. - name: hello-world
    9. type: webserver
    10. properties:
    11. image: crccheck/hello-world
    12. port: 8000
    13. env:
    14. - name: "foo"
    15. value: "bar"
    16. cpu: "100m"
    1. kubectl get deployment
    1. NAME READY UP-TO-DATE AVAILABLE AGE
    2. hello-world-v1 1/1 1 1 15s
    1. kubectl get svc
    1. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

    What’s Next

    Please check the documentation about why we support CUE as first-class templating solution and more details about using CUE efficiently.