---
menu:
  workshop:
    parent: Additional Resources
title: Imperative Framework
weight: 101
---

:toc:
include::modules/comm-attributes.adoc[]

[#versus]
== Imperative vs. Declarative Actions

What's the difference between Imperative and Declarative actions?

Declarative is when we **describe** what we want in our clusters, and we let the GitOps controller reconcile the difference between what's in Git and what's in the cluster.

Imperative is where we take action on the cluster. A simplified way of thinking about this is all of the actions done by hand (e.g. `oc apply -f`, `kubectl`)


During the development of the imperative framework there as a realization that there was a generalized need to support a limited mechanism for running these imperative actions in the most declarative way possible.

We needed an automated, self-contained and supportable mechanism to interact with elements of OpenShift that could not be predicted prior to installation.

Some examples of when this is necessary:

* The management of secrets across clusters - the need to make clusters mutually trust each others' Certificate Authorities and transfer of tokens/credentials


[#declaring]
== Defining an imperative action

NOTE: The following code snippet is from the `values-hub.yaml` in the multicloud-gitops pattern

[source,yaml]
----
  imperative:
    # The default schedule is every 10 minutes: imperative.schedule
    # Total timeout of all jobs is 1h: imperative.activeDeadlineSeconds
    # imagePullPolicy is set to always: imperative.imagePullPolicy
    jobs:
      - name: hello-world
        # ansible playbook to be run
        playbook: common/ansible/playbooks/hello-world/hello-world.yaml
        # per playbook timeout in seconds
        timeout: 234
        # verbosity: "-v"
----


When the pattern is deployed a cronJob is created in the `imperative` namespace. By default it is set to run `every 10 minutes`.

The cronJob (see below) has been parameterized so we can change the intervals and define our imperative playbooks.

[#cron-example]

[source,yaml]
----
apiVersion: batch/v1
kind: CronJob
metadata:
  name: {{ $.Values.clusterGroup.imperative.cronJobName }}
  namespace: {{ $.Values.clusterGroup.imperative.namespace}}
spec:
  schedule: {{ $.Values.clusterGroup.imperative.schedule | quote }}
  # if previous Job is still running, skip execution of a new Job
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      activeDeadlineSeconds: {{ $.Values.clusterGroup.imperative.activeDeadlineSeconds }}
      template:
        metadata:
          name: {{ $.Values.clusterGroup.imperative.jobName }}
----
