diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d2bf24ff1d13ff01172652110a5daea06abf63e2..129f6a8cea2b952ff90e9262a1ac0ceb476a6851 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -20,7 +20,7 @@ variables:
   PKR_VAR_security_groups: '["allow-ssh"]'
   PKR_VAR_skip_create_image: "false"
   PKR_VAR_ssh_username: "centos"
-  PKR_VAR_networks: '["8cf2f12e-905d-46d9-bc70-b0897c65f75a"]'
+  PKR_VAR_networks: '["0295b9ca-ba14-4d08-8c57-78a4c07345eb"]'
   GIT_AUTHOR_NAME: "Gitlab runner"
   GIT_AUTHOR_EMAIL: "gitlab@runner"
   INSTANCE_FLAVOR: "m1.medium-ruffner"
@@ -107,6 +107,44 @@ workflow:
     reports:
       dotenv: image.env
 
+.build_compute_image_template: &build_compute_image_template
+  script:
+    - *update_ansible_repo
+    - *get_ansible_files
+    # packer vars for job env
+    - export PKR_VAR_flavor="${PROXY_BUILD_FLAVOR:-$PKR_VAR_flavor}"
+    - export PKR_VAR_build_instance_name="${BUILD_TARGET}-${EXT_REPO_HEAD}"
+    - export PKR_VAR_image_date_suffix=false
+    - |
+      if [ $CI_PIPELINE_SOURCE == 'merge_request_event' ]; then
+        export PKR_VAR_image_name="${BUILD_TARGET}-PR-${CI_MERGE_REQUEST_IID}"
+      elif [ $CI_PIPELINE_SOURCE == 'schedule' ]; then
+        export PKR_VAR_image_name="${BUILD_TARGET}-${BUILD_DATE}"
+      fi
+    # packer commands
+    - packer init openstack-compute
+    - packer validate openstack-compute
+    - packer build -machine-readable openstack-compute | tee compute_build.log
+    - export BUILT_COMPUTE_IMAGE_ID=$(grep 'Image:' compute_build.log | awk '{print $4}')
+    - echo BUILT_COMPUTE_IMAGE_ID=${BUILT_COMPUTE_IMAGE_ID} | tee -a $CI_PROJECT_DIR/image.env
+    - openstack image set --property CRI_XCBC_prod=${CRI_XCBC_prod} --property CRI_XCBC_dev=${CRI_XCBC_dev} --property PACKER_IMAGE_HEAD=${PACKER_IMAGE_HEAD} ${BUILT_COMPUTE_IMAGE_ID}
+  artifacts:
+    reports:
+      dotenv: image.env
+
+build_compute_image:
+  stage: build
+  environment:
+    name: $ENV
+  tags:
+    - build
+  variables:
+    PROXY_ENABLE_VAR: "enable_compute"
+  <<: *build_compute_image_template
+  rules:
+    - if: $PIPELINE_TARGET == "build" && $BUILD_TARGET == "compute"
+      when: always
+
 build_http_proxy_image:
   stage: build
   environment:
@@ -133,6 +171,34 @@ build_ssh_proxy_image:
     - if: $PIPELINE_TARGET == "build" && $BUILD_TARGET == "ssh-proxy"
       when: always
 
+
+deploy_compute_node:
+  stage: deploy
+  environment:
+    name: $ENV
+  tags:
+    - build
+  script:
+    - openstack image set --accept $BUILT_COMPUTE_IMAGE_ID || true
+    - FAILED=false
+    - |
+      cat > user_data.txt <<EOF
+      echo "$DEV_KEY" >> /root/.ssh/authorized_keys
+      EOF
+    - |
+      export cmd="openstack server create"
+      cmd+=" -c id -f value --image $BUILT_COMPUTE_IMAGE_ID"
+      cmd+=" --flavor $INSTANCE_FLAVOR"
+      cmd+=" --network $PKR_VAR_networks"
+      cmd+=" --security-group webserver_sec_group"
+      cmd+=" --security-group allow-ssh"
+      cmd+=" --user-data user_data.txt"
+
+  rules:
+    - if: $PIPELINE_TARGET == "deploy" && $BUILT_COMPUTE_IMAGE_ID
+      when: always
+
+
 deploy_http_proxy_node:
   stage: deploy
   environment:
diff --git a/ansible/compute.yml b/ansible/compute.yml
index 2907d08077a8431a717209aec22fc362bf2391a7..400992914c594449e23f024038a4b5c37076f95b 100644
--- a/ansible/compute.yml
+++ b/ansible/compute.yml
@@ -8,5 +8,3 @@
     - { name: 'pam_slurm_adopt', tags: 'pam_slurm_adopt' }
     - { name: 'install_nhc', tags: 'install_nhc'}
 
-- name: Setup node for use as a virtual cheaha node
-  ansible.builtin.import_playbook: cheaha.yml
diff --git a/openstack-compute/nodeimage.pkr.hcl b/openstack-compute/nodeimage.pkr.hcl
index 15941bab1900a056d3d67bdba2db2bd5d94a31fb..0df7158b0288a3dbf94f6ee4e500d362a953df04 100644
--- a/openstack-compute/nodeimage.pkr.hcl
+++ b/openstack-compute/nodeimage.pkr.hcl
@@ -36,6 +36,17 @@ source "openstack" "image" {
 build {
   sources = ["source.openstack.image"]
 
+  provisioner "ansible" {
+    use_proxy     = false
+    user          = var.ssh_username
+    groups        = ["base"]
+    playbook_file = "./ansible/base.yml"
+    roles_path    = "./ansible/roles"
+    extra_arguments = [
+      "--extra-vars", "root_ssh_key='${var.root_ssh_key}'"
+    ]
+  }
+  
   provisioner "ansible" {
     use_proxy     = false
     user          = var.ssh_username
diff --git a/openstack-compute/variables.pkr.hcl b/openstack-compute/variables.pkr.hcl
index 20efd641406f81250b3cb1cc6514f5078ee2a503..d3681394fe7c66990a5b9f1507f38f7dbc74d025 100644
--- a/openstack-compute/variables.pkr.hcl
+++ b/openstack-compute/variables.pkr.hcl
@@ -1,6 +1,7 @@
 variable "root_ssh_key" {
   type        = string
   description = "The root key to use for ssh"
+  default     = ""
 }
 
 variable "image_name" {