From c0f63fb902b53bc592e6862d5876af9b244ee82b Mon Sep 17 00:00:00 2001
From: Tim Bielawa <tbielawa@redhat.com>
Date: Thu, 5 Oct 2017 15:42:18 -0400
Subject: Rename openshift_cfme role to openshift_management

---
 .../templates/cloudforms/cfme-backup-job.yaml      |  28 +
 .../templates/cloudforms/cfme-backup-pvc.yaml      |  10 +
 .../cloudforms/cfme-pv-backup-example.yaml         |  13 +
 .../templates/cloudforms/cfme-pv-db-example.yaml   |  38 +
 .../cloudforms/cfme-pv-server-example.yaml         |  38 +
 .../templates/cloudforms/cfme-restore-job.yaml     |  35 +
 .../templates/cloudforms/cfme-scc-sysadmin.yaml    |  38 +
 .../templates/cloudforms/cfme-template-ext-db.yaml | 763 +++++++++++++++++
 .../files/templates/cloudforms/cfme-template.yaml  | 940 ++++++++++++++++++++
 .../files/templates/manageiq/miq-backup-job.yaml   |  28 +
 .../files/templates/manageiq/miq-backup-pvc.yaml   |  10 +
 .../templates/manageiq/miq-pv-backup-example.yaml  |  13 +
 .../templates/manageiq/miq-pv-db-example.yaml      |  38 +
 .../templates/manageiq/miq-pv-server-example.yaml  |  38 +
 .../files/templates/manageiq/miq-restore-job.yaml  |  35 +
 .../templates/manageiq/miq-template-ext-db.yaml    | 771 +++++++++++++++++
 .../files/templates/manageiq/miq-template.yaml     | 948 +++++++++++++++++++++
 17 files changed, 3784 insertions(+)
 create mode 100644 roles/openshift_management/files/templates/cloudforms/cfme-backup-job.yaml
 create mode 100644 roles/openshift_management/files/templates/cloudforms/cfme-backup-pvc.yaml
 create mode 100644 roles/openshift_management/files/templates/cloudforms/cfme-pv-backup-example.yaml
 create mode 100644 roles/openshift_management/files/templates/cloudforms/cfme-pv-db-example.yaml
 create mode 100644 roles/openshift_management/files/templates/cloudforms/cfme-pv-server-example.yaml
 create mode 100644 roles/openshift_management/files/templates/cloudforms/cfme-restore-job.yaml
 create mode 100644 roles/openshift_management/files/templates/cloudforms/cfme-scc-sysadmin.yaml
 create mode 100644 roles/openshift_management/files/templates/cloudforms/cfme-template-ext-db.yaml
 create mode 100644 roles/openshift_management/files/templates/cloudforms/cfme-template.yaml
 create mode 100644 roles/openshift_management/files/templates/manageiq/miq-backup-job.yaml
 create mode 100644 roles/openshift_management/files/templates/manageiq/miq-backup-pvc.yaml
 create mode 100644 roles/openshift_management/files/templates/manageiq/miq-pv-backup-example.yaml
 create mode 100644 roles/openshift_management/files/templates/manageiq/miq-pv-db-example.yaml
 create mode 100644 roles/openshift_management/files/templates/manageiq/miq-pv-server-example.yaml
 create mode 100644 roles/openshift_management/files/templates/manageiq/miq-restore-job.yaml
 create mode 100644 roles/openshift_management/files/templates/manageiq/miq-template-ext-db.yaml
 create mode 100644 roles/openshift_management/files/templates/manageiq/miq-template.yaml

(limited to 'roles/openshift_management/files')

diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-backup-job.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-backup-job.yaml
new file mode 100644
index 000000000..c3bc1d20c
--- /dev/null
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-backup-job.yaml
@@ -0,0 +1,28 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: cloudforms-backup
+spec:
+  template:
+    metadata:
+      name: cloudforms-backup
+    spec:
+      containers:
+      - name: postgresql
+        image: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-postgresql:latest
+        command:
+        - "/opt/rh/cfme-container-scripts/backup_db"
+        env:
+        - name: DATABASE_URL
+          valueFrom:
+            secretKeyRef:
+              name: cloudforms-secrets
+              key: database-url
+        volumeMounts:
+        - name: cfme-backup-vol
+          mountPath: "/backups"
+      volumes:
+      - name: cfme-backup-vol
+        persistentVolumeClaim:
+          claimName: cloudforms-backup
+      restartPolicy: Never
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-backup-pvc.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-backup-pvc.yaml
new file mode 100644
index 000000000..92598ce82
--- /dev/null
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-backup-pvc.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: cloudforms-backup
+spec:
+  accessModes:
+  - ReadWriteOnce
+  resources:
+    requests:
+      storage: 15Gi
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-pv-backup-example.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-pv-backup-example.yaml
new file mode 100644
index 000000000..4fe349897
--- /dev/null
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-pv-backup-example.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+  name: cfme-pv03
+spec:
+  capacity:
+    storage: 15Gi
+  accessModes:
+  - ReadWriteOnce
+  nfs:
+    path: "/exports/cfme-pv03"
+    server: "<your-nfs-host-here>"
+  persistentVolumeReclaimPolicy: Retain
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-pv-db-example.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-pv-db-example.yaml
new file mode 100644
index 000000000..0cdd821b5
--- /dev/null
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-pv-db-example.yaml
@@ -0,0 +1,38 @@
+apiVersion: v1
+kind: Template
+labels:
+  template: cloudforms-db-pv
+metadata:
+  name: cloudforms-db-pv
+  annotations:
+    description: PV Template for CFME PostgreSQL DB
+    tags: PVS, CFME
+objects:
+- apiVersion: v1
+  kind: PersistentVolume
+  metadata:
+    name: cfme-db
+  spec:
+    capacity:
+      storage: "${PV_SIZE}"
+    accessModes:
+    - ReadWriteOnce
+    nfs:
+      path: "${BASE_PATH}/cfme-db"
+      server: "${NFS_HOST}"
+    persistentVolumeReclaimPolicy: Retain
+parameters:
+- name: PV_SIZE
+  displayName: PV Size for DB
+  required: true
+  description: The size of the CFME DB PV given in Gi
+  value: 15Gi
+- name: BASE_PATH
+  displayName: Exports Directory Base Path
+  required: true
+  description: The parent directory of your NFS exports
+  value: "/exports"
+- name: NFS_HOST
+  displayName: NFS Server Hostname
+  required: true
+  description: The hostname or IP address of the NFS server
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-pv-server-example.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-pv-server-example.yaml
new file mode 100644
index 000000000..527090ae8
--- /dev/null
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-pv-server-example.yaml
@@ -0,0 +1,38 @@
+apiVersion: v1
+kind: Template
+labels:
+  template: cloudforms-app-pv
+metadata:
+  name: cloudforms-app-pv
+  annotations:
+    description: PV Template for CFME Server
+    tags: PVS, CFME
+objects:
+- apiVersion: v1
+  kind: PersistentVolume
+  metadata:
+    name: cfme-app
+  spec:
+    capacity:
+      storage: "${PV_SIZE}"
+    accessModes:
+    - ReadWriteOnce
+    nfs:
+      path: "${BASE_PATH}/cfme-app"
+      server: "${NFS_HOST}"
+    persistentVolumeReclaimPolicy: Retain
+parameters:
+- name: PV_SIZE
+  displayName: PV Size for App
+  required: true
+  description: The size of the CFME APP PV given in Gi
+  value: 5Gi
+- name: BASE_PATH
+  displayName: Exports Directory Base Path
+  required: true
+  description: The parent directory of your NFS exports
+  value: "/exports"
+- name: NFS_HOST
+  displayName: NFS Server Hostname
+  required: true
+  description: The hostname or IP address of the NFS server
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-restore-job.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-restore-job.yaml
new file mode 100644
index 000000000..8b23f8a33
--- /dev/null
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-restore-job.yaml
@@ -0,0 +1,35 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: cloudforms-restore
+spec:
+  template:
+    metadata:
+      name: cloudforms-restore
+    spec:
+      containers:
+      - name: postgresql
+        image: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-postgresql:latest
+        command:
+        - "/opt/rh/cfme-container-scripts/restore_db"
+        env:
+        - name: DATABASE_URL
+          valueFrom:
+            secretKeyRef:
+              name: cloudforms-secrets
+              key: database-url
+        - name: BACKUP_VERSION
+          value: latest
+        volumeMounts:
+        - name: cfme-backup-vol
+          mountPath: "/backups"
+        - name: cfme-prod-vol
+          mountPath: "/restore"
+      volumes:
+      - name: cfme-backup-vol
+        persistentVolumeClaim:
+          claimName: cloudforms-backup
+      - name: cfme-prod-vol
+        persistentVolumeClaim:
+          claimName: cloudforms-postgresql
+      restartPolicy: Never
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-scc-sysadmin.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-scc-sysadmin.yaml
new file mode 100644
index 000000000..d2ece9298
--- /dev/null
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-scc-sysadmin.yaml
@@ -0,0 +1,38 @@
+allowHostDirVolumePlugin: false
+allowHostIPC: false
+allowHostNetwork: false
+allowHostPID: false
+allowHostPorts: false
+allowPrivilegedContainer: false
+allowedCapabilities:
+apiVersion: v1
+defaultAddCapabilities:
+- SYS_ADMIN
+fsGroup:
+  type: RunAsAny
+groups:
+- system:cluster-admins
+kind: SecurityContextConstraints
+metadata:
+  annotations:
+    kubernetes.io/description: cfme-sysadmin provides all features of the anyuid SCC but allows users to have SYS_ADMIN capabilities. This is the required scc for Pods requiring to run with systemd and the message bus.
+  creationTimestamp:
+  name: cfme-sysadmin
+priority: 10
+readOnlyRootFilesystem: false
+requiredDropCapabilities:
+- MKNOD
+- SYS_CHROOT
+runAsUser:
+  type: RunAsAny
+seLinuxContext:
+  type: MustRunAs
+supplementalGroups:
+  type: RunAsAny
+users:
+volumes:
+- configMap
+- downwardAPI
+- emptyDir
+- persistentVolumeClaim
+- secret
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-template-ext-db.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-template-ext-db.yaml
new file mode 100644
index 000000000..4a04f3372
--- /dev/null
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-template-ext-db.yaml
@@ -0,0 +1,763 @@
+apiVersion: v1
+kind: Template
+labels:
+  template: cloudforms-ext-db
+metadata:
+  name: cloudforms-ext-db
+  annotations:
+    description: CloudForms appliance with persistent storage using a external DB host
+    tags: instant-app,cloudforms,cfme
+    iconClass: icon-rails
+objects:
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: cfme-orchestrator
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: cfme-anyuid
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: cfme-privileged
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: cfme-httpd
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    name: "${NAME}-secrets"
+  stringData:
+    pg-password: "${DATABASE_PASSWORD}"
+    database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
+    v2-key: "${V2_KEY}"
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    name: "${ANSIBLE_SERVICE_NAME}-secrets"
+  stringData:
+    rabbit-password: "${ANSIBLE_RABBITMQ_PASSWORD}"
+    secret-key: "${ANSIBLE_SECRET_KEY}"
+    admin-password: "${ANSIBLE_ADMIN_PASSWORD}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Exposes and load balances CloudForms pods
+      service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"},{"name":"${MEMCACHED_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+    name: "${NAME}"
+  spec:
+    clusterIP: None
+    ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 80
+    selector:
+      name: "${NAME}"
+- apiVersion: v1
+  kind: Route
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+  spec:
+    host: "${APPLICATION_DOMAIN}"
+    port:
+      targetPort: http
+    tls:
+      termination: edge
+      insecureEdgeTerminationPolicy: Redirect
+    to:
+      kind: Service
+      name: "${HTTPD_SERVICE_NAME}"
+- apiVersion: apps/v1beta1
+  kind: StatefulSet
+  metadata:
+    name: "${NAME}"
+    annotations:
+      description: Defines how to deploy the CloudForms appliance
+  spec:
+    serviceName: "${NAME}"
+    replicas: "${APPLICATION_REPLICA_COUNT}"
+    template:
+      metadata:
+        labels:
+          name: "${NAME}"
+        name: "${NAME}"
+      spec:
+        containers:
+        - name: cloudforms
+          image: "${FRONTEND_APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
+          livenessProbe:
+            tcpSocket:
+              port: 80
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          readinessProbe:
+            httpGet:
+              path: "/"
+              port: 80
+              scheme: HTTP
+            initialDelaySeconds: 200
+            timeoutSeconds: 3
+          ports:
+          - containerPort: 80
+            protocol: TCP
+          volumeMounts:
+          - name: "${NAME}-server"
+            mountPath: "/persistent"
+          env:
+          - name: MY_POD_NAMESPACE
+            valueFrom:
+              fieldRef:
+                fieldPath: metadata.namespace
+          - name: APPLICATION_INIT_DELAY
+            value: "${APPLICATION_INIT_DELAY}"
+          - name: DATABASE_REGION
+            value: "${DATABASE_REGION}"
+          - name: DATABASE_URL
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: database-url
+          - name: V2_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: v2-key
+          - name: ANSIBLE_ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          resources:
+            requests:
+              memory: "${APPLICATION_MEM_REQ}"
+              cpu: "${APPLICATION_CPU_REQ}"
+            limits:
+              memory: "${APPLICATION_MEM_LIMIT}"
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                - "/opt/rh/cfme-container-scripts/sync-pv-data"
+        serviceAccount: cfme-orchestrator
+        serviceAccountName: cfme-orchestrator
+        terminationGracePeriodSeconds: 90
+    volumeClaimTemplates:
+    - metadata:
+        name: "${NAME}-server"
+        annotations:
+      spec:
+        accessModes:
+        - ReadWriteOnce
+        resources:
+          requests:
+            storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Headless service for CloudForms backend pods
+    name: "${NAME}-backend"
+  spec:
+    clusterIP: None
+    selector:
+      name: "${NAME}-backend"
+- apiVersion: apps/v1beta1
+  kind: StatefulSet
+  metadata:
+    name: "${NAME}-backend"
+    annotations:
+      description: Defines how to deploy the CloudForms appliance
+  spec:
+    serviceName: "${NAME}-backend"
+    replicas: 0
+    template:
+      metadata:
+        labels:
+          name: "${NAME}-backend"
+        name: "${NAME}-backend"
+      spec:
+        containers:
+        - name: cloudforms
+          image: "${BACKEND_APPLICATION_IMG_NAME}:${BACKEND_APPLICATION_IMG_TAG}"
+          livenessProbe:
+            exec:
+              command:
+              - pidof
+              - MIQ Server
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          volumeMounts:
+          - name: "${NAME}-server"
+            mountPath: "/persistent"
+          env:
+          - name: APPLICATION_INIT_DELAY
+            value: "${APPLICATION_INIT_DELAY}"
+          - name: DATABASE_URL
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: database-url
+          - name: MIQ_SERVER_DEFAULT_ROLES
+            value: database_operations,event,reporting,scheduler,smartstate,ems_operations,ems_inventory,automate
+          - name: FRONTEND_SERVICE_NAME
+            value: "${NAME}"
+          - name: V2_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: v2-key
+          - name: ANSIBLE_ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          resources:
+            requests:
+              memory: "${APPLICATION_MEM_REQ}"
+              cpu: "${APPLICATION_CPU_REQ}"
+            limits:
+              memory: "${APPLICATION_MEM_LIMIT}"
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                - "/opt/rh/cfme-container-scripts/sync-pv-data"
+        serviceAccount: cfme-orchestrator
+        serviceAccountName: cfme-orchestrator
+        terminationGracePeriodSeconds: 90
+    volumeClaimTemplates:
+    - metadata:
+        name: "${NAME}-server"
+        annotations:
+      spec:
+        accessModes:
+        - ReadWriteOnce
+        resources:
+          requests:
+            storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${MEMCACHED_SERVICE_NAME}"
+    annotations:
+      description: Exposes the memcached server
+  spec:
+    ports:
+    - name: memcached
+      port: 11211
+      targetPort: 11211
+    selector:
+      name: "${MEMCACHED_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${MEMCACHED_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy memcached
+  spec:
+    strategy:
+      type: Recreate
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${MEMCACHED_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${MEMCACHED_SERVICE_NAME}"
+        labels:
+          name: "${MEMCACHED_SERVICE_NAME}"
+      spec:
+        volumes: []
+        containers:
+        - name: memcached
+          image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
+          ports:
+          - containerPort: 11211
+          readinessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 5
+            tcpSocket:
+              port: 11211
+          livenessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 30
+            tcpSocket:
+              port: 11211
+          volumeMounts: []
+          env:
+          - name: MEMCACHED_MAX_MEMORY
+            value: "${MEMCACHED_MAX_MEMORY}"
+          - name: MEMCACHED_MAX_CONNECTIONS
+            value: "${MEMCACHED_MAX_CONNECTIONS}"
+          - name: MEMCACHED_SLAB_PAGE_SIZE
+            value: "${MEMCACHED_SLAB_PAGE_SIZE}"
+          resources:
+            requests:
+              memory: "${MEMCACHED_MEM_REQ}"
+              cpu: "${MEMCACHED_CPU_REQ}"
+            limits:
+              memory: "${MEMCACHED_MEM_LIMIT}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}"
+    annotations:
+      description: Remote database service
+  spec:
+    ports:
+    - name: postgresql
+      port: 5432
+      targetPort: "${{DATABASE_PORT}}"
+    selector: {}
+- apiVersion: v1
+  kind: Endpoints
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}"
+  subsets:
+  - addresses:
+    - ip: "${DATABASE_IP}"
+    ports:
+    - port: "${{DATABASE_PORT}}"
+      name: postgresql
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Exposes and load balances Ansible pods
+      service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+    name: "${ANSIBLE_SERVICE_NAME}"
+  spec:
+    ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 80
+    - name: https
+      port: 443
+      protocol: TCP
+      targetPort: 443
+    selector:
+      name: "${ANSIBLE_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${ANSIBLE_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy the Ansible appliance
+  spec:
+    strategy:
+      type: Recreate
+    serviceName: "${ANSIBLE_SERVICE_NAME}"
+    replicas: 0
+    template:
+      metadata:
+        labels:
+          name: "${ANSIBLE_SERVICE_NAME}"
+        name: "${ANSIBLE_SERVICE_NAME}"
+      spec:
+        containers:
+        - name: ansible
+          image: "${ANSIBLE_IMG_NAME}:${ANSIBLE_IMG_TAG}"
+          livenessProbe:
+            tcpSocket:
+              port: 443
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          readinessProbe:
+            httpGet:
+              path: "/"
+              port: 443
+              scheme: HTTPS
+            initialDelaySeconds: 200
+            timeoutSeconds: 3
+          ports:
+          - containerPort: 80
+            protocol: TCP
+          - containerPort: 443
+            protocol: TCP
+          securityContext:
+            privileged: true
+          env:
+          - name: ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          - name: RABBITMQ_USER_NAME
+            value: "${ANSIBLE_RABBITMQ_USER_NAME}"
+          - name: RABBITMQ_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: rabbit-password
+          - name: ANSIBLE_SECRET_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: secret-key
+          - name: DATABASE_SERVICE_NAME
+            value: "${DATABASE_SERVICE_NAME}"
+          - name: POSTGRESQL_USER
+            value: "${DATABASE_USER}"
+          - name: POSTGRESQL_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: pg-password
+          - name: POSTGRESQL_DATABASE
+            value: "${ANSIBLE_DATABASE_NAME}"
+          resources:
+            requests:
+              memory: "${ANSIBLE_MEM_REQ}"
+              cpu: "${ANSIBLE_CPU_REQ}"
+            limits:
+              memory: "${ANSIBLE_MEM_LIMIT}"
+        serviceAccount: cfme-privileged
+        serviceAccountName: cfme-privileged
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}-configs"
+  data:
+    application.conf: |
+      # Timeout: The number of seconds before receives and sends time out.
+      Timeout 120
+
+      RewriteEngine On
+      Options SymLinksIfOwnerMatch
+
+      <VirtualHost *:80>
+        KeepAlive on
+        ProxyPreserveHost on
+        ProxyPass        /ws/ ws://${NAME}/ws/
+        ProxyPassReverse /ws/ ws://${NAME}/ws/
+        ProxyPass        / http://${NAME}/
+        ProxyPassReverse / http://${NAME}/
+      </VirtualHost>
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}-auth-configs"
+  data:
+    auth-type: internal
+    auth-configuration.conf: |
+      # External Authentication Configuration File
+      #
+      # For details on usage please see https://github.com/ManageIQ/manageiq-pods/blob/master/README.md#configuring-external-authentication
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+    annotations:
+      description: Exposes the httpd server
+      service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+  spec:
+    ports:
+    - name: http
+      port: 80
+      targetPort: 80
+    selector:
+      name: httpd
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy httpd
+  spec:
+    strategy:
+      type: Recreate
+      recreateParams:
+        timeoutSeconds: 1200
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${HTTPD_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${HTTPD_SERVICE_NAME}"
+        labels:
+          name: "${HTTPD_SERVICE_NAME}"
+      spec:
+        volumes:
+        - name: httpd-config
+          configMap:
+            name: "${HTTPD_SERVICE_NAME}-configs"
+        - name: httpd-auth-config
+          configMap:
+            name: "${HTTPD_SERVICE_NAME}-auth-configs"
+        containers:
+        - name: httpd
+          image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
+          ports:
+          - containerPort: 80
+          livenessProbe:
+            exec:
+              command:
+              - pidof
+              - httpd
+            initialDelaySeconds: 15
+            timeoutSeconds: 3
+          readinessProbe:
+            tcpSocket:
+              port: 80
+            initialDelaySeconds: 10
+            timeoutSeconds: 3
+          volumeMounts:
+          - name: httpd-config
+            mountPath: "${HTTPD_CONFIG_DIR}"
+          - name: httpd-auth-config
+            mountPath: "${HTTPD_AUTH_CONFIG_DIR}"
+          resources:
+            requests:
+              memory: "${HTTPD_MEM_REQ}"
+              cpu: "${HTTPD_CPU_REQ}"
+            limits:
+              memory: "${HTTPD_MEM_LIMIT}"
+          env:
+          - name: HTTPD_AUTH_TYPE
+            valueFrom:
+              configMapKeyRef:
+                name: "${HTTPD_SERVICE_NAME}-auth-configs"
+                key: auth-type
+          lifecycle:
+            postStart:
+              exec:
+                command:
+                - "/usr/bin/save-container-environment"
+        serviceAccount: cfme-httpd
+        serviceAccountName: cfme-httpd
+parameters:
+- name: NAME
+  displayName: Name
+  required: true
+  description: The name assigned to all of the frontend objects defined in this template.
+  value: cloudforms
+- name: V2_KEY
+  displayName: CloudForms Encryption Key
+  required: true
+  description: Encryption Key for CloudForms Passwords
+  from: "[a-zA-Z0-9]{43}"
+  generate: expression
+- name: DATABASE_SERVICE_NAME
+  displayName: PostgreSQL Service Name
+  required: true
+  description: The name of the OpenShift Service exposed for the PostgreSQL container.
+  value: postgresql
+- name: DATABASE_USER
+  displayName: PostgreSQL User
+  required: true
+  description: PostgreSQL user that will access the database.
+  value: root
+- name: DATABASE_PASSWORD
+  displayName: PostgreSQL Password
+  required: true
+  description: Password for the PostgreSQL user.
+  from: "[a-zA-Z0-9]{8}"
+  generate: expression
+- name: DATABASE_IP
+  displayName: PostgreSQL Server IP
+  required: true
+  description: PostgreSQL external server IP used to configure service.
+  value: ''
+- name: DATABASE_PORT
+  displayName: PostgreSQL Server Port
+  required: true
+  description: PostgreSQL external server port used to configure service.
+  value: '5432'
+- name: DATABASE_NAME
+  required: true
+  displayName: PostgreSQL Database Name
+  description: Name of the PostgreSQL database accessed.
+  value: vmdb_production
+- name: DATABASE_REGION
+  required: true
+  displayName: Application Database Region
+  description: Database region that will be used for application.
+  value: '0'
+- name: ANSIBLE_DATABASE_NAME
+  displayName: Ansible PostgreSQL database name
+  required: true
+  description: The database to be used by the Ansible continer
+  value: awx
+- name: MEMCACHED_SERVICE_NAME
+  required: true
+  displayName: Memcached Service Name
+  description: The name of the OpenShift Service exposed for the Memcached container.
+  value: memcached
+- name: MEMCACHED_MAX_MEMORY
+  displayName: Memcached Max Memory
+  description: Memcached maximum memory for memcached object storage in MB.
+  value: '64'
+- name: MEMCACHED_MAX_CONNECTIONS
+  displayName: Memcached Max Connections
+  description: Memcached maximum number of connections allowed.
+  value: '1024'
+- name: MEMCACHED_SLAB_PAGE_SIZE
+  displayName: Memcached Slab Page Size
+  description: Memcached size of each slab page.
+  value: 1m
+- name: ANSIBLE_SERVICE_NAME
+  displayName: Ansible Service Name
+  description: The name of the OpenShift Service exposed for the Ansible container.
+  value: ansible
+- name: ANSIBLE_ADMIN_PASSWORD
+  displayName: Ansible admin User password
+  required: true
+  description: The password for the Ansible container admin user
+  from: "[a-zA-Z0-9]{32}"
+  generate: expression
+- name: ANSIBLE_SECRET_KEY
+  displayName: Ansible Secret Key
+  required: true
+  description: Encryption key for the Ansible container
+  from: "[a-f0-9]{32}"
+  generate: expression
+- name: ANSIBLE_RABBITMQ_USER_NAME
+  displayName: RabbitMQ Username
+  required: true
+  description: Username for the Ansible RabbitMQ Server
+  value: ansible
+- name: ANSIBLE_RABBITMQ_PASSWORD
+  displayName: RabbitMQ Server Password
+  required: true
+  description: Password for the Ansible RabbitMQ Server
+  from: "[a-zA-Z0-9]{32}"
+  generate: expression
+- name: APPLICATION_CPU_REQ
+  displayName: Application Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Application container will need (expressed in millicores).
+  value: 1000m
+- name: MEMCACHED_CPU_REQ
+  displayName: Memcached Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Memcached container will need (expressed in millicores).
+  value: 200m
+- name: ANSIBLE_CPU_REQ
+  displayName: Ansible Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Ansible container will need (expressed in millicores).
+  value: 1000m
+- name: APPLICATION_MEM_REQ
+  displayName: Application Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Application container will need.
+  value: 6144Mi
+- name: MEMCACHED_MEM_REQ
+  displayName: Memcached Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Memcached container will need.
+  value: 64Mi
+- name: ANSIBLE_MEM_REQ
+  displayName: Ansible Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Ansible container will need.
+  value: 2048Mi
+- name: APPLICATION_MEM_LIMIT
+  displayName: Application Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Application container can consume.
+  value: 16384Mi
+- name: MEMCACHED_MEM_LIMIT
+  displayName: Memcached Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Memcached container can consume.
+  value: 256Mi
+- name: ANSIBLE_MEM_LIMIT
+  displayName: Ansible Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Ansible container can consume.
+  value: 8096Mi
+- name: MEMCACHED_IMG_NAME
+  displayName: Memcached Image Name
+  description: This is the Memcached image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-memcached
+- name: MEMCACHED_IMG_TAG
+  displayName: Memcached Image Tag
+  description: This is the Memcached image tag/version requested to deploy.
+  value: latest
+- name: FRONTEND_APPLICATION_IMG_NAME
+  displayName: Frontend Application Image Name
+  description: This is the Frontend Application image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-app-ui
+- name: BACKEND_APPLICATION_IMG_NAME
+  displayName: Backend Application Image Name
+  description: This is the Backend Application image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-app
+- name: FRONTEND_APPLICATION_IMG_TAG
+  displayName: Front end Application Image Tag
+  description: This is the CloudForms Frontend Application image tag/version requested to deploy.
+  value: latest
+- name: BACKEND_APPLICATION_IMG_TAG
+  displayName: Back end Application Image Tag
+  description: This is the CloudForms Backend Application image tag/version requested to deploy.
+  value: latest
+- name: ANSIBLE_IMG_NAME
+  displayName: Ansible Image Name
+  description: This is the Ansible image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-embedded-ansible
+- name: ANSIBLE_IMG_TAG
+  displayName: Ansible Image Tag
+  description: This is the Ansible image tag/version requested to deploy.
+  value: latest
+- name: APPLICATION_DOMAIN
+  displayName: Application Hostname
+  description: The exposed hostname that will route to the application service, if left blank a value will be defaulted.
+  value: ''
+- name: APPLICATION_REPLICA_COUNT
+  displayName: Application Replica Count
+  description: This is the number of Application replicas requested to deploy.
+  value: '1'
+- name: APPLICATION_INIT_DELAY
+  displayName: Application Init Delay
+  required: true
+  description: Delay in seconds before we attempt to initialize the application.
+  value: '15'
+- name: APPLICATION_VOLUME_CAPACITY
+  displayName: Application Volume Capacity
+  required: true
+  description: Volume space available for application data.
+  value: 5Gi
+- name: HTTPD_SERVICE_NAME
+  required: true
+  displayName: Apache httpd Service Name
+  description: The name of the OpenShift Service exposed for the httpd container.
+  value: httpd
+- name: HTTPD_IMG_NAME
+  displayName: Apache httpd Image Name
+  description: This is the httpd image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-httpd
+- name: HTTPD_IMG_TAG
+  displayName: Apache httpd Image Tag
+  description: This is the httpd image tag/version requested to deploy.
+  value: latest
+- name: HTTPD_CONFIG_DIR
+  displayName: Apache httpd Configuration Directory
+  description: Directory used to store the Apache configuration files.
+  value: "/etc/httpd/conf.d"
+- name: HTTPD_AUTH_CONFIG_DIR
+  displayName: External Authentication Configuration Directory
+  description: Directory used to store the external authentication configuration files.
+  value: "/etc/httpd/auth-conf.d"
+- name: HTTPD_CPU_REQ
+  displayName: Apache httpd Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the httpd container will need (expressed in millicores).
+  value: 500m
+- name: HTTPD_MEM_REQ
+  displayName: Apache httpd Min RAM Requested
+  required: true
+  description: Minimum amount of memory the httpd container will need.
+  value: 512Mi
+- name: HTTPD_MEM_LIMIT
+  displayName: Apache httpd Max RAM Limit
+  required: true
+  description: Maximum amount of memory the httpd container can consume.
+  value: 8192Mi
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-template.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-template.yaml
new file mode 100644
index 000000000..d7c9f5af7
--- /dev/null
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-template.yaml
@@ -0,0 +1,940 @@
+apiVersion: v1
+kind: Template
+labels:
+  template: cloudforms
+metadata:
+  name: cloudforms
+  annotations:
+    description: CloudForms appliance with persistent storage
+    tags: instant-app,cloudforms,cfme
+    iconClass: icon-rails
+objects:
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: cfme-orchestrator
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: cfme-anyuid
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: cfme-privileged
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: cfme-httpd
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    name: "${NAME}-secrets"
+  stringData:
+    pg-password: "${DATABASE_PASSWORD}"
+    database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
+    v2-key: "${V2_KEY}"
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    name: "${ANSIBLE_SERVICE_NAME}-secrets"
+  stringData:
+    rabbit-password: "${ANSIBLE_RABBITMQ_PASSWORD}"
+    secret-key: "${ANSIBLE_SECRET_KEY}"
+    admin-password: "${ANSIBLE_ADMIN_PASSWORD}"
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}-configs"
+  data:
+    01_miq_overrides.conf: |
+      #------------------------------------------------------------------------------
+      # CONNECTIONS AND AUTHENTICATION
+      #------------------------------------------------------------------------------
+
+      tcp_keepalives_count = 9
+      tcp_keepalives_idle = 3
+      tcp_keepalives_interval = 75
+
+      #------------------------------------------------------------------------------
+      # RESOURCE USAGE (except WAL)
+      #------------------------------------------------------------------------------
+
+      shared_preload_libraries = 'pglogical,repmgr_funcs'
+      max_worker_processes = 10
+
+      #------------------------------------------------------------------------------
+      # WRITE AHEAD LOG
+      #------------------------------------------------------------------------------
+
+      wal_level = 'logical'
+      wal_log_hints = on
+      wal_buffers = 16MB
+      checkpoint_completion_target = 0.9
+
+      #------------------------------------------------------------------------------
+      # REPLICATION
+      #------------------------------------------------------------------------------
+
+      max_wal_senders = 10
+      wal_sender_timeout = 0
+      max_replication_slots = 10
+      hot_standby = on
+
+      #------------------------------------------------------------------------------
+      # ERROR REPORTING AND LOGGING
+      #------------------------------------------------------------------------------
+
+      log_filename = 'postgresql.log'
+      log_rotation_age = 0
+      log_min_duration_statement = 5000
+      log_connections = on
+      log_disconnections = on
+      log_line_prefix = '%t:%r:%c:%u@%d:[%p]:'
+      log_lock_waits = on
+
+      #------------------------------------------------------------------------------
+      # AUTOVACUUM PARAMETERS
+      #------------------------------------------------------------------------------
+
+      log_autovacuum_min_duration = 0
+      autovacuum_naptime = 5min
+      autovacuum_vacuum_threshold = 500
+      autovacuum_analyze_threshold = 500
+      autovacuum_vacuum_scale_factor = 0.05
+
+      #------------------------------------------------------------------------------
+      # LOCK MANAGEMENT
+      #------------------------------------------------------------------------------
+
+      deadlock_timeout = 5s
+
+      #------------------------------------------------------------------------------
+      # VERSION/PLATFORM COMPATIBILITY
+      #------------------------------------------------------------------------------
+
+      escape_string_warning = off
+      standard_conforming_strings = off
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}-configs"
+  data:
+    application.conf: |
+      # Timeout: The number of seconds before receives and sends time out.
+      Timeout 120
+
+      RewriteEngine On
+      Options SymLinksIfOwnerMatch
+
+      <VirtualHost *:80>
+        KeepAlive on
+        ProxyPreserveHost on
+        ProxyPass        /ws/ ws://${NAME}/ws/
+        ProxyPassReverse /ws/ ws://${NAME}/ws/
+        ProxyPass        / http://${NAME}/
+        ProxyPassReverse / http://${NAME}/
+      </VirtualHost>
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}-auth-configs"
+  data:
+    auth-type: internal
+    auth-configuration.conf: |
+      # External Authentication Configuration File
+      #
+      # For details on usage please see https://github.com/ManageIQ/manageiq-pods/blob/master/README.md#configuring-external-authentication
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Exposes and load balances CloudForms pods
+      service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"},{"name":"${MEMCACHED_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+    name: "${NAME}"
+  spec:
+    clusterIP: None
+    ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 80
+    selector:
+      name: "${NAME}"
+- apiVersion: v1
+  kind: Route
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+  spec:
+    host: "${APPLICATION_DOMAIN}"
+    port:
+      targetPort: http
+    tls:
+      termination: edge
+      insecureEdgeTerminationPolicy: Redirect
+    to:
+      kind: Service
+      name: "${HTTPD_SERVICE_NAME}"
+- apiVersion: v1
+  kind: PersistentVolumeClaim
+  metadata:
+    name: "${NAME}-${DATABASE_SERVICE_NAME}"
+  spec:
+    accessModes:
+    - ReadWriteOnce
+    resources:
+      requests:
+        storage: "${DATABASE_VOLUME_CAPACITY}"
+- apiVersion: apps/v1beta1
+  kind: StatefulSet
+  metadata:
+    name: "${NAME}"
+    annotations:
+      description: Defines how to deploy the CloudForms appliance
+  spec:
+    serviceName: "${NAME}"
+    replicas: "${APPLICATION_REPLICA_COUNT}"
+    template:
+      metadata:
+        labels:
+          name: "${NAME}"
+        name: "${NAME}"
+      spec:
+        containers:
+        - name: cloudforms
+          image: "${FRONTEND_APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
+          livenessProbe:
+            tcpSocket:
+              port: 80
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          readinessProbe:
+            httpGet:
+              path: "/"
+              port: 80
+              scheme: HTTP
+            initialDelaySeconds: 200
+            timeoutSeconds: 3
+          ports:
+          - containerPort: 80
+            protocol: TCP
+          volumeMounts:
+          - name: "${NAME}-server"
+            mountPath: "/persistent"
+          env:
+          - name: MY_POD_NAMESPACE
+            valueFrom:
+              fieldRef:
+                fieldPath: metadata.namespace
+          - name: APPLICATION_INIT_DELAY
+            value: "${APPLICATION_INIT_DELAY}"
+          - name: DATABASE_REGION
+            value: "${DATABASE_REGION}"
+          - name: DATABASE_URL
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: database-url
+          - name: V2_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: v2-key
+          - name: ANSIBLE_ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          resources:
+            requests:
+              memory: "${APPLICATION_MEM_REQ}"
+              cpu: "${APPLICATION_CPU_REQ}"
+            limits:
+              memory: "${APPLICATION_MEM_LIMIT}"
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                - "/opt/rh/cfme-container-scripts/sync-pv-data"
+        serviceAccount: cfme-orchestrator
+        serviceAccountName: cfme-orchestrator
+        terminationGracePeriodSeconds: 90
+    volumeClaimTemplates:
+    - metadata:
+        name: "${NAME}-server"
+        annotations:
+      spec:
+        accessModes:
+        - ReadWriteOnce
+        resources:
+          requests:
+            storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Headless service for CloudForms backend pods
+    name: "${NAME}-backend"
+  spec:
+    clusterIP: None
+    selector:
+      name: "${NAME}-backend"
+- apiVersion: apps/v1beta1
+  kind: StatefulSet
+  metadata:
+    name: "${NAME}-backend"
+    annotations:
+      description: Defines how to deploy the CloudForms appliance
+  spec:
+    serviceName: "${NAME}-backend"
+    replicas: 0
+    template:
+      metadata:
+        labels:
+          name: "${NAME}-backend"
+        name: "${NAME}-backend"
+      spec:
+        containers:
+        - name: cloudforms
+          image: "${BACKEND_APPLICATION_IMG_NAME}:${BACKEND_APPLICATION_IMG_TAG}"
+          livenessProbe:
+            exec:
+              command:
+              - pidof
+              - MIQ Server
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          volumeMounts:
+          - name: "${NAME}-server"
+            mountPath: "/persistent"
+          env:
+          - name: APPLICATION_INIT_DELAY
+            value: "${APPLICATION_INIT_DELAY}"
+          - name: DATABASE_URL
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: database-url
+          - name: MIQ_SERVER_DEFAULT_ROLES
+            value: database_operations,event,reporting,scheduler,smartstate,ems_operations,ems_inventory,automate
+          - name: FRONTEND_SERVICE_NAME
+            value: "${NAME}"
+          - name: V2_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: v2-key
+          - name: ANSIBLE_ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          resources:
+            requests:
+              memory: "${APPLICATION_MEM_REQ}"
+              cpu: "${APPLICATION_CPU_REQ}"
+            limits:
+              memory: "${APPLICATION_MEM_LIMIT}"
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                - "/opt/rh/cfme-container-scripts/sync-pv-data"
+        serviceAccount: cfme-orchestrator
+        serviceAccountName: cfme-orchestrator
+        terminationGracePeriodSeconds: 90
+    volumeClaimTemplates:
+    - metadata:
+        name: "${NAME}-server"
+        annotations:
+      spec:
+        accessModes:
+        - ReadWriteOnce
+        resources:
+          requests:
+            storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${MEMCACHED_SERVICE_NAME}"
+    annotations:
+      description: Exposes the memcached server
+  spec:
+    ports:
+    - name: memcached
+      port: 11211
+      targetPort: 11211
+    selector:
+      name: "${MEMCACHED_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${MEMCACHED_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy memcached
+  spec:
+    strategy:
+      type: Recreate
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${MEMCACHED_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${MEMCACHED_SERVICE_NAME}"
+        labels:
+          name: "${MEMCACHED_SERVICE_NAME}"
+      spec:
+        volumes: []
+        containers:
+        - name: memcached
+          image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
+          ports:
+          - containerPort: 11211
+          readinessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 5
+            tcpSocket:
+              port: 11211
+          livenessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 30
+            tcpSocket:
+              port: 11211
+          volumeMounts: []
+          env:
+          - name: MEMCACHED_MAX_MEMORY
+            value: "${MEMCACHED_MAX_MEMORY}"
+          - name: MEMCACHED_MAX_CONNECTIONS
+            value: "${MEMCACHED_MAX_CONNECTIONS}"
+          - name: MEMCACHED_SLAB_PAGE_SIZE
+            value: "${MEMCACHED_SLAB_PAGE_SIZE}"
+          resources:
+            requests:
+              memory: "${MEMCACHED_MEM_REQ}"
+              cpu: "${MEMCACHED_CPU_REQ}"
+            limits:
+              memory: "${MEMCACHED_MEM_LIMIT}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}"
+    annotations:
+      description: Exposes the database server
+  spec:
+    ports:
+    - name: postgresql
+      port: 5432
+      targetPort: 5432
+    selector:
+      name: "${DATABASE_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy the database
+  spec:
+    strategy:
+      type: Recreate
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${DATABASE_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${DATABASE_SERVICE_NAME}"
+        labels:
+          name: "${DATABASE_SERVICE_NAME}"
+      spec:
+        volumes:
+        - name: cfme-pgdb-volume
+          persistentVolumeClaim:
+            claimName: "${NAME}-${DATABASE_SERVICE_NAME}"
+        - name: cfme-pg-configs
+          configMap:
+            name: "${DATABASE_SERVICE_NAME}-configs"
+        containers:
+        - name: postgresql
+          image: "${POSTGRESQL_IMG_NAME}:${POSTGRESQL_IMG_TAG}"
+          ports:
+          - containerPort: 5432
+          readinessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 15
+            exec:
+              command:
+              - "/bin/sh"
+              - "-i"
+              - "-c"
+              - psql -h 127.0.0.1 -U ${POSTGRESQL_USER} -q -d ${POSTGRESQL_DATABASE} -c 'SELECT 1'
+          livenessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 60
+            tcpSocket:
+              port: 5432
+          volumeMounts:
+          - name: cfme-pgdb-volume
+            mountPath: "/var/lib/pgsql/data"
+          - name: cfme-pg-configs
+            mountPath: "${POSTGRESQL_CONFIG_DIR}"
+          env:
+          - name: POSTGRESQL_USER
+            value: "${DATABASE_USER}"
+          - name: POSTGRESQL_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: pg-password
+          - name: POSTGRESQL_DATABASE
+            value: "${DATABASE_NAME}"
+          - name: POSTGRESQL_MAX_CONNECTIONS
+            value: "${POSTGRESQL_MAX_CONNECTIONS}"
+          - name: POSTGRESQL_SHARED_BUFFERS
+            value: "${POSTGRESQL_SHARED_BUFFERS}"
+          - name: POSTGRESQL_CONFIG_DIR
+            value: "${POSTGRESQL_CONFIG_DIR}"
+          resources:
+            requests:
+              memory: "${POSTGRESQL_MEM_REQ}"
+              cpu: "${POSTGRESQL_CPU_REQ}"
+            limits:
+              memory: "${POSTGRESQL_MEM_LIMIT}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Exposes and load balances Ansible pods
+      service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+    name: "${ANSIBLE_SERVICE_NAME}"
+  spec:
+    ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 80
+    - name: https
+      port: 443
+      protocol: TCP
+      targetPort: 443
+    selector:
+      name: "${ANSIBLE_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${ANSIBLE_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy the Ansible appliance
+  spec:
+    strategy:
+      type: Recreate
+    serviceName: "${ANSIBLE_SERVICE_NAME}"
+    replicas: 0
+    template:
+      metadata:
+        labels:
+          name: "${ANSIBLE_SERVICE_NAME}"
+        name: "${ANSIBLE_SERVICE_NAME}"
+      spec:
+        containers:
+        - name: ansible
+          image: "${ANSIBLE_IMG_NAME}:${ANSIBLE_IMG_TAG}"
+          livenessProbe:
+            tcpSocket:
+              port: 443
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          readinessProbe:
+            httpGet:
+              path: "/"
+              port: 443
+              scheme: HTTPS
+            initialDelaySeconds: 200
+            timeoutSeconds: 3
+          ports:
+          - containerPort: 80
+            protocol: TCP
+          - containerPort: 443
+            protocol: TCP
+          securityContext:
+            privileged: true
+          env:
+          - name: ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          - name: RABBITMQ_USER_NAME
+            value: "${ANSIBLE_RABBITMQ_USER_NAME}"
+          - name: RABBITMQ_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: rabbit-password
+          - name: ANSIBLE_SECRET_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: secret-key
+          - name: DATABASE_SERVICE_NAME
+            value: "${DATABASE_SERVICE_NAME}"
+          - name: POSTGRESQL_USER
+            value: "${DATABASE_USER}"
+          - name: POSTGRESQL_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: pg-password
+          - name: POSTGRESQL_DATABASE
+            value: "${ANSIBLE_DATABASE_NAME}"
+          resources:
+            requests:
+              memory: "${ANSIBLE_MEM_REQ}"
+              cpu: "${ANSIBLE_CPU_REQ}"
+            limits:
+              memory: "${ANSIBLE_MEM_LIMIT}"
+        serviceAccount: cfme-privileged
+        serviceAccountName: cfme-privileged
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+    annotations:
+      description: Exposes the httpd server
+      service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+  spec:
+    ports:
+    - name: http
+      port: 80
+      targetPort: 80
+    selector:
+      name: httpd
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy httpd
+  spec:
+    strategy:
+      type: Recreate
+      recreateParams:
+        timeoutSeconds: 1200
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${HTTPD_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${HTTPD_SERVICE_NAME}"
+        labels:
+          name: "${HTTPD_SERVICE_NAME}"
+      spec:
+        volumes:
+        - name: httpd-config
+          configMap:
+            name: "${HTTPD_SERVICE_NAME}-configs"
+        - name: httpd-auth-config
+          configMap:
+            name: "${HTTPD_SERVICE_NAME}-auth-configs"
+        containers:
+        - name: httpd
+          image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
+          ports:
+          - containerPort: 80
+          livenessProbe:
+            exec:
+              command:
+              - pidof
+              - httpd
+            initialDelaySeconds: 15
+            timeoutSeconds: 3
+          readinessProbe:
+            tcpSocket:
+              port: 80
+            initialDelaySeconds: 10
+            timeoutSeconds: 3
+          volumeMounts:
+          - name: httpd-config
+            mountPath: "${HTTPD_CONFIG_DIR}"
+          - name: httpd-auth-config
+            mountPath: "${HTTPD_AUTH_CONFIG_DIR}"
+          resources:
+            requests:
+              memory: "${HTTPD_MEM_REQ}"
+              cpu: "${HTTPD_CPU_REQ}"
+            limits:
+              memory: "${HTTPD_MEM_LIMIT}"
+          env:
+          - name: HTTPD_AUTH_TYPE
+            valueFrom:
+              configMapKeyRef:
+                name: "${HTTPD_SERVICE_NAME}-auth-configs"
+                key: auth-type
+          lifecycle:
+            postStart:
+              exec:
+                command:
+                - "/usr/bin/save-container-environment"
+        serviceAccount: cfme-httpd
+        serviceAccountName: cfme-httpd
+parameters:
+- name: NAME
+  displayName: Name
+  required: true
+  description: The name assigned to all of the frontend objects defined in this template.
+  value: cloudforms
+- name: V2_KEY
+  displayName: CloudForms Encryption Key
+  required: true
+  description: Encryption Key for CloudForms Passwords
+  from: "[a-zA-Z0-9]{43}"
+  generate: expression
+- name: DATABASE_SERVICE_NAME
+  displayName: PostgreSQL Service Name
+  required: true
+  description: The name of the OpenShift Service exposed for the PostgreSQL container.
+  value: postgresql
+- name: DATABASE_USER
+  displayName: PostgreSQL User
+  required: true
+  description: PostgreSQL user that will access the database.
+  value: root
+- name: DATABASE_PASSWORD
+  displayName: PostgreSQL Password
+  required: true
+  description: Password for the PostgreSQL user.
+  from: "[a-zA-Z0-9]{8}"
+  generate: expression
+- name: DATABASE_NAME
+  required: true
+  displayName: PostgreSQL Database Name
+  description: Name of the PostgreSQL database accessed.
+  value: vmdb_production
+- name: DATABASE_REGION
+  required: true
+  displayName: Application Database Region
+  description: Database region that will be used for application.
+  value: '0'
+- name: ANSIBLE_DATABASE_NAME
+  displayName: Ansible PostgreSQL database name
+  required: true
+  description: The database to be used by the Ansible continer
+  value: awx
+- name: MEMCACHED_SERVICE_NAME
+  required: true
+  displayName: Memcached Service Name
+  description: The name of the OpenShift Service exposed for the Memcached container.
+  value: memcached
+- name: MEMCACHED_MAX_MEMORY
+  displayName: Memcached Max Memory
+  description: Memcached maximum memory for memcached object storage in MB.
+  value: '64'
+- name: MEMCACHED_MAX_CONNECTIONS
+  displayName: Memcached Max Connections
+  description: Memcached maximum number of connections allowed.
+  value: '1024'
+- name: MEMCACHED_SLAB_PAGE_SIZE
+  displayName: Memcached Slab Page Size
+  description: Memcached size of each slab page.
+  value: 1m
+- name: POSTGRESQL_CONFIG_DIR
+  displayName: PostgreSQL Configuration Overrides
+  description: Directory used to store PostgreSQL configuration overrides.
+  value: "/var/lib/pgsql/conf.d"
+- name: POSTGRESQL_MAX_CONNECTIONS
+  displayName: PostgreSQL Max Connections
+  description: PostgreSQL maximum number of database connections allowed.
+  value: '1000'
+- name: POSTGRESQL_SHARED_BUFFERS
+  displayName: PostgreSQL Shared Buffer Amount
+  description: Amount of memory dedicated for PostgreSQL shared memory buffers.
+  value: 1GB
+- name: ANSIBLE_SERVICE_NAME
+  displayName: Ansible Service Name
+  description: The name of the OpenShift Service exposed for the Ansible container.
+  value: ansible
+- name: ANSIBLE_ADMIN_PASSWORD
+  displayName: Ansible admin User password
+  required: true
+  description: The password for the Ansible container admin user
+  from: "[a-zA-Z0-9]{32}"
+  generate: expression
+- name: ANSIBLE_SECRET_KEY
+  displayName: Ansible Secret Key
+  required: true
+  description: Encryption key for the Ansible container
+  from: "[a-f0-9]{32}"
+  generate: expression
+- name: ANSIBLE_RABBITMQ_USER_NAME
+  displayName: RabbitMQ Username
+  required: true
+  description: Username for the Ansible RabbitMQ Server
+  value: ansible
+- name: ANSIBLE_RABBITMQ_PASSWORD
+  displayName: RabbitMQ Server Password
+  required: true
+  description: Password for the Ansible RabbitMQ Server
+  from: "[a-zA-Z0-9]{32}"
+  generate: expression
+- name: APPLICATION_CPU_REQ
+  displayName: Application Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Application container will need (expressed in millicores).
+  value: 1000m
+- name: POSTGRESQL_CPU_REQ
+  displayName: PostgreSQL Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the PostgreSQL container will need (expressed in millicores).
+  value: 500m
+- name: MEMCACHED_CPU_REQ
+  displayName: Memcached Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Memcached container will need (expressed in millicores).
+  value: 200m
+- name: ANSIBLE_CPU_REQ
+  displayName: Ansible Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Ansible container will need (expressed in millicores).
+  value: 1000m
+- name: APPLICATION_MEM_REQ
+  displayName: Application Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Application container will need.
+  value: 6144Mi
+- name: POSTGRESQL_MEM_REQ
+  displayName: PostgreSQL Min RAM Requested
+  required: true
+  description: Minimum amount of memory the PostgreSQL container will need.
+  value: 4Gi
+- name: MEMCACHED_MEM_REQ
+  displayName: Memcached Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Memcached container will need.
+  value: 64Mi
+- name: ANSIBLE_MEM_REQ
+  displayName: Ansible Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Ansible container will need.
+  value: 2048Mi
+- name: APPLICATION_MEM_LIMIT
+  displayName: Application Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Application container can consume.
+  value: 16384Mi
+- name: POSTGRESQL_MEM_LIMIT
+  displayName: PostgreSQL Max RAM Limit
+  required: true
+  description: Maximum amount of memory the PostgreSQL container can consume.
+  value: 8Gi
+- name: MEMCACHED_MEM_LIMIT
+  displayName: Memcached Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Memcached container can consume.
+  value: 256Mi
+- name: ANSIBLE_MEM_LIMIT
+  displayName: Ansible Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Ansible container can consume.
+  value: 8096Mi
+- name: POSTGRESQL_IMG_NAME
+  displayName: PostgreSQL Image Name
+  description: This is the PostgreSQL image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-postgresql
+- name: POSTGRESQL_IMG_TAG
+  displayName: PostgreSQL Image Tag
+  description: This is the PostgreSQL image tag/version requested to deploy.
+  value: latest
+- name: MEMCACHED_IMG_NAME
+  displayName: Memcached Image Name
+  description: This is the Memcached image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-memcached
+- name: MEMCACHED_IMG_TAG
+  displayName: Memcached Image Tag
+  description: This is the Memcached image tag/version requested to deploy.
+  value: latest
+- name: FRONTEND_APPLICATION_IMG_NAME
+  displayName: Frontend Application Image Name
+  description: This is the Frontend Application image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-app-ui
+- name: BACKEND_APPLICATION_IMG_NAME
+  displayName: Backend Application Image Name
+  description: This is the Backend Application image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-app
+- name: FRONTEND_APPLICATION_IMG_TAG
+  displayName: Front end Application Image Tag
+  description: This is the CloudForms Frontend Application image tag/version requested to deploy.
+  value: latest
+- name: BACKEND_APPLICATION_IMG_TAG
+  displayName: Back end Application Image Tag
+  description: This is the CloudForms Backend Application image tag/version requested to deploy.
+  value: latest
+- name: ANSIBLE_IMG_NAME
+  displayName: Ansible Image Name
+  description: This is the Ansible image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-embedded-ansible
+- name: ANSIBLE_IMG_TAG
+  displayName: Ansible Image Tag
+  description: This is the Ansible image tag/version requested to deploy.
+  value: latest
+- name: APPLICATION_DOMAIN
+  displayName: Application Hostname
+  description: The exposed hostname that will route to the application service, if left blank a value will be defaulted.
+  value: ''
+- name: APPLICATION_REPLICA_COUNT
+  displayName: Application Replica Count
+  description: This is the number of Application replicas requested to deploy.
+  value: '1'
+- name: APPLICATION_INIT_DELAY
+  displayName: Application Init Delay
+  required: true
+  description: Delay in seconds before we attempt to initialize the application.
+  value: '15'
+- name: APPLICATION_VOLUME_CAPACITY
+  displayName: Application Volume Capacity
+  required: true
+  description: Volume space available for application data.
+  value: 5Gi
+- name: DATABASE_VOLUME_CAPACITY
+  displayName: Database Volume Capacity
+  required: true
+  description: Volume space available for database.
+  value: 15Gi
+- name: HTTPD_SERVICE_NAME
+  required: true
+  displayName: Apache httpd Service Name
+  description: The name of the OpenShift Service exposed for the httpd container.
+  value: httpd
+- name: HTTPD_IMG_NAME
+  displayName: Apache httpd Image Name
+  description: This is the httpd image name requested to deploy.
+  value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-httpd
+- name: HTTPD_IMG_TAG
+  displayName: Apache httpd Image Tag
+  description: This is the httpd image tag/version requested to deploy.
+  value: latest
+- name: HTTPD_CONFIG_DIR
+  displayName: Apache Configuration Directory
+  description: Directory used to store the Apache configuration files.
+  value: "/etc/httpd/conf.d"
+- name: HTTPD_AUTH_CONFIG_DIR
+  displayName: External Authentication Configuration Directory
+  description: Directory used to store the external authentication configuration files.
+  value: "/etc/httpd/auth-conf.d"
+- name: HTTPD_CPU_REQ
+  displayName: Apache httpd Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the httpd container will need (expressed in millicores).
+  value: 500m
+- name: HTTPD_MEM_REQ
+  displayName: Apache httpd Min RAM Requested
+  required: true
+  description: Minimum amount of memory the httpd container will need.
+  value: 512Mi
+- name: HTTPD_MEM_LIMIT
+  displayName: Apache httpd Max RAM Limit
+  required: true
+  description: Maximum amount of memory the httpd container can consume.
+  value: 8192Mi
diff --git a/roles/openshift_management/files/templates/manageiq/miq-backup-job.yaml b/roles/openshift_management/files/templates/manageiq/miq-backup-job.yaml
new file mode 100644
index 000000000..044cb73a5
--- /dev/null
+++ b/roles/openshift_management/files/templates/manageiq/miq-backup-job.yaml
@@ -0,0 +1,28 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: manageiq-backup
+spec:
+  template:
+    metadata:
+      name: manageiq-backup
+    spec:
+      containers:
+      - name: postgresql
+        image: docker.io/manageiq/postgresql:latest
+        command:
+        - "/opt/manageiq/container-scripts/backup_db"
+        env:
+        - name: DATABASE_URL
+          valueFrom:
+            secretKeyRef:
+              name: manageiq-secrets
+              key: database-url
+        volumeMounts:
+        - name: miq-backup-vol
+          mountPath: "/backups"
+      volumes:
+      - name: miq-backup-vol
+        persistentVolumeClaim:
+          claimName: manageiq-backup
+      restartPolicy: Never
diff --git a/roles/openshift_management/files/templates/manageiq/miq-backup-pvc.yaml b/roles/openshift_management/files/templates/manageiq/miq-backup-pvc.yaml
new file mode 100644
index 000000000..25696ef23
--- /dev/null
+++ b/roles/openshift_management/files/templates/manageiq/miq-backup-pvc.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: manageiq-backup
+spec:
+  accessModes:
+  - ReadWriteOnce
+  resources:
+    requests:
+      storage: 15Gi
diff --git a/roles/openshift_management/files/templates/manageiq/miq-pv-backup-example.yaml b/roles/openshift_management/files/templates/manageiq/miq-pv-backup-example.yaml
new file mode 100644
index 000000000..a5cf54d4e
--- /dev/null
+++ b/roles/openshift_management/files/templates/manageiq/miq-pv-backup-example.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+  name: miq-pv03
+spec:
+  capacity:
+    storage: 15Gi
+  accessModes:
+  - ReadWriteOnce
+  nfs:
+    path: "/exports/miq-pv03"
+    server: "<your-nfs-host-here>"
+  persistentVolumeReclaimPolicy: Retain
diff --git a/roles/openshift_management/files/templates/manageiq/miq-pv-db-example.yaml b/roles/openshift_management/files/templates/manageiq/miq-pv-db-example.yaml
new file mode 100644
index 000000000..a803bebe2
--- /dev/null
+++ b/roles/openshift_management/files/templates/manageiq/miq-pv-db-example.yaml
@@ -0,0 +1,38 @@
+apiVersion: v1
+kind: Template
+labels:
+  template: manageiq-db-pv
+metadata:
+  name: manageiq-db-pv
+  annotations:
+    description: PV Template for MIQ PostgreSQL DB
+    tags: PVS, MIQ
+objects:
+- apiVersion: v1
+  kind: PersistentVolume
+  metadata:
+    name: miq-db
+  spec:
+    capacity:
+      storage: "${PV_SIZE}"
+    accessModes:
+    - ReadWriteOnce
+    nfs:
+      path: "${BASE_PATH}/miq-db"
+      server: "${NFS_HOST}"
+    persistentVolumeReclaimPolicy: Retain
+parameters:
+- name: PV_SIZE
+  displayName: PV Size for DB
+  required: true
+  description: The size of the MIQ DB PV given in Gi
+  value: 15Gi
+- name: BASE_PATH
+  displayName: Exports Directory Base Path
+  required: true
+  description: The parent directory of your NFS exports
+  value: "/exports"
+- name: NFS_HOST
+  displayName: NFS Server Hostname
+  required: true
+  description: The hostname or IP address of the NFS server
diff --git a/roles/openshift_management/files/templates/manageiq/miq-pv-server-example.yaml b/roles/openshift_management/files/templates/manageiq/miq-pv-server-example.yaml
new file mode 100644
index 000000000..1288544d1
--- /dev/null
+++ b/roles/openshift_management/files/templates/manageiq/miq-pv-server-example.yaml
@@ -0,0 +1,38 @@
+apiVersion: v1
+kind: Template
+labels:
+  template: manageiq-app-pv
+metadata:
+  name: manageiq-app-pv
+  annotations:
+    description: PV Template for MIQ Server
+    tags: PVS, MIQ
+objects:
+- apiVersion: v1
+  kind: PersistentVolume
+  metadata:
+    name: miq-app
+  spec:
+    capacity:
+      storage: "${PV_SIZE}"
+    accessModes:
+    - ReadWriteOnce
+    nfs:
+      path: "${BASE_PATH}/miq-app"
+      server: "${NFS_HOST}"
+    persistentVolumeReclaimPolicy: Retain
+parameters:
+- name: PV_SIZE
+  displayName: PV Size for App
+  required: true
+  description: The size of the MIQ APP PV given in Gi
+  value: 5Gi
+- name: BASE_PATH
+  displayName: Exports Directory Base Path
+  required: true
+  description: The parent directory of your NFS exports
+  value: "/exports"
+- name: NFS_HOST
+  displayName: NFS Server Hostname
+  required: true
+  description: The hostname or IP address of the NFS server
diff --git a/roles/openshift_management/files/templates/manageiq/miq-restore-job.yaml b/roles/openshift_management/files/templates/manageiq/miq-restore-job.yaml
new file mode 100644
index 000000000..eea284dd4
--- /dev/null
+++ b/roles/openshift_management/files/templates/manageiq/miq-restore-job.yaml
@@ -0,0 +1,35 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: manageiq-restore
+spec:
+  template:
+    metadata:
+      name: manageiq-restore
+    spec:
+      containers:
+      - name: postgresql
+        image: docker.io/manageiq/postgresql:latest
+        command:
+        - "/opt/manageiq/container-scripts/restore_db"
+        env:
+        - name: DATABASE_URL
+          valueFrom:
+            secretKeyRef:
+              name: manageiq-secrets
+              key: database-url
+        - name: BACKUP_VERSION
+          value: latest
+        volumeMounts:
+        - name: miq-backup-vol
+          mountPath: "/backups"
+        - name: miq-prod-vol
+          mountPath: "/restore"
+      volumes:
+      - name: miq-backup-vol
+        persistentVolumeClaim:
+          claimName: manageiq-backup
+      - name: miq-prod-vol
+        persistentVolumeClaim:
+          claimName: manageiq-postgresql
+      restartPolicy: Never
diff --git a/roles/openshift_management/files/templates/manageiq/miq-template-ext-db.yaml b/roles/openshift_management/files/templates/manageiq/miq-template-ext-db.yaml
new file mode 100644
index 000000000..82cd5d49e
--- /dev/null
+++ b/roles/openshift_management/files/templates/manageiq/miq-template-ext-db.yaml
@@ -0,0 +1,771 @@
+apiVersion: v1
+kind: Template
+labels:
+  template: manageiq-ext-db
+metadata:
+  name: manageiq-ext-db
+  annotations:
+    description: ManageIQ appliance with persistent storage using a external DB host
+    tags: instant-app,manageiq,miq
+    iconClass: icon-rails
+objects:
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: miq-orchestrator
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: miq-anyuid
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: miq-privileged
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: miq-httpd
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    name: "${NAME}-secrets"
+  stringData:
+    pg-password: "${DATABASE_PASSWORD}"
+    database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
+    v2-key: "${V2_KEY}"
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    name: "${ANSIBLE_SERVICE_NAME}-secrets"
+  stringData:
+    rabbit-password: "${ANSIBLE_RABBITMQ_PASSWORD}"
+    secret-key: "${ANSIBLE_SECRET_KEY}"
+    admin-password: "${ANSIBLE_ADMIN_PASSWORD}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Exposes and load balances ManageIQ pods
+      service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"},{"name":"${MEMCACHED_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+    name: "${NAME}"
+  spec:
+    clusterIP: None
+    ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 80
+    selector:
+      name: "${NAME}"
+- apiVersion: v1
+  kind: Route
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+  spec:
+    host: "${APPLICATION_DOMAIN}"
+    port:
+      targetPort: http
+    tls:
+      termination: edge
+      insecureEdgeTerminationPolicy: Redirect
+    to:
+      kind: Service
+      name: "${HTTPD_SERVICE_NAME}"
+- apiVersion: apps/v1beta1
+  kind: StatefulSet
+  metadata:
+    name: "${NAME}"
+    annotations:
+      description: Defines how to deploy the ManageIQ appliance
+  spec:
+    serviceName: "${NAME}"
+    replicas: "${APPLICATION_REPLICA_COUNT}"
+    template:
+      metadata:
+        labels:
+          name: "${NAME}"
+        name: "${NAME}"
+      spec:
+        containers:
+        - name: manageiq
+          image: "${APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
+          livenessProbe:
+            tcpSocket:
+              port: 80
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          readinessProbe:
+            httpGet:
+              path: "/"
+              port: 80
+              scheme: HTTP
+            initialDelaySeconds: 200
+            timeoutSeconds: 3
+          ports:
+          - containerPort: 80
+            protocol: TCP
+          volumeMounts:
+          - name: "${NAME}-server"
+            mountPath: "/persistent"
+          env:
+          - name: MY_POD_NAMESPACE
+            valueFrom:
+              fieldRef:
+                fieldPath: metadata.namespace
+          - name: APPLICATION_INIT_DELAY
+            value: "${APPLICATION_INIT_DELAY}"
+          - name: DATABASE_SERVICE_NAME
+            value: "${DATABASE_SERVICE_NAME}"
+          - name: DATABASE_REGION
+            value: "${DATABASE_REGION}"
+          - name: DATABASE_URL
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: database-url
+          - name: MEMCACHED_SERVER
+            value: "${MEMCACHED_SERVICE_NAME}:11211"
+          - name: MEMCACHED_SERVICE_NAME
+            value: "${MEMCACHED_SERVICE_NAME}"
+          - name: V2_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: v2-key
+          - name: ANSIBLE_SERVICE_NAME
+            value: "${ANSIBLE_SERVICE_NAME}"
+          - name: ANSIBLE_ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          resources:
+            requests:
+              memory: "${APPLICATION_MEM_REQ}"
+              cpu: "${APPLICATION_CPU_REQ}"
+            limits:
+              memory: "${APPLICATION_MEM_LIMIT}"
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                - "/opt/manageiq/container-scripts/sync-pv-data"
+        serviceAccount: miq-orchestrator
+        serviceAccountName: miq-orchestrator
+        terminationGracePeriodSeconds: 90
+    volumeClaimTemplates:
+    - metadata:
+        name: "${NAME}-server"
+        annotations:
+      spec:
+        accessModes:
+        - ReadWriteOnce
+        resources:
+          requests:
+            storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Headless service for ManageIQ backend pods
+    name: "${NAME}-backend"
+  spec:
+    clusterIP: None
+    selector:
+      name: "${NAME}-backend"
+- apiVersion: apps/v1beta1
+  kind: StatefulSet
+  metadata:
+    name: "${NAME}-backend"
+    annotations:
+      description: Defines how to deploy the ManageIQ appliance
+  spec:
+    serviceName: "${NAME}-backend"
+    replicas: 0
+    template:
+      metadata:
+        labels:
+          name: "${NAME}-backend"
+        name: "${NAME}-backend"
+      spec:
+        containers:
+        - name: manageiq
+          image: "${APPLICATION_IMG_NAME}:${BACKEND_APPLICATION_IMG_TAG}"
+          livenessProbe:
+            exec:
+              command:
+              - pidof
+              - MIQ Server
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          volumeMounts:
+          - name: "${NAME}-server"
+            mountPath: "/persistent"
+          env:
+          - name: APPLICATION_INIT_DELAY
+            value: "${APPLICATION_INIT_DELAY}"
+          - name: DATABASE_URL
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: database-url
+          - name: MIQ_SERVER_DEFAULT_ROLES
+            value: database_operations,event,reporting,scheduler,smartstate,ems_operations,ems_inventory,automate
+          - name: FRONTEND_SERVICE_NAME
+            value: "${NAME}"
+          - name: MEMCACHED_SERVER
+            value: "${MEMCACHED_SERVICE_NAME}:11211"
+          - name: V2_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: v2-key
+          - name: ANSIBLE_SERVICE_NAME
+            value: "${ANSIBLE_SERVICE_NAME}"
+          - name: ANSIBLE_ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          resources:
+            requests:
+              memory: "${APPLICATION_MEM_REQ}"
+              cpu: "${APPLICATION_CPU_REQ}"
+            limits:
+              memory: "${APPLICATION_MEM_LIMIT}"
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                - "/opt/manageiq/container-scripts/sync-pv-data"
+        serviceAccount: miq-orchestrator
+        serviceAccountName: miq-orchestrator
+        terminationGracePeriodSeconds: 90
+    volumeClaimTemplates:
+    - metadata:
+        name: "${NAME}-server"
+        annotations:
+      spec:
+        accessModes:
+        - ReadWriteOnce
+        resources:
+          requests:
+            storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${MEMCACHED_SERVICE_NAME}"
+    annotations:
+      description: Exposes the memcached server
+  spec:
+    ports:
+    - name: memcached
+      port: 11211
+      targetPort: 11211
+    selector:
+      name: "${MEMCACHED_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${MEMCACHED_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy memcached
+  spec:
+    strategy:
+      type: Recreate
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${MEMCACHED_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${MEMCACHED_SERVICE_NAME}"
+        labels:
+          name: "${MEMCACHED_SERVICE_NAME}"
+      spec:
+        volumes: []
+        containers:
+        - name: memcached
+          image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
+          ports:
+          - containerPort: 11211
+          readinessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 5
+            tcpSocket:
+              port: 11211
+          livenessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 30
+            tcpSocket:
+              port: 11211
+          volumeMounts: []
+          env:
+          - name: MEMCACHED_MAX_MEMORY
+            value: "${MEMCACHED_MAX_MEMORY}"
+          - name: MEMCACHED_MAX_CONNECTIONS
+            value: "${MEMCACHED_MAX_CONNECTIONS}"
+          - name: MEMCACHED_SLAB_PAGE_SIZE
+            value: "${MEMCACHED_SLAB_PAGE_SIZE}"
+          resources:
+            requests:
+              memory: "${MEMCACHED_MEM_REQ}"
+              cpu: "${MEMCACHED_CPU_REQ}"
+            limits:
+              memory: "${MEMCACHED_MEM_LIMIT}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}"
+    annotations:
+      description: Remote database service
+  spec:
+    ports:
+    - name: postgresql
+      port: 5432
+      targetPort: "${{DATABASE_PORT}}"
+    selector: {}
+- apiVersion: v1
+  kind: Endpoints
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}"
+  subsets:
+  - addresses:
+    - ip: "${DATABASE_IP}"
+    ports:
+    - port: "${{DATABASE_PORT}}"
+      name: postgresql
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Exposes and load balances Ansible pods
+      service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+    name: "${ANSIBLE_SERVICE_NAME}"
+  spec:
+    ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 80
+    - name: https
+      port: 443
+      protocol: TCP
+      targetPort: 443
+    selector:
+      name: "${ANSIBLE_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${ANSIBLE_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy the Ansible appliance
+  spec:
+    strategy:
+      type: Recreate
+    serviceName: "${ANSIBLE_SERVICE_NAME}"
+    replicas: 0
+    template:
+      metadata:
+        labels:
+          name: "${ANSIBLE_SERVICE_NAME}"
+        name: "${ANSIBLE_SERVICE_NAME}"
+      spec:
+        containers:
+        - name: ansible
+          image: "${ANSIBLE_IMG_NAME}:${ANSIBLE_IMG_TAG}"
+          livenessProbe:
+            tcpSocket:
+              port: 443
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          readinessProbe:
+            httpGet:
+              path: "/"
+              port: 443
+              scheme: HTTPS
+            initialDelaySeconds: 200
+            timeoutSeconds: 3
+          ports:
+          - containerPort: 80
+            protocol: TCP
+          - containerPort: 443
+            protocol: TCP
+          securityContext:
+            privileged: true
+          env:
+          - name: ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          - name: RABBITMQ_USER_NAME
+            value: "${ANSIBLE_RABBITMQ_USER_NAME}"
+          - name: RABBITMQ_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: rabbit-password
+          - name: ANSIBLE_SECRET_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: secret-key
+          - name: DATABASE_SERVICE_NAME
+            value: "${DATABASE_SERVICE_NAME}"
+          - name: POSTGRESQL_USER
+            value: "${DATABASE_USER}"
+          - name: POSTGRESQL_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: pg-password
+          - name: POSTGRESQL_DATABASE
+            value: "${ANSIBLE_DATABASE_NAME}"
+          resources:
+            requests:
+              memory: "${ANSIBLE_MEM_REQ}"
+              cpu: "${ANSIBLE_CPU_REQ}"
+            limits:
+              memory: "${ANSIBLE_MEM_LIMIT}"
+        serviceAccount: miq-privileged
+        serviceAccountName: miq-privileged
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}-configs"
+  data:
+    application.conf: |
+      # Timeout: The number of seconds before receives and sends time out.
+      Timeout 120
+
+      RewriteEngine On
+      Options SymLinksIfOwnerMatch
+
+      <VirtualHost *:80>
+        KeepAlive on
+        ProxyPreserveHost on
+        ProxyPass        /ws/ ws://${NAME}/ws/
+        ProxyPassReverse /ws/ ws://${NAME}/ws/
+        ProxyPass        / http://${NAME}/
+        ProxyPassReverse / http://${NAME}/
+      </VirtualHost>
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}-auth-configs"
+  data:
+    auth-type: internal
+    auth-configuration.conf: |
+      # External Authentication Configuration File
+      #
+      # For details on usage please see https://github.com/ManageIQ/manageiq-pods/blob/master/README.md#configuring-external-authentication
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+    annotations:
+      description: Exposes the httpd server
+      service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+  spec:
+    ports:
+    - name: http
+      port: 80
+      targetPort: 80
+    selector:
+      name: httpd
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy httpd
+  spec:
+    strategy:
+      type: Recreate
+      recreateParams:
+        timeoutSeconds: 1200
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${HTTPD_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${HTTPD_SERVICE_NAME}"
+        labels:
+          name: "${HTTPD_SERVICE_NAME}"
+      spec:
+        volumes:
+        - name: httpd-config
+          configMap:
+            name: "${HTTPD_SERVICE_NAME}-configs"
+        - name: httpd-auth-config
+          configMap:
+            name: "${HTTPD_SERVICE_NAME}-auth-configs"
+        containers:
+        - name: httpd
+          image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
+          ports:
+          - containerPort: 80
+          livenessProbe:
+            exec:
+              command:
+              - pidof
+              - httpd
+            initialDelaySeconds: 15
+            timeoutSeconds: 3
+          readinessProbe:
+            tcpSocket:
+              port: 80
+            initialDelaySeconds: 10
+            timeoutSeconds: 3
+          volumeMounts:
+          - name: httpd-config
+            mountPath: "${HTTPD_CONFIG_DIR}"
+          - name: httpd-auth-config
+            mountPath: "${HTTPD_AUTH_CONFIG_DIR}"
+          resources:
+            requests:
+              memory: "${HTTPD_MEM_REQ}"
+              cpu: "${HTTPD_CPU_REQ}"
+            limits:
+              memory: "${HTTPD_MEM_LIMIT}"
+          env:
+          - name: HTTPD_AUTH_TYPE
+            valueFrom:
+              configMapKeyRef:
+                name: "${HTTPD_SERVICE_NAME}-auth-configs"
+                key: auth-type
+          lifecycle:
+            postStart:
+              exec:
+                command:
+                - "/usr/bin/save-container-environment"
+        serviceAccount: miq-anyuid
+        serviceAccountName: miq-anyuid
+parameters:
+- name: NAME
+  displayName: Name
+  required: true
+  description: The name assigned to all of the frontend objects defined in this template.
+  value: manageiq
+- name: V2_KEY
+  displayName: ManageIQ Encryption Key
+  required: true
+  description: Encryption Key for ManageIQ Passwords
+  from: "[a-zA-Z0-9]{43}"
+  generate: expression
+- name: DATABASE_SERVICE_NAME
+  displayName: PostgreSQL Service Name
+  required: true
+  description: The name of the OpenShift Service exposed for the PostgreSQL container.
+  value: postgresql
+- name: DATABASE_USER
+  displayName: PostgreSQL User
+  required: true
+  description: PostgreSQL user that will access the database.
+  value: root
+- name: DATABASE_PASSWORD
+  displayName: PostgreSQL Password
+  required: true
+  description: Password for the PostgreSQL user.
+  from: "[a-zA-Z0-9]{8}"
+  generate: expression
+- name: DATABASE_IP
+  displayName: PostgreSQL Server IP
+  required: true
+  description: PostgreSQL external server IP used to configure service.
+  value: ''
+- name: DATABASE_PORT
+  displayName: PostgreSQL Server Port
+  required: true
+  description: PostgreSQL external server port used to configure service.
+  value: '5432'
+- name: DATABASE_NAME
+  required: true
+  displayName: PostgreSQL Database Name
+  description: Name of the PostgreSQL database accessed.
+  value: vmdb_production
+- name: DATABASE_REGION
+  required: true
+  displayName: Application Database Region
+  description: Database region that will be used for application.
+  value: '0'
+- name: ANSIBLE_DATABASE_NAME
+  displayName: Ansible PostgreSQL database name
+  required: true
+  description: The database to be used by the Ansible continer
+  value: awx
+- name: MEMCACHED_SERVICE_NAME
+  required: true
+  displayName: Memcached Service Name
+  description: The name of the OpenShift Service exposed for the Memcached container.
+  value: memcached
+- name: MEMCACHED_MAX_MEMORY
+  displayName: Memcached Max Memory
+  description: Memcached maximum memory for memcached object storage in MB.
+  value: '64'
+- name: MEMCACHED_MAX_CONNECTIONS
+  displayName: Memcached Max Connections
+  description: Memcached maximum number of connections allowed.
+  value: '1024'
+- name: MEMCACHED_SLAB_PAGE_SIZE
+  displayName: Memcached Slab Page Size
+  description: Memcached size of each slab page.
+  value: 1m
+- name: ANSIBLE_SERVICE_NAME
+  displayName: Ansible Service Name
+  description: The name of the OpenShift Service exposed for the Ansible container.
+  value: ansible
+- name: ANSIBLE_ADMIN_PASSWORD
+  displayName: Ansible admin User password
+  required: true
+  description: The password for the Ansible container admin user
+  from: "[a-zA-Z0-9]{32}"
+  generate: expression
+- name: ANSIBLE_SECRET_KEY
+  displayName: Ansible Secret Key
+  required: true
+  description: Encryption key for the Ansible container
+  from: "[a-f0-9]{32}"
+  generate: expression
+- name: ANSIBLE_RABBITMQ_USER_NAME
+  displayName: RabbitMQ Username
+  required: true
+  description: Username for the Ansible RabbitMQ Server
+  value: ansible
+- name: ANSIBLE_RABBITMQ_PASSWORD
+  displayName: RabbitMQ Server Password
+  required: true
+  description: Password for the Ansible RabbitMQ Server
+  from: "[a-zA-Z0-9]{32}"
+  generate: expression
+- name: APPLICATION_CPU_REQ
+  displayName: Application Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Application container will need (expressed in millicores).
+  value: 1000m
+- name: MEMCACHED_CPU_REQ
+  displayName: Memcached Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Memcached container will need (expressed in millicores).
+  value: 200m
+- name: ANSIBLE_CPU_REQ
+  displayName: Ansible Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Ansible container will need (expressed in millicores).
+  value: 1000m
+- name: APPLICATION_MEM_REQ
+  displayName: Application Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Application container will need.
+  value: 6144Mi
+- name: MEMCACHED_MEM_REQ
+  displayName: Memcached Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Memcached container will need.
+  value: 64Mi
+- name: ANSIBLE_MEM_REQ
+  displayName: Ansible Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Ansible container will need.
+  value: 2048Mi
+- name: APPLICATION_MEM_LIMIT
+  displayName: Application Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Application container can consume.
+  value: 16384Mi
+- name: MEMCACHED_MEM_LIMIT
+  displayName: Memcached Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Memcached container can consume.
+  value: 256Mi
+- name: ANSIBLE_MEM_LIMIT
+  displayName: Ansible Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Ansible container can consume.
+  value: 8096Mi
+- name: MEMCACHED_IMG_NAME
+  displayName: Memcached Image Name
+  description: This is the Memcached image name requested to deploy.
+  value: docker.io/manageiq/memcached
+- name: MEMCACHED_IMG_TAG
+  displayName: Memcached Image Tag
+  description: This is the Memcached image tag/version requested to deploy.
+  value: latest
+- name: APPLICATION_IMG_NAME
+  displayName: Application Image Name
+  description: This is the Application image name requested to deploy.
+  value: docker.io/manageiq/manageiq-pods
+- name: FRONTEND_APPLICATION_IMG_TAG
+  displayName: Front end Application Image Tag
+  description: This is the ManageIQ Frontend Application image tag/version requested to deploy.
+  value: frontend-latest
+- name: BACKEND_APPLICATION_IMG_TAG
+  displayName: Back end Application Image Tag
+  description: This is the ManageIQ Backend Application image tag/version requested to deploy.
+  value: backend-latest
+- name: ANSIBLE_IMG_NAME
+  displayName: Ansible Image Name
+  description: This is the Ansible image name requested to deploy.
+  value: docker.io/manageiq/embedded-ansible
+- name: ANSIBLE_IMG_TAG
+  displayName: Ansible Image Tag
+  description: This is the Ansible image tag/version requested to deploy.
+  value: latest
+- name: APPLICATION_DOMAIN
+  displayName: Application Hostname
+  description: The exposed hostname that will route to the application service, if left blank a value will be defaulted.
+  value: ''
+- name: APPLICATION_REPLICA_COUNT
+  displayName: Application Replica Count
+  description: This is the number of Application replicas requested to deploy.
+  value: '1'
+- name: APPLICATION_INIT_DELAY
+  displayName: Application Init Delay
+  required: true
+  description: Delay in seconds before we attempt to initialize the application.
+  value: '15'
+- name: APPLICATION_VOLUME_CAPACITY
+  displayName: Application Volume Capacity
+  required: true
+  description: Volume space available for application data.
+  value: 5Gi
+- name: HTTPD_SERVICE_NAME
+  required: true
+  displayName: Apache httpd Service Name
+  description: The name of the OpenShift Service exposed for the httpd container.
+  value: httpd
+- name: HTTPD_IMG_NAME
+  displayName: Apache httpd Image Name
+  description: This is the httpd image name requested to deploy.
+  value: docker.io/manageiq/httpd
+- name: HTTPD_IMG_TAG
+  displayName: Apache httpd Image Tag
+  description: This is the httpd image tag/version requested to deploy.
+  value: latest
+- name: HTTPD_CONFIG_DIR
+  displayName: Apache httpd Configuration Directory
+  description: Directory used to store the Apache configuration files.
+  value: "/etc/httpd/conf.d"
+- name: HTTPD_AUTH_CONFIG_DIR
+  displayName: External Authentication Configuration Directory
+  description: Directory used to store the external authentication configuration files.
+  value: "/etc/httpd/auth-conf.d"
+- name: HTTPD_CPU_REQ
+  displayName: Apache httpd Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the httpd container will need (expressed in millicores).
+  value: 500m
+- name: HTTPD_MEM_REQ
+  displayName: Apache httpd Min RAM Requested
+  required: true
+  description: Minimum amount of memory the httpd container will need.
+  value: 512Mi
+- name: HTTPD_MEM_LIMIT
+  displayName: Apache httpd Max RAM Limit
+  required: true
+  description: Maximum amount of memory the httpd container can consume.
+  value: 8192Mi
diff --git a/roles/openshift_management/files/templates/manageiq/miq-template.yaml b/roles/openshift_management/files/templates/manageiq/miq-template.yaml
new file mode 100644
index 000000000..3f5a12205
--- /dev/null
+++ b/roles/openshift_management/files/templates/manageiq/miq-template.yaml
@@ -0,0 +1,948 @@
+apiVersion: v1
+kind: Template
+labels:
+  template: manageiq
+metadata:
+  name: manageiq
+  annotations:
+    description: ManageIQ appliance with persistent storage
+    tags: instant-app,manageiq,miq
+    iconClass: icon-rails
+objects:
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: miq-orchestrator
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: miq-anyuid
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: miq-privileged
+- apiVersion: v1
+  kind: ServiceAccount
+  metadata:
+    name: miq-httpd
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    name: "${NAME}-secrets"
+  stringData:
+    pg-password: "${DATABASE_PASSWORD}"
+    database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
+    v2-key: "${V2_KEY}"
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    name: "${ANSIBLE_SERVICE_NAME}-secrets"
+  stringData:
+    rabbit-password: "${ANSIBLE_RABBITMQ_PASSWORD}"
+    secret-key: "${ANSIBLE_SECRET_KEY}"
+    admin-password: "${ANSIBLE_ADMIN_PASSWORD}"
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}-configs"
+  data:
+    01_miq_overrides.conf: |
+      #------------------------------------------------------------------------------
+      # CONNECTIONS AND AUTHENTICATION
+      #------------------------------------------------------------------------------
+
+      tcp_keepalives_count = 9
+      tcp_keepalives_idle = 3
+      tcp_keepalives_interval = 75
+
+      #------------------------------------------------------------------------------
+      # RESOURCE USAGE (except WAL)
+      #------------------------------------------------------------------------------
+
+      shared_preload_libraries = 'pglogical,repmgr_funcs'
+      max_worker_processes = 10
+
+      #------------------------------------------------------------------------------
+      # WRITE AHEAD LOG
+      #------------------------------------------------------------------------------
+
+      wal_level = 'logical'
+      wal_log_hints = on
+      wal_buffers = 16MB
+      checkpoint_completion_target = 0.9
+
+      #------------------------------------------------------------------------------
+      # REPLICATION
+      #------------------------------------------------------------------------------
+
+      max_wal_senders = 10
+      wal_sender_timeout = 0
+      max_replication_slots = 10
+      hot_standby = on
+
+      #------------------------------------------------------------------------------
+      # ERROR REPORTING AND LOGGING
+      #------------------------------------------------------------------------------
+
+      log_filename = 'postgresql.log'
+      log_rotation_age = 0
+      log_min_duration_statement = 5000
+      log_connections = on
+      log_disconnections = on
+      log_line_prefix = '%t:%r:%c:%u@%d:[%p]:'
+      log_lock_waits = on
+
+      #------------------------------------------------------------------------------
+      # AUTOVACUUM PARAMETERS
+      #------------------------------------------------------------------------------
+
+      log_autovacuum_min_duration = 0
+      autovacuum_naptime = 5min
+      autovacuum_vacuum_threshold = 500
+      autovacuum_analyze_threshold = 500
+      autovacuum_vacuum_scale_factor = 0.05
+
+      #------------------------------------------------------------------------------
+      # LOCK MANAGEMENT
+      #------------------------------------------------------------------------------
+
+      deadlock_timeout = 5s
+
+      #------------------------------------------------------------------------------
+      # VERSION/PLATFORM COMPATIBILITY
+      #------------------------------------------------------------------------------
+
+      escape_string_warning = off
+      standard_conforming_strings = off
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}-configs"
+  data:
+    application.conf: |
+      # Timeout: The number of seconds before receives and sends time out.
+      Timeout 120
+
+      RewriteEngine On
+      Options SymLinksIfOwnerMatch
+
+      <VirtualHost *:80>
+        KeepAlive on
+        ProxyPreserveHost on
+        ProxyPass        /ws/ ws://${NAME}/ws/
+        ProxyPassReverse /ws/ ws://${NAME}/ws/
+        ProxyPass        / http://${NAME}/
+        ProxyPassReverse / http://${NAME}/
+      </VirtualHost>
+- apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}-auth-configs"
+  data:
+    auth-type: internal
+    auth-configuration.conf: |
+      # External Authentication Configuration File
+      #
+      # For details on usage please see https://github.com/ManageIQ/manageiq-pods/blob/master/README.md#configuring-external-authentication
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Exposes and load balances ManageIQ pods
+      service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"},{"name":"${MEMCACHED_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+    name: "${NAME}"
+  spec:
+    clusterIP: None
+    ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 80
+    selector:
+      name: "${NAME}"
+- apiVersion: v1
+  kind: Route
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+  spec:
+    host: "${APPLICATION_DOMAIN}"
+    port:
+      targetPort: http
+    tls:
+      termination: edge
+      insecureEdgeTerminationPolicy: Redirect
+    to:
+      kind: Service
+      name: "${HTTPD_SERVICE_NAME}"
+- apiVersion: v1
+  kind: PersistentVolumeClaim
+  metadata:
+    name: "${NAME}-${DATABASE_SERVICE_NAME}"
+  spec:
+    accessModes:
+    - ReadWriteOnce
+    resources:
+      requests:
+        storage: "${DATABASE_VOLUME_CAPACITY}"
+- apiVersion: apps/v1beta1
+  kind: StatefulSet
+  metadata:
+    name: "${NAME}"
+    annotations:
+      description: Defines how to deploy the ManageIQ appliance
+  spec:
+    serviceName: "${NAME}"
+    replicas: "${APPLICATION_REPLICA_COUNT}"
+    template:
+      metadata:
+        labels:
+          name: "${NAME}"
+        name: "${NAME}"
+      spec:
+        containers:
+        - name: manageiq
+          image: "${APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
+          livenessProbe:
+            tcpSocket:
+              port: 80
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          readinessProbe:
+            httpGet:
+              path: "/"
+              port: 80
+              scheme: HTTP
+            initialDelaySeconds: 200
+            timeoutSeconds: 3
+          ports:
+          - containerPort: 80
+            protocol: TCP
+          volumeMounts:
+          - name: "${NAME}-server"
+            mountPath: "/persistent"
+          env:
+          - name: MY_POD_NAMESPACE
+            valueFrom:
+              fieldRef:
+                fieldPath: metadata.namespace
+          - name: APPLICATION_INIT_DELAY
+            value: "${APPLICATION_INIT_DELAY}"
+          - name: DATABASE_SERVICE_NAME
+            value: "${DATABASE_SERVICE_NAME}"
+          - name: DATABASE_REGION
+            value: "${DATABASE_REGION}"
+          - name: DATABASE_URL
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: database-url
+          - name: MEMCACHED_SERVER
+            value: "${MEMCACHED_SERVICE_NAME}:11211"
+          - name: MEMCACHED_SERVICE_NAME
+            value: "${MEMCACHED_SERVICE_NAME}"
+          - name: V2_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: v2-key
+          - name: ANSIBLE_SERVICE_NAME
+            value: "${ANSIBLE_SERVICE_NAME}"
+          - name: ANSIBLE_ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          resources:
+            requests:
+              memory: "${APPLICATION_MEM_REQ}"
+              cpu: "${APPLICATION_CPU_REQ}"
+            limits:
+              memory: "${APPLICATION_MEM_LIMIT}"
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                - "/opt/manageiq/container-scripts/sync-pv-data"
+        serviceAccount: miq-orchestrator
+        serviceAccountName: miq-orchestrator
+        terminationGracePeriodSeconds: 90
+    volumeClaimTemplates:
+    - metadata:
+        name: "${NAME}-server"
+        annotations:
+      spec:
+        accessModes:
+        - ReadWriteOnce
+        resources:
+          requests:
+            storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Headless service for ManageIQ backend pods
+    name: "${NAME}-backend"
+  spec:
+    clusterIP: None
+    selector:
+      name: "${NAME}-backend"
+- apiVersion: apps/v1beta1
+  kind: StatefulSet
+  metadata:
+    name: "${NAME}-backend"
+    annotations:
+      description: Defines how to deploy the ManageIQ appliance
+  spec:
+    serviceName: "${NAME}-backend"
+    replicas: 0
+    template:
+      metadata:
+        labels:
+          name: "${NAME}-backend"
+        name: "${NAME}-backend"
+      spec:
+        containers:
+        - name: manageiq
+          image: "${APPLICATION_IMG_NAME}:${BACKEND_APPLICATION_IMG_TAG}"
+          livenessProbe:
+            exec:
+              command:
+              - pidof
+              - MIQ Server
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          volumeMounts:
+          - name: "${NAME}-server"
+            mountPath: "/persistent"
+          env:
+          - name: APPLICATION_INIT_DELAY
+            value: "${APPLICATION_INIT_DELAY}"
+          - name: DATABASE_URL
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: database-url
+          - name: MIQ_SERVER_DEFAULT_ROLES
+            value: database_operations,event,reporting,scheduler,smartstate,ems_operations,ems_inventory,automate
+          - name: FRONTEND_SERVICE_NAME
+            value: "${NAME}"
+          - name: MEMCACHED_SERVER
+            value: "${MEMCACHED_SERVICE_NAME}:11211"
+          - name: V2_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: v2-key
+          - name: ANSIBLE_SERVICE_NAME
+            value: "${ANSIBLE_SERVICE_NAME}"
+          - name: ANSIBLE_ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          resources:
+            requests:
+              memory: "${APPLICATION_MEM_REQ}"
+              cpu: "${APPLICATION_CPU_REQ}"
+            limits:
+              memory: "${APPLICATION_MEM_LIMIT}"
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                - "/opt/manageiq/container-scripts/sync-pv-data"
+        serviceAccount: miq-orchestrator
+        serviceAccountName: miq-orchestrator
+        terminationGracePeriodSeconds: 90
+    volumeClaimTemplates:
+    - metadata:
+        name: "${NAME}-server"
+        annotations:
+      spec:
+        accessModes:
+        - ReadWriteOnce
+        resources:
+          requests:
+            storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${MEMCACHED_SERVICE_NAME}"
+    annotations:
+      description: Exposes the memcached server
+  spec:
+    ports:
+    - name: memcached
+      port: 11211
+      targetPort: 11211
+    selector:
+      name: "${MEMCACHED_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${MEMCACHED_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy memcached
+  spec:
+    strategy:
+      type: Recreate
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${MEMCACHED_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${MEMCACHED_SERVICE_NAME}"
+        labels:
+          name: "${MEMCACHED_SERVICE_NAME}"
+      spec:
+        volumes: []
+        containers:
+        - name: memcached
+          image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
+          ports:
+          - containerPort: 11211
+          readinessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 5
+            tcpSocket:
+              port: 11211
+          livenessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 30
+            tcpSocket:
+              port: 11211
+          volumeMounts: []
+          env:
+          - name: MEMCACHED_MAX_MEMORY
+            value: "${MEMCACHED_MAX_MEMORY}"
+          - name: MEMCACHED_MAX_CONNECTIONS
+            value: "${MEMCACHED_MAX_CONNECTIONS}"
+          - name: MEMCACHED_SLAB_PAGE_SIZE
+            value: "${MEMCACHED_SLAB_PAGE_SIZE}"
+          resources:
+            requests:
+              memory: "${MEMCACHED_MEM_REQ}"
+              cpu: "${MEMCACHED_CPU_REQ}"
+            limits:
+              memory: "${MEMCACHED_MEM_LIMIT}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}"
+    annotations:
+      description: Exposes the database server
+  spec:
+    ports:
+    - name: postgresql
+      port: 5432
+      targetPort: 5432
+    selector:
+      name: "${DATABASE_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${DATABASE_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy the database
+  spec:
+    strategy:
+      type: Recreate
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${DATABASE_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${DATABASE_SERVICE_NAME}"
+        labels:
+          name: "${DATABASE_SERVICE_NAME}"
+      spec:
+        volumes:
+        - name: miq-pgdb-volume
+          persistentVolumeClaim:
+            claimName: "${NAME}-${DATABASE_SERVICE_NAME}"
+        - name: miq-pg-configs
+          configMap:
+            name: "${DATABASE_SERVICE_NAME}-configs"
+        containers:
+        - name: postgresql
+          image: "${POSTGRESQL_IMG_NAME}:${POSTGRESQL_IMG_TAG}"
+          ports:
+          - containerPort: 5432
+          readinessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 15
+            exec:
+              command:
+              - "/bin/sh"
+              - "-i"
+              - "-c"
+              - psql -h 127.0.0.1 -U ${POSTGRESQL_USER} -q -d ${POSTGRESQL_DATABASE} -c 'SELECT 1'
+          livenessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 60
+            tcpSocket:
+              port: 5432
+          volumeMounts:
+          - name: miq-pgdb-volume
+            mountPath: "/var/lib/pgsql/data"
+          - name: miq-pg-configs
+            mountPath: "${POSTGRESQL_CONFIG_DIR}"
+          env:
+          - name: POSTGRESQL_USER
+            value: "${DATABASE_USER}"
+          - name: POSTGRESQL_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: pg-password
+          - name: POSTGRESQL_DATABASE
+            value: "${DATABASE_NAME}"
+          - name: POSTGRESQL_MAX_CONNECTIONS
+            value: "${POSTGRESQL_MAX_CONNECTIONS}"
+          - name: POSTGRESQL_SHARED_BUFFERS
+            value: "${POSTGRESQL_SHARED_BUFFERS}"
+          - name: POSTGRESQL_CONFIG_DIR
+            value: "${POSTGRESQL_CONFIG_DIR}"
+          resources:
+            requests:
+              memory: "${POSTGRESQL_MEM_REQ}"
+              cpu: "${POSTGRESQL_CPU_REQ}"
+            limits:
+              memory: "${POSTGRESQL_MEM_LIMIT}"
+- apiVersion: v1
+  kind: Service
+  metadata:
+    annotations:
+      description: Exposes and load balances Ansible pods
+      service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+    name: "${ANSIBLE_SERVICE_NAME}"
+  spec:
+    ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 80
+    - name: https
+      port: 443
+      protocol: TCP
+      targetPort: 443
+    selector:
+      name: "${ANSIBLE_SERVICE_NAME}"
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${ANSIBLE_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy the Ansible appliance
+  spec:
+    strategy:
+      type: Recreate
+    serviceName: "${ANSIBLE_SERVICE_NAME}"
+    replicas: 0
+    template:
+      metadata:
+        labels:
+          name: "${ANSIBLE_SERVICE_NAME}"
+        name: "${ANSIBLE_SERVICE_NAME}"
+      spec:
+        containers:
+        - name: ansible
+          image: "${ANSIBLE_IMG_NAME}:${ANSIBLE_IMG_TAG}"
+          livenessProbe:
+            tcpSocket:
+              port: 443
+            initialDelaySeconds: 480
+            timeoutSeconds: 3
+          readinessProbe:
+            httpGet:
+              path: "/"
+              port: 443
+              scheme: HTTPS
+            initialDelaySeconds: 200
+            timeoutSeconds: 3
+          ports:
+          - containerPort: 80
+            protocol: TCP
+          - containerPort: 443
+            protocol: TCP
+          securityContext:
+            privileged: true
+          env:
+          - name: ADMIN_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: admin-password
+          - name: RABBITMQ_USER_NAME
+            value: "${ANSIBLE_RABBITMQ_USER_NAME}"
+          - name: RABBITMQ_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: rabbit-password
+          - name: ANSIBLE_SECRET_KEY
+            valueFrom:
+              secretKeyRef:
+                name: "${ANSIBLE_SERVICE_NAME}-secrets"
+                key: secret-key
+          - name: DATABASE_SERVICE_NAME
+            value: "${DATABASE_SERVICE_NAME}"
+          - name: POSTGRESQL_USER
+            value: "${DATABASE_USER}"
+          - name: POSTGRESQL_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "${NAME}-secrets"
+                key: pg-password
+          - name: POSTGRESQL_DATABASE
+            value: "${ANSIBLE_DATABASE_NAME}"
+          resources:
+            requests:
+              memory: "${ANSIBLE_MEM_REQ}"
+              cpu: "${ANSIBLE_CPU_REQ}"
+            limits:
+              memory: "${ANSIBLE_MEM_LIMIT}"
+        serviceAccount: miq-privileged
+        serviceAccountName: miq-privileged
+- apiVersion: v1
+  kind: Service
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+    annotations:
+      description: Exposes the httpd server
+      service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+  spec:
+    ports:
+    - name: http
+      port: 80
+      targetPort: 80
+    selector:
+      name: httpd
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: "${HTTPD_SERVICE_NAME}"
+    annotations:
+      description: Defines how to deploy httpd
+  spec:
+    strategy:
+      type: Recreate
+      recreateParams:
+        timeoutSeconds: 1200
+    triggers:
+    - type: ConfigChange
+    replicas: 1
+    selector:
+      name: "${HTTPD_SERVICE_NAME}"
+    template:
+      metadata:
+        name: "${HTTPD_SERVICE_NAME}"
+        labels:
+          name: "${HTTPD_SERVICE_NAME}"
+      spec:
+        volumes:
+        - name: httpd-config
+          configMap:
+            name: "${HTTPD_SERVICE_NAME}-configs"
+        - name: httpd-auth-config
+          configMap:
+            name: "${HTTPD_SERVICE_NAME}-auth-configs"
+        containers:
+        - name: httpd
+          image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
+          ports:
+          - containerPort: 80
+          livenessProbe:
+            exec:
+              command:
+              - pidof
+              - httpd
+            initialDelaySeconds: 15
+            timeoutSeconds: 3
+          readinessProbe:
+            tcpSocket:
+              port: 80
+            initialDelaySeconds: 10
+            timeoutSeconds: 3
+          volumeMounts:
+          - name: httpd-config
+            mountPath: "${HTTPD_CONFIG_DIR}"
+          - name: httpd-auth-config
+            mountPath: "${HTTPD_AUTH_CONFIG_DIR}"
+          resources:
+            requests:
+              memory: "${HTTPD_MEM_REQ}"
+              cpu: "${HTTPD_CPU_REQ}"
+            limits:
+              memory: "${HTTPD_MEM_LIMIT}"
+          env:
+          - name: HTTPD_AUTH_TYPE
+            valueFrom:
+              configMapKeyRef:
+                name: "${HTTPD_SERVICE_NAME}-auth-configs"
+                key: auth-type
+          lifecycle:
+            postStart:
+              exec:
+                command:
+                - "/usr/bin/save-container-environment"
+        serviceAccount: miq-anyuid
+        serviceAccountName: miq-anyuid
+parameters:
+- name: NAME
+  displayName: Name
+  required: true
+  description: The name assigned to all of the frontend objects defined in this template.
+  value: manageiq
+- name: V2_KEY
+  displayName: ManageIQ Encryption Key
+  required: true
+  description: Encryption Key for ManageIQ Passwords
+  from: "[a-zA-Z0-9]{43}"
+  generate: expression
+- name: DATABASE_SERVICE_NAME
+  displayName: PostgreSQL Service Name
+  required: true
+  description: The name of the OpenShift Service exposed for the PostgreSQL container.
+  value: postgresql
+- name: DATABASE_USER
+  displayName: PostgreSQL User
+  required: true
+  description: PostgreSQL user that will access the database.
+  value: root
+- name: DATABASE_PASSWORD
+  displayName: PostgreSQL Password
+  required: true
+  description: Password for the PostgreSQL user.
+  from: "[a-zA-Z0-9]{8}"
+  generate: expression
+- name: DATABASE_NAME
+  required: true
+  displayName: PostgreSQL Database Name
+  description: Name of the PostgreSQL database accessed.
+  value: vmdb_production
+- name: DATABASE_REGION
+  required: true
+  displayName: Application Database Region
+  description: Database region that will be used for application.
+  value: '0'
+- name: ANSIBLE_DATABASE_NAME
+  displayName: Ansible PostgreSQL database name
+  required: true
+  description: The database to be used by the Ansible continer
+  value: awx
+- name: MEMCACHED_SERVICE_NAME
+  required: true
+  displayName: Memcached Service Name
+  description: The name of the OpenShift Service exposed for the Memcached container.
+  value: memcached
+- name: MEMCACHED_MAX_MEMORY
+  displayName: Memcached Max Memory
+  description: Memcached maximum memory for memcached object storage in MB.
+  value: '64'
+- name: MEMCACHED_MAX_CONNECTIONS
+  displayName: Memcached Max Connections
+  description: Memcached maximum number of connections allowed.
+  value: '1024'
+- name: MEMCACHED_SLAB_PAGE_SIZE
+  displayName: Memcached Slab Page Size
+  description: Memcached size of each slab page.
+  value: 1m
+- name: POSTGRESQL_CONFIG_DIR
+  displayName: PostgreSQL Configuration Overrides
+  description: Directory used to store PostgreSQL configuration overrides.
+  value: "/var/lib/pgsql/conf.d"
+- name: POSTGRESQL_MAX_CONNECTIONS
+  displayName: PostgreSQL Max Connections
+  description: PostgreSQL maximum number of database connections allowed.
+  value: '1000'
+- name: POSTGRESQL_SHARED_BUFFERS
+  displayName: PostgreSQL Shared Buffer Amount
+  description: Amount of memory dedicated for PostgreSQL shared memory buffers.
+  value: 1GB
+- name: ANSIBLE_SERVICE_NAME
+  displayName: Ansible Service Name
+  description: The name of the OpenShift Service exposed for the Ansible container.
+  value: ansible
+- name: ANSIBLE_ADMIN_PASSWORD
+  displayName: Ansible admin User password
+  required: true
+  description: The password for the Ansible container admin user
+  from: "[a-zA-Z0-9]{32}"
+  generate: expression
+- name: ANSIBLE_SECRET_KEY
+  displayName: Ansible Secret Key
+  required: true
+  description: Encryption key for the Ansible container
+  from: "[a-f0-9]{32}"
+  generate: expression
+- name: ANSIBLE_RABBITMQ_USER_NAME
+  displayName: RabbitMQ Username
+  required: true
+  description: Username for the Ansible RabbitMQ Server
+  value: ansible
+- name: ANSIBLE_RABBITMQ_PASSWORD
+  displayName: RabbitMQ Server Password
+  required: true
+  description: Password for the Ansible RabbitMQ Server
+  from: "[a-zA-Z0-9]{32}"
+  generate: expression
+- name: APPLICATION_CPU_REQ
+  displayName: Application Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Application container will need (expressed in millicores).
+  value: 1000m
+- name: POSTGRESQL_CPU_REQ
+  displayName: PostgreSQL Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the PostgreSQL container will need (expressed in millicores).
+  value: 500m
+- name: MEMCACHED_CPU_REQ
+  displayName: Memcached Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Memcached container will need (expressed in millicores).
+  value: 200m
+- name: ANSIBLE_CPU_REQ
+  displayName: Ansible Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the Ansible container will need (expressed in millicores).
+  value: 1000m
+- name: APPLICATION_MEM_REQ
+  displayName: Application Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Application container will need.
+  value: 6144Mi
+- name: POSTGRESQL_MEM_REQ
+  displayName: PostgreSQL Min RAM Requested
+  required: true
+  description: Minimum amount of memory the PostgreSQL container will need.
+  value: 4Gi
+- name: MEMCACHED_MEM_REQ
+  displayName: Memcached Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Memcached container will need.
+  value: 64Mi
+- name: ANSIBLE_MEM_REQ
+  displayName: Ansible Min RAM Requested
+  required: true
+  description: Minimum amount of memory the Ansible container will need.
+  value: 2048Mi
+- name: APPLICATION_MEM_LIMIT
+  displayName: Application Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Application container can consume.
+  value: 16384Mi
+- name: POSTGRESQL_MEM_LIMIT
+  displayName: PostgreSQL Max RAM Limit
+  required: true
+  description: Maximum amount of memory the PostgreSQL container can consume.
+  value: 8Gi
+- name: MEMCACHED_MEM_LIMIT
+  displayName: Memcached Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Memcached container can consume.
+  value: 256Mi
+- name: ANSIBLE_MEM_LIMIT
+  displayName: Ansible Max RAM Limit
+  required: true
+  description: Maximum amount of memory the Ansible container can consume.
+  value: 8096Mi
+- name: POSTGRESQL_IMG_NAME
+  displayName: PostgreSQL Image Name
+  description: This is the PostgreSQL image name requested to deploy.
+  value: docker.io/manageiq/postgresql
+- name: POSTGRESQL_IMG_TAG
+  displayName: PostgreSQL Image Tag
+  description: This is the PostgreSQL image tag/version requested to deploy.
+  value: latest
+- name: MEMCACHED_IMG_NAME
+  displayName: Memcached Image Name
+  description: This is the Memcached image name requested to deploy.
+  value: docker.io/manageiq/memcached
+- name: MEMCACHED_IMG_TAG
+  displayName: Memcached Image Tag
+  description: This is the Memcached image tag/version requested to deploy.
+  value: latest
+- name: APPLICATION_IMG_NAME
+  displayName: Application Image Name
+  description: This is the Application image name requested to deploy.
+  value: docker.io/manageiq/manageiq-pods
+- name: FRONTEND_APPLICATION_IMG_TAG
+  displayName: Front end Application Image Tag
+  description: This is the ManageIQ Frontend Application image tag/version requested to deploy.
+  value: frontend-latest
+- name: BACKEND_APPLICATION_IMG_TAG
+  displayName: Back end Application Image Tag
+  description: This is the ManageIQ Backend Application image tag/version requested to deploy.
+  value: backend-latest
+- name: ANSIBLE_IMG_NAME
+  displayName: Ansible Image Name
+  description: This is the Ansible image name requested to deploy.
+  value: docker.io/manageiq/embedded-ansible
+- name: ANSIBLE_IMG_TAG
+  displayName: Ansible Image Tag
+  description: This is the Ansible image tag/version requested to deploy.
+  value: latest
+- name: APPLICATION_DOMAIN
+  displayName: Application Hostname
+  description: The exposed hostname that will route to the application service, if left blank a value will be defaulted.
+  value: ''
+- name: APPLICATION_REPLICA_COUNT
+  displayName: Application Replica Count
+  description: This is the number of Application replicas requested to deploy.
+  value: '1'
+- name: APPLICATION_INIT_DELAY
+  displayName: Application Init Delay
+  required: true
+  description: Delay in seconds before we attempt to initialize the application.
+  value: '15'
+- name: APPLICATION_VOLUME_CAPACITY
+  displayName: Application Volume Capacity
+  required: true
+  description: Volume space available for application data.
+  value: 5Gi
+- name: DATABASE_VOLUME_CAPACITY
+  displayName: Database Volume Capacity
+  required: true
+  description: Volume space available for database.
+  value: 15Gi
+- name: HTTPD_SERVICE_NAME
+  required: true
+  displayName: Apache httpd Service Name
+  description: The name of the OpenShift Service exposed for the httpd container.
+  value: httpd
+- name: HTTPD_IMG_NAME
+  displayName: Apache httpd Image Name
+  description: This is the httpd image name requested to deploy.
+  value: docker.io/manageiq/httpd
+- name: HTTPD_IMG_TAG
+  displayName: Apache httpd Image Tag
+  description: This is the httpd image tag/version requested to deploy.
+  value: latest
+- name: HTTPD_CONFIG_DIR
+  displayName: Apache Configuration Directory
+  description: Directory used to store the Apache configuration files.
+  value: "/etc/httpd/conf.d"
+- name: HTTPD_AUTH_CONFIG_DIR
+  displayName: External Authentication Configuration Directory
+  description: Directory used to store the external authentication configuration files.
+  value: "/etc/httpd/auth-conf.d"
+- name: HTTPD_CPU_REQ
+  displayName: Apache httpd Min CPU Requested
+  required: true
+  description: Minimum amount of CPU time the httpd container will need (expressed in millicores).
+  value: 500m
+- name: HTTPD_MEM_REQ
+  displayName: Apache httpd Min RAM Requested
+  required: true
+  description: Minimum amount of memory the httpd container will need.
+  value: 512Mi
+- name: HTTPD_MEM_LIMIT
+  displayName: Apache httpd Max RAM Limit
+  required: true
+  description: Maximum amount of memory the httpd container can consume.
+  value: 8192Mi
-- 
cgit v1.2.3