Specification

Resources

Provisioner

Route


score.yaml (view on GitHub) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload
containers:
  my-container:
    image: ghcr.io/stefanprodan/podinfo:latest
    variables:
      PODINFO_UI_MESSAGE: "Hello, ${resources.dns.host}!"
resources:
  dns:
    type: dns
  route:
    type: route
    params:
      host: ${resources.dns.host}
      path: /
      port: 8080
service:
  ports:
    tcp:
      port: 8080
      targetPort: 9898

Initialize your local workspace, by importing a specific community provisioner:

score-commpose init --provisioners REPLACE-ME-WITH-ACTUAL-PROVISIONER-FILE-URL.yaml

Note: you need to replace REPLACE-ME-WITH-ACTUAL-PROVISIONER-FILE-URL.yaml by the actual provisioner file you want to use and import. More information here.

Get the provisioners definition:

score-compose provisioners list

Generate the platform specific manifests:

score-commpose generate score.yaml

See the resource outputs:

score-commpose resources list

You can run the following command on each resource listed with the previous command to get their outputs:

score-commpose resources get-outputs

Deploy the generated manifests:

docker compose up -d

See the running containers:

docker ps


10-ingress-route.provisioners.yaml (view on GitHub) :

- uri: template://community-provisioners/ingress-route
  type: route
  description: Provisions an Ingress route on a shared nginx instance.
  supported_params:
    - path
    - host
    - port
  init: |
    {{ if not (regexMatch "^/|(/([^/]+))+$" .Params.path) }}{{ fail "params.path start with a / but cannot end with /" }}{{ end }}
    {{ if not (regexMatch "^[a-z0-9_.-]{1,253}$" .Params.host) }}{{ fail (cat "params.host must be a valid hostname but was" .Params.host) }}{{ end }}
    {{ $ports := (index .WorkloadServices .SourceWorkload).Ports }}
    {{ if not $ports }}{{ fail "no service ports exist" }}{{ end }}
    {{ $port := index $ports (print .Params.port) }}
    {{ if not $port.TargetPort }}{{ fail "params.port is not a named service port" }}{{ end }}    
  state: |
    routeName: route-{{ .SourceWorkload }}-{{ substr 0 8 .Guid | lower }}    
  manifests: |
    - apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: {{ .State.routeName }}
        {{ if ne .Namespace "" }}
        namespace: {{ .Namespace }}
        {{ end }}
      spec:
        ingressClassName: nginx
        rules:
          - host: {{ .Params.host | quote }}
            http:
              paths:
                - path: {{ .Params.path | quote }}
                  pathType: Prefix
                  backend:
                    service:
                      name: {{ (index .WorkloadServices .SourceWorkload).ServiceName }}
                      port:
                        number: {{ .Params.port }}    

10-ingress-with-netpol-route.provisioners.yaml (view on GitHub) :

- uri: template://community-provisioners/ingress-with-net-pol-route
  type: route
  description: Provisions an Ingress route on a shared nginx instance, and a NetworkPolicy between them.
  supported_params:
    - path
    - host
    - port
  init: |
    {{ if not (regexMatch "^/|(/([^/]+))+$" .Params.path) }}{{ fail "params.path start with a / but cannot end with /" }}{{ end }}
    {{ if not (regexMatch "^[a-z0-9_.-]{1,253}$" .Params.host) }}{{ fail (cat "params.host must be a valid hostname but was" .Params.host) }}{{ end }}
    {{ $ports := (index .WorkloadServices .SourceWorkload).Ports }}
    {{ if not $ports }}{{ fail "no service ports exist" }}{{ end }}
    {{ $port := index $ports (print .Params.port) }}
    {{ if not $port.TargetPort }}{{ fail "params.port is not a named service port" }}{{ end }}
    targetPort: {{ $port.TargetPort }}    
  state: |
    routeName: route-{{ .SourceWorkload }}-{{ substr 0 8 .Guid | lower }}    
  manifests: |
    - apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: {{ .State.routeName }}
        {{ if ne .Namespace "" }}
        namespace: {{ .Namespace }}
        {{ end }}
      spec:
        ingressClassName: nginx
        rules:
          - host: {{ .Params.host | quote }}
            http:
              paths:
                - path: {{ .Params.path | quote }}
                  pathType: Prefix
                  backend:
                    service:
                      name: {{ (index .WorkloadServices .SourceWorkload).ServiceName }}
                      port:
                        number: {{ .Params.port }}
    - apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: ingress-to-{{ .SourceWorkload }}
        {{ if ne .Namespace "" }}
        namespace: {{ .Namespace }}
        {{ end }}
      spec:
        podSelector:
          matchLabels:
            app.kubernetes.io/name: {{ .SourceWorkload }}
        policyTypes:
          - Ingress
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: ingress-nginx
            podSelector:
              matchLabels:
                app.kubernetes.io/name: ingress-nginx
          ports:
          - protocol: TCP
            port: {{ .Init.targetPort }}    

10-shared-gateway-httproute-with-netpol.provisioners.yaml (view on GitHub) :

