A cluster template is an Ansible role that is responsible for installing and configuring an OpenShift cluster. Cluster templates are distributed in Ansible collections. A collection may contain multiple templates.
If you don't already have a collection for distributing your cluster templates, you can create a new one using the ansible-galaxy collection init command. Collection names consist of two parts, a namespace (often a company name) and a name, so if we wanted to create a new template named redhat.rhoai, we would run:
ansible-galaxy collection init redhat.rhoai
That creates a directory tree that looks like:
redhat/
└── rhoai
├── docs
├── galaxy.yml
├── meta
│ └── runtime.yml
├── plugins
│ └── README.md
├── README.md
└── roles
A cluster template role consists of at least two playbooks:
-
tasks/main.yaml-- this playbook runs with privileges on the management cluster. It is responsible for creating the cluster whencluster_template_stateispresentand for deleting the cluster whencluster_template_stateisabsent. -
tasks/post-install.yaml-- this playbook runs with privileges on the tenant cluster. It is responsible for performing any software installation and configuration tasks on the tenant cluster.
A template role also contains two metadata files:
-
meta/argument_specs.yaml-- this file describes all the parameters accepted by the role. -
meta/cloudkit.yaml-- this file contains metadata such as a friendly title and a description.
The syntax of the argument_spec.yaml file is fully documented in the Ansible documentation. Your role will need to accept a cluster_order parameter with the values from the cluster request, and a template_parameters parameter with any values required by your role (or by roles to which you call out). A basic example looks like this:
argument_specs:
main:
options:
cluster_order:
type: dict
required: true
cluster_working_namespace:
type: str
required: true
node_requests:
type: list
elements: dict
options:
numberOfNodes:
type: int
required: true
resourceClass:
type: str
required: true
choices:
- fc430
template_parameters:
type: dict
options:
pull_secret:
description: >
The pull secret contains credentials for authenticating to image repositories.
type: str
required: true
ssh_public_key:
description: >
A public ssh key that will be installed into the `authorized_keys` file
of the `core` user on cluster worker nodes.
type: strThe cloudkit.yaml file contains metadata about your template role that isn't part of the standard Ansible metadata. Here is a sample cloudkit.yaml:
# Define the display name and description of the template
title: Simple OpenShift 4.17 Cluster
description: >
This template will build a minimally configured OpenShift 4.17 cluster.
# This sets the nodeRequest field in the ClusterOrder manifest. There must be at
# least one entry in this list.
default_node_request:
- resourceClass: fc430
numberOfNodes: 2
# This declares that for a cluster built from this template, only the resource
# classes listed here may be used when requesting additional nodes. If this
# list is empty or unspecified, a ClusterOrder may request nodes from any
# available resource class.
allowed_resource_classes:
- fc430In most cases, your main.yaml will simply include roles distributed as part of the OSAC installer. A typical example would be:
- name: Create a new instance of this template
when: cluster_template_state == 'present'
ansible.builtin.import_role:
name: cloudkit.templates.ocp_4_17_small
- name: Destroy an instance of this template
when: cluster_template_state == 'absent'
ansible.builtin.import_role:
name: cloudkit.templates.ocp_4_17_small
The post-install.yaml task list runs with credentials for the tenant cluster and will typically consist of many calls to the kubernetes.core.k8s module:
- name: Create grafana namespace
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: grafana
You can leverage [Kustomize] to deploy resources by using the kubernetes.core.kustomize lookup:
- name: Install Operators
kubernetes.core.k8s:
state: present
definition: "{{ lookup('kubernetes.core.kustomize', dir = kustomize_dir ~ '/operators') }}"
validate_certs: false
There are two steps to making your collection available to the OSAC installer:
- Build a new execution environment that includes your collection.
- Configure the
cloudkit_template_collectionsvariable to include the name of your collection
-
Check out the
cloudkit-aaprepository:git clone https://github.com/innabox/cloudkit-aap && cd cloudkit-aap -
Edit
collections/requirements.ymlto include your new collection. If your collection has been published to Ansible Galaxy, you can use the fully qualified collection name:- name: redhat.rhoai version: 1.0.0If your collection is hosted in a Git repository, provide the URL to the repository:
- source: https://github.com/innabox/redhat-rhoai-collection.git type: git version: 1.0.0If you are not tagging versions in your repository, you can use a commit hash instead of a tag.
-
Build a new execution environment:
cd execution-environment ansible-builder build --tag cloudkit-aap-ee -
Publish the container image to a container registry:
podman push cloudkit-aap-ee quay.io/myusername/cloudkit-aap-ee:latest
Configure AAP to use the new image as the execution environment and to look for templates in your Ansible collection.. You will need to set the AAP_EE_IMAGE key in the config-as-code-ig Secret to the fully qualified image name. For example, if you are deploying using the installer repository, you could add the following to your kustomization.yaml:
```
secretGenerator:
- name: config-as-code-ig
options:
disableNameSuffixHash: true
literals:
- AAP_EE_IMAGE=quay.io/myname/cloudkit-aap-ee@sha256:ddc3dec0315de244c14df9d2ee11cc242a60dabd0b0b43b2c48fd1a0de2e61da
- CLOUDKIT_TEMPLATE_COLLECTIONS=cloudkit.templates,redhat.rhoai
```
Now, re-deploy the installation manifests.