diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 44e6bfab14824d1ab276848be4d73dfeade1b818..287365758ceaa7b1502ab4fc63cccf6c95cd9e5a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -173,6 +173,46 @@ build_login_image:
     - if: $PIPELINE_TARGET == "build" && $BUILD_TARGET == "login"
       when: always
 
+build_ood_image:
+  stage: build
+  environment:
+    name: $ENV
+  tags:
+    - build
+  script:
+    - *update_ansible_repo
+    - *get_ansible_files
+    # packer vars for job env
+    - export PKR_VAR_flavor="${OOD_BUILD_FLAVOR:-$PKR_VAR_flavor}"
+    - export PKR_VAR_build_instance_name="${BUILD_TARGET}-${EXT_REPO_HEAD}"
+    - export PKR_VAR_image_date_suffix=false
+    - export PKR_VAR_image_name="${BUILD_TARGET}-${BUILD_DATE}"
+    - |
+      if [ $ENV = 'knightly' || $ENV = 'prod' ]; then
+        curl --header "PRIVATE-TOKEN: ${ANSIBLE_VAR_TOKEN}" \
+        "${CI_API_V4_URL}/projects/2836/repository/files/knightly/raw?ref=main" \
+        -o CRI_XCBC/group_vars/$ENV
+        'sed -i -E "s/(lts_access_key: ).*/\1\"${AWS_ACCESS_KEY_ID}\"/" CRI_XCBC/group_vars/$ENV'
+        'sed -i -E "s/(lts_secret_key: ).*/\1\"${AWS_SECRET_ACCESS_KEY}\"/" CRI_XCBC/group_vars/$ENV'
+        'sed -i -E "s/(user_register_app_key: ).*/\1\"${SELF_REG_APP_KEY}\"/" CRI_XCBC/group_vars/$ENV'
+        'sed -i -E "s/(celery_user_password: ).*/\1\"${CELERY_PASSWD}\"/" CRI_XCBC/group_vars/$ENV'
+        'sed -i -E "s|(ssh_pub_key: ).*|\1\"{{ lookup(''file'', ''${SSH_PUB_KEY}'') }}\"|" CRI_XCBC/group_vars/$ENV'
+      fi
+    # packer commands
+    - packer init openstack-ood
+    - packer validate openstack-ood
+    - packer build -machine-readable openstack-ood | tee ood_build.log
+    - export BUILT_OOD_IMAGE_ID=$(grep 'Image:' ood_build.log | awk '{print $4}')
+    - echo BUILT_OOD_IMAGE_ID=${BUILT_OOD_IMAGE_ID} | tee -a $CI_PROJECT_DIR/image.env
+    # set image properties with repo state
+    - openstack image set --property EXT_PR_SRC_REPO=${EXT_PR_SRC_REPO} --property EXT_PR_SRC_BRANCH_SHA=${EXT_PR_SRC_BRANCH_SHA} --property EXT_PR_TARGET_REPO=${EXT_PR_TARGET_REPO} --property EXT_PR_TARGET_BRANCH_SHA=${EXT_PR_TARGET_BRANCH_SHA} --property PACKER_IMAGE_HEAD=${CI_COMMIT_SHORT_SHA} ${BUILT_OOD_IMAGE_ID}
+  artifacts:
+    reports:
+      dotenv: image.env
+  rules:
+    - if: $PIPELINE_TARGET == "build" && $BUILD_TARGET == "ood"
+      when: always
+
 deploy_http_proxy_node:
   stage: deploy
   environment:
diff --git a/ansible/ood.yml b/ansible/ood.yml
index 089ffd3ee0d3cece4cc03c3a2a8a047083fa2b6d..37c09aa4e34466ae9c52c20699c868a70642a346 100644
--- a/ansible/ood.yml
+++ b/ansible/ood.yml
@@ -6,6 +6,3 @@
     - { name: 'fix_centos_repo', tags: 'fix_centos_repo' }
     - { name: 'install_packages', tags: 'install_packages' }
     - { name: 'install_zsh', tags: 'install_zsh' }
-
-- name: Setup node for use as a virtual cheaha node
-  ansible.builtin.import_playbook: cheaha.yml
diff --git a/openstack-ood/nodeimage.pkr.hcl b/openstack-ood/nodeimage.pkr.hcl
index 61b05ef820cc0bc2cf3d413e1f0b3af54212be7f..1a1374419cd8ed985a4cde57378154a5cf07ff3f 100644
--- a/openstack-ood/nodeimage.pkr.hcl
+++ b/openstack-ood/nodeimage.pkr.hcl
@@ -57,4 +57,13 @@ build {
       "--extra-vars", "${var.extra_vars}"
     ]
   }
+
+  provisioner "shell" {
+    inline = [
+      "sudo yum install -y libselinux-python3 python3 python3-pip tmux vim git bash-completion curl wget unzip",
+      "sudo python3 -m pip install --upgrade pip",
+      "sudo pip3 install s3cmd==2.3.0 ansible==4.10.0 python-openstackclient==5.8.0"
+    ]
+  }
+
 }
diff --git a/openstack-ood/variables.pkr.hcl b/openstack-ood/variables.pkr.hcl
index b87cb6dff0443bf9874e14802a8af7b660362e36..3e20d6dc9e6b35ccac6b7bdb03f5ec28e8d24cce 100644
--- a/openstack-ood/variables.pkr.hcl
+++ b/openstack-ood/variables.pkr.hcl
@@ -1,5 +1,6 @@
 variable "root_ssh_key" {
   type        = string
+  default     = ""
   description = "The root key to use for ssh"
 }