fix: feed pre-existing ssh key to the heat stack tailoring nova api 2.92 for molecule scenario (#762)

Co-authored-by: okozachenko1203 <okozachenko1203@users.noreply.github.com>
diff --git a/molecule/default/create.yml b/molecule/default/create.yml
index 84b5858..e2298d7 100644
--- a/molecule/default/create.yml
+++ b/molecule/default/create.yml
@@ -36,6 +36,12 @@
     boot_from_volume: "{{ lookup('env', 'ATMOSPHERE_BOOT_FROM_VOLUME') | bool }}"
     create_bastion_host: "{{ lookup('env', 'ATMOSPHERE_CREATE_BASTION_HOST') | bool }}"
   tasks:
+    - name: Generate a SSH key for stack
+      community.crypto.openssh_keypair:
+        path: "{{ identity_file }}"
+        regenerate: full_idempotence
+      register: _os_stack_keypair
+
     - name: create stack
       openstack.cloud.stack:
         name: "{{ stack_name }}"
@@ -50,18 +56,17 @@
           nameservers: "{{ nameservers }}"
           boot_from_volume: "{{  boot_from_volume }}"
           create_bastion_host: "{{ create_bastion_host }}"
+          public_key_pair: "{{ _os_stack_keypair.public_key }}"
       register: _os_stack
     - debug:
         msg: "{{ _os_stack.stack }}"
 
     - name: grab list of all ip addresses
       ansible.builtin.set_fact:
-        key_pair: "{{ _os_stack.stack.outputs | json_query(key_query) | first }}"
         controller_ips: "{{ _os_stack.stack.outputs | community.general.json_query(controller_query) | first }}"
         storage_ips: "{{ _os_stack.stack.outputs | community.general.json_query(storage_query) | first }}"
         compute_ips: "{{ _os_stack.stack.outputs | community.general.json_query(compute_query) | first }}"
       vars:
-        key_query: "[?output_key=='key_pair'].output_value"
         controller_query: "[?output_key=='controller_floating_ip_addresses'].output_value"
         storage_query: "[?output_key=='storage_floating_ip_addresses'].output_value"
         compute_query: "[?output_key=='compute_floating_ip_addresses'].output_value"
@@ -76,12 +81,6 @@
       delay: 10
       loop: "{{ controller_ips + storage_ips + compute_ips }}"
 
-    - name: generate private key file
-      ansible.builtin.copy:
-        dest: "{{ identity_file }}"
-        content: "{{ key_pair }}"
-        mode: 0600
-
     - name: generate instance config file
       copy:
         content: "{{ instance_config | to_yaml }}"
diff --git a/molecule/default/heat/stack.yaml b/molecule/default/heat/stack.yaml
index c5b171f..e40d43b 100644
--- a/molecule/default/heat/stack.yaml
+++ b/molecule/default/heat/stack.yaml
@@ -35,6 +35,9 @@
     constraints:
       - custom_constraint: neutron.network
 
+  public_key_pair:
+    type: string
+
   image:
     type: string
     constraints:
@@ -133,7 +136,7 @@
     type: OS::Nova::KeyPair
     properties:
       name: { get_param: OS::stack_id }
-      save_private_key: true
+      public_key: { get_param: public_key_pair }
 
   bastion_host:
     type: server.yaml
@@ -221,5 +224,3 @@
     value: { get_attr: [storage, floating_ip_address] }
   compute_floating_ip_addresses:
     value: { get_attr: [compute, floating_ip_address] }
-  key_pair:
-    value: { get_attr: [key_pair, private_key] }
diff --git a/playbooks/generate_workspace.yml b/playbooks/generate_workspace.yml
index 4eb2bcd..3df0c4a 100644
--- a/playbooks/generate_workspace.yml
+++ b/playbooks/generate_workspace.yml
@@ -398,6 +398,7 @@
               cut -d':' -f2
 
     - name: Generate SSH keys for missing variables
+      when: item.path is defined
       community.crypto.openssh_keypair:
         path: "{{ item.path }}"
         regenerate: full_idempotence
@@ -407,6 +408,7 @@
         label: "{{ item.item }}"
 
     - name: Set values for SSH keys
+      when: item.path is defined
       ansible.builtin.set_fact:
         secrets: "{{ secrets | default({}) | combine({item.item: lookup('file', item.path)}) }}"
       loop: "{{ _ssh_key_file.results }}"
@@ -414,6 +416,7 @@
         label: "{{ item.item }}"
 
     - name: Delete the temporary files generated for SSH keys
+      when: item.path is defined
       ansible.builtin.file:
         path: "{{ item.path }}"
         state: absent