Cos'è un template in OpenShift
Published: 2023-10-03 14:27:06

---
title: Cos'è un template in OpenShift
published: true
date: 2022-10-27 00:00:00 UTC
tags: 
canonical_url: 
---

Docker Compose usa il file docker-compose.yml, mentre Kubernetes usa i chart. E OpenShift?

OpenShift definisce i template, ossia dei modelli che possono essere utilizzati per descrivere lo stack di un’applicazione.

Come funziona e come scriverne uno?

# Definizione

Un _template_ descrive un insieme di oggetti che possono essere parametrizzati ed elaborati per produrre un elenco di risorse che possono essere create all’interno di un cluster OpenShift.

Un template può essere definito per creare qualsiasi oggetto tu abbia l’autorizzazione di creare all’interno di un progetto, ad esempio Service, Build e DeploymentConfigs. Un template può anche definire una serie di **etichette** -o _label_- da applicare a ogni oggetto definito nel template.

# Come crearne uno vuoto

Per creare un template _bootstrap_, puoi usare il seguente comando:

```
oc adm create-bootstrap-project-template -o yaml > template.yaml

```

Questo andrà a produrre, sfruttando l’istruzione _create-bootstrap-project-template_, un **template di base** che potrai andare a completare secondo le tue necessità.

L’output prodotto sarà simile al seguente:

```
apiVersion: template.openshift.io/v1
kind: Template
metadata:
 creationTimestamp: null
 name: project-request
objects:
 - apiVersion: project.openshift.io/v1
 kind: Project
 metadata:
 annotations:
 openshift.io/description: ${PROJECT_DESCRIPTION}
 openshift.io/display-name: ${PROJECT_DISPLAYNAME}
 openshift.io/requester: ${PROJECT_REQUESTING_USER}
 creationTimestamp: null
 name: ${PROJECT_NAME}
 spec: {}
 status: {}
 - apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
 creationTimestamp: null
 name: admin
 namespace: ${PROJECT_NAME}
 roleRef:
 apiGroup: rbac.authorization.k8s.io
 kind: ClusterRole
 name: admin
 subjects:
 - apiGroup: rbac.authorization.k8s.io
 kind: User
 name: ${PROJECT_ADMIN_USER}
parameters:
 - name: PROJECT_NAME
 - name: PROJECT_DISPLAYNAME
 - name: PROJECT_DESCRIPTION
 - name: PROJECT_ADMIN_USER
 - name: PROJECT_REQUESTING_USER

```

# Come funziona

La chiave _apiVersion_ rappresenta la versione di riferimento dell’oggetto di tipo _Template_ a cui farà riferimento il nostro oggetto, così come la proprietà _kind_.

I metadata sono le informazioni che riguardano il template stesso, come il suo nome -che possiamo modificare liberamente- e la data di creazione.

> Tieni presente che il nome del template dev’essere univoco per singolo namespace!

All’interno della chiave _objects_ andremo invece a definire tutte le **risorse che il template andrà a creare o istanziare** : DeploymentConfig, Service, ConfigMaps, Secret e tutte quelle che OpenShift e Kubernetes ci mette a disposizione.

Queste andranno definite come oggetti singoli che fanno parte della lista di _objects_, quindi ognuno di essi avrà un <ins>trattino che separa la definizione di una risorsa dall’altra</ins>.

In questo caso, il template va a definire un oggetto di tipo _Project_, quindi un vero e proprio namespace, con le relative informazioni: il nome univoco da associare (ossia _name_), il nome mostrato sulla console (ovvero_metadata>annotations>openshift.io/display-name_) e anche una descrizione (sempre all’interno di_metadata>annotations_).

> Il nome è l’unico parametro obbligatorio.

Oltre al progetto, viene definito il RoleBinding che permette di associare l’utente al progetto; qui notiamo che, così come nella sezione precedente, ci sono alcune espressioni tra parentesi graffe.

> ${PLACEHOLDER} rappresenta il modo in cui possiamo parametrizzare dei campi nel template e valorizzarli solo in fase di creazione dell’istanza del template.

Se osserviamo bene, come proprietà _sibling_ di _objects_ abbiamo _parameters_: questo oggetto permette la definizione dei parametri che possono essere valorizzati quando il template viene processato.

Mentre le proprietà che abbiamo elencato finora, come _apiVersion_ e _objects_ sono obbligatorie, i parametri non lo sono: è possibile scrivere un template con all’interno tutti i campi già valorizzati. <ins>Questo è solitamente
sconsigliato perché il template dovrebbe rappresentare un modello astratto e configurabile</ins> a seconda delle necessità, piuttosto che un oggetto.

# Creare le risorse

Per poter creare le risorse contenute in un template, sarà sufficiente eseguire un comando come il seguente:

```
$ oc process -f my-template.yml -p PROJECT_NAME=my-namespace -p PROJECT_DISPLAYNAME="My Project" ...

```

Ogni parametro presente nel template potrà essere valorizzato usando l’opzione _-p_. Tuttavia, il comando _oc process_ci andrà a restituire il template con i parametri aggiornati grazie ai valori passati in input, ma non andrà a creare le risorse al suo interno.

Questo perché _oc process_ prende il template e i parametri come input e lo processa, ma non lo esegue.

Per farlo, useremo _oc apply_:

```
$ oc process -f my-template.yml -p PROJECT_NAME=my-namespace -p PROJECT_DISPLAYNAME="My Project" ... oc apply -f -

```

> _oc apply_ andrà a sovrascrivere le risorse da creare a quelle esistenti, eventualmente apportando modifiche o aggiornamenti esistenti in questa versione. Per creare da zero, usare _oc create_.

# Tip

Includere un’etichetta chiamata _label_ in tutti gli oggetti che vengono creati a partire da quel template è una delle _best practice_.

L’aggiunta di un’etichetta comune a tutti gli oggetti creati da un template consente agli utenti e agli amministratori di tenere traccia degli oggetti creati da un determinato template come un gruppo di risorse dipendenti.

Ad esempio, è sufficiente aggiungere una label come _template=my-app-template_.

Inoltre, includere un’etichetta _app_ in tutti gli oggetti fornisce un’etichetta dinamica che può essere utilizzata per eseguire query su un’istanza specifica di un template e che può valorizzata usando un parametro come _${APPLICATION\_NAME}_.