- uri: template://community-provisioners/route-with-shared-gateway-with-netpol
  type: route
  description: Generates an HTTPRoute attached to a default Gateway in default Namespace, and a NetworkPolicy between them.
  supported_params:
    - path
    - host
    - port
  init: |
    {{ if not (regexMatch "^/|(/([^/]+))+$" .Params.path) }}{{ fail "params.path start with a / but cannot end with /" }}{{ end }}
    {{ if not (regexMatch "^[a-z0-9_.-]{1,253}$" .Params.host) }}{{ fail (cat "params.host must be a valid hostname but was" .Params.host) }}{{ end }}
    {{ $ports := (index .WorkloadServices .SourceWorkload).Ports }}
    {{ if not $ports }}{{ fail "no service ports exist" }}{{ end }}
    {{ $port := index $ports (print .Params.port) }}
    {{ if not $port.TargetPort }}{{ fail "params.port is not a named service port" }}{{ end }}
    targetPort: {{ $port.TargetPort }}
    gatewayNamespace: default
    gatewayName: default    
  state: |
    routeName: route-{{ .SourceWorkload }}-{{ substr 0 8 .Guid | lower }}    
  manifests: |
    - apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: {{ .State.routeName }}
        annotations:
          k8s.score.dev/source-workload: {{ .SourceWorkload }}
          k8s.score.dev/resource-uid: {{ .Uid }}
          k8s.score.dev/resource-guid: {{ .Guid }}
        labels:
          app.kubernetes.io/managed-by: score-k8s
          app.kubernetes.io/name: {{ .State.routeName }}
          app.kubernetes.io/instance: {{ .State.routeName }}
      spec:
        parentRefs:
        - name: {{ .Init.gatewayName }}
          namespace: {{ .Init.gatewayNamespace }}
        hostnames:
        - {{ .Params.host | quote }}
        rules:
        - matches:
          - path:
              type: PathPrefix
              value: {{ .Params.path | quote }}
          backendRefs:
          - name: {{ (index .WorkloadServices .SourceWorkload).ServiceName }}
            port: {{ .Params.port }}
    - apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: gateway-to-{{ .SourceWorkload }}
      spec:
        podSelector:
          matchLabels:
            app.kubernetes.io/name: {{ .SourceWorkload }}
        policyTypes:
          - Ingress
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: nginx-gateway
            podSelector:
              matchLabels:
                app.kubernetes.io/name: nginx-gateway-fabric
          ports:
          - protocol: TCP
            port: {{ .Init.targetPort }}    

10-shared-gateway-httproute.provisioners.yaml (view on GitHub) :

- uri: template://community-provisioners/route-with-shared-gateway
  type: route
  description: Generates an HTTPRoute attached to a default Gateway in default Namespace.
  supported_params:
    - path
    - host
    - port
  init: |
    {{ if not (regexMatch "^/|(/([^/]+))+$" .Params.path) }}{{ fail "params.path start with a / but cannot end with /" }}{{ end }}
    {{ if not (regexMatch "^[a-z0-9_.-]{1,253}$" .Params.host) }}{{ fail (cat "params.host must be a valid hostname but was" .Params.host) }}{{ end }}
    {{ $ports := (index .WorkloadServices .SourceWorkload).Ports }}
    {{ if not $ports }}{{ fail "no service ports exist" }}{{ end }}
    {{ $port := index $ports (print .Params.port) }}
    {{ if not $port.TargetPort }}{{ fail "params.port is not a named service port" }}{{ end }}
    gatewayNamespace: default
    gatewayName: default    
  state: |
    routeName: route-{{ .SourceWorkload }}-{{ substr 0 8 .Guid | lower }}    
  manifests: |
    - apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: {{ .State.routeName }}
        {{ if ne .Namespace "" }}
        namespace: {{ .Namespace }}
        {{ end }}
        annotations:
          k8s.score.dev/source-workload: {{ .SourceWorkload }}
          k8s.score.dev/resource-uid: {{ .Uid }}
          k8s.score.dev/resource-guid: {{ .Guid }}
        labels:
          app.kubernetes.io/managed-by: score-k8s
          app.kubernetes.io/name: {{ .State.routeName }}
          app.kubernetes.io/instance: {{ .State.routeName }}
      spec:
        parentRefs:
        - name: {{ .Init.gatewayName }}
          namespace: {{ .Init.gatewayNamespace }}
        hostnames:
        - {{ .Params.host | quote }}
        rules:
        - matches:
          - path:
              type: PathPrefix
              value: {{ .Params.path | quote }}
          backendRefs:
          - name: {{ (index .WorkloadServices .SourceWorkload).ServiceName }}
            port: {{ .Params.port }}    

Initialize your local workspace, by importing a specific community provisioner:

score-k8s init --provisioners REPLACE-ME-WITH-ACTUAL-PROVISIONER-FILE-URL.yaml

Note: you need to replace REPLACE-ME-WITH-ACTUAL-PROVISIONER-FILE-URL.yaml by the actual provisioner file you want to use and import. More information here.

Get the provisioners definition:

score-k8s provisioners list

Generate the platform specific manifests:

score-k8s generate score.yaml

See the resource outputs:

score-k8s resources list

You can run the following command on each resource listed with the previous command to get their outputs:

score-k8s resources get-outputs

Deploy the generated manifests:

kubectl apply -f manifests.yaml

See the running containers:

kubectl get all