...

/

Creating a New Serverless Application Project

Creating a New Serverless Application Project

In this lesson, we will learn to create a new serverless application project.

Jenkins X does its best to be easy for everyone and not to introduce unnecessary complexity. True to that goal, there is nothing special users need to do to create a new project with serverless deployments. There is no additional command, nor are there any extra arguments. The jx edit deploy command already told Jenkins X that we want all new projects to be serverless by default, so all we have to do is create a new quick start.

Creating a new quick start project

Press + to interact
jx create quickstart \
--filter golang-http \
--project-name jx-knative \
--batch-mode

As you can see, that command was no different than any other quick start we created earlier. We needed a project with a unique name, so the only change is that this one is called jx-knative.

If you look at the output, there is nothing new there either. If someone else changed the team’s deployment kind, you wouldn’t even know that a quick start will end with the first release running in the staging environment in the serverless fashion.

Browsing to project directory

There is one difference, though, and we need to enter the project directory to find it.

Press + to interact
cd jx-knative

Inspecting the values.yaml file

Now, there is only one value that matters, and it is located in values.yaml.

Press + to interact
cat charts/jx-knative/values.yaml

The output, limited to the relevant parts, is as follows.

Press + to interact
...
# enable this flag to use knative serve to deploy the app
knativeDeploy: true
...

As you can see, the knativeDeploy variable is set to true. All the past projects, at least those created after May 2019, had that value set to false, simply because we did not have the Gloo addon installed, and our deployment setting was set to default instead of knative. But, now that we changed that, knativeDeploy will be set to true for all the new projects unless we change the deployment setting again.

Now, you might be thinking to yourself that a Helm variable does not mean much by itself unless it is used. You are right; it is only a variable, and we have yet to discover the reason for its existence.

Inspecting the templates directory

Let’s take a look at what we have in the Chart’s templates directory.

Press + to interact
ls -1 charts/jx-knative/templates

The output is as follows.

Press + to interact
NOTES.txt
_helpers.tpl
deployment.yaml
ksvc.yaml
service.yaml

We are already familiar with deployment.yaml and service.yaml files, but we might have missed a crucial detail. Let’s take a look at what’s inside one of them.

Press + to interact
cat charts/jx-knative/templates/deployment.yaml

The output, limited to the top and bottom parts, is as follows.

Press + to interact
{{- if .Values.knativeDeploy }}
{{- else }}
...
{{- end }}

We have the {{- if .Values.knativeDeploy }} instruction that immediately continues into {{- else }}, while the whole definition of the deployment is between {{- else }} and {{- end }}. While that might look strange at first, it actually means that the Deployment resource should be created only if knativeDeploy is set to false.

If you take a look at the service.yaml file, you’ll notice the same pattern. In both cases, the resources are created only if we didn’t choose to use Knative deployments. That brings us to the ksvc.yaml file.

Inspecting the ksvc.yaml file.

Press + to interact
cat charts/jx-knative/templates/ksvc.yaml

The output is as follows.

Press + to interact
{{- if .Values.knativeDeploy }}
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
{{- if .Values.service.name }}
name: {{ .Values.service.name }}
{{- else }}
name: {{ template "fullname" . }}
{{- end }}
labels:
chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
spec:
runLatest:
configuration:
revisionTemplate:
spec:
container:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- range $pkey, $pval := .Values.env }}
- name: {{ $pkey }}
value: {{ quote $pval }}
{{- end }}
livenessProbe:
httpGet:
path: {{ .Values.probePath }}
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
successThreshold: {{ .Values.livenessProbe.successThreshold }}
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
readinessProbe:
httpGet:
path: {{ .Values.probePath }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
successThreshold: {{ .Values.readinessProbe.successThreshold }}
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
resources:
{{ toYaml .Values.resources | indent 14 }}
{{- end }}

To begin with, you can see that the conditional logic is reversed. The resource defined in that file will be created only if the knativeDeploy variable is set to true.

We won’t go into details of the specification. I’ll only say that it is similar to what we’d define as a Pod specification, and leave you to explore Knative Serving API spec on your own. Where Knative definition differs significantly from what we’re used to when we work with Deployments and StatefulSets, is that we don’t need to specify many of the things. There is no need for creating a Deployment, that defines a ReplicaSet, that defines pod templates. There is no definition of a Service associated with the pods. Knative will create all the objects required to convert our Pods into a scalable solution accessible to our users.

We can think of the Knative definition as being more developer-friendly than other Kubernetes resources. It dramatically simplifies things by making some assumptions. All the Kubernetes resources we’re used to seeing like Deployment, ReplicaSet, and Service will still be created along with quite a few others. The significant difference is not only in what will be ...