diff --git a/plugins/modules/create_heat_stack.py b/plugins/modules/create_heat_stack.py index 94501ef6..41e520b9 100644 --- a/plugins/modules/create_heat_stack.py +++ b/plugins/modules/create_heat_stack.py @@ -45,6 +45,12 @@ required: false type: int default: 600 + output_dir: + description: + - Directory where heat-stack-info.txt will be written after successful stack creation. + - The file is written on the same host that runs the module, using the exact path provided. + required: false + type: str """ EXAMPLES = r""" @@ -72,4 +78,9 @@ returned: success type: dict sample: {"id": "stack-uuid", "name": "os-migrate-20240120", "status": "CREATE_COMPLETE"} +info_path: + description: Path to the written heat-stack-info.txt file + returned: when output_dir is provided + type: str + sample: "/opt/os-migrate/heat-stack-info.txt" """ diff --git a/plugins/modules/src/create_heat_stack/create_heat_stack.go b/plugins/modules/src/create_heat_stack/create_heat_stack.go index 4c09fa29..987d59da 100644 --- a/plugins/modules/src/create_heat_stack/create_heat_stack.go +++ b/plugins/modules/src/create_heat_stack/create_heat_stack.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "os" + "path/filepath" "time" "vmware-migration-kit/plugins/module_utils/ansible" @@ -40,6 +41,7 @@ type ModuleArgs struct { Parameters map[string]interface{} `json:"parameters"` Wait bool `json:"wait"` Timeout int `json:"timeout"` + OutputDir string `json:"output_dir"` } type StackInfo struct { @@ -49,10 +51,11 @@ type StackInfo struct { } type Response struct { - Msg string `json:"msg"` - Changed bool `json:"changed"` - Failed bool `json:"failed"` - Stack StackInfo `json:"stack,omitempty"` + Msg string `json:"msg"` + Changed bool `json:"changed"` + Failed bool `json:"failed"` + Stack StackInfo `json:"stack,omitempty"` + InfoPath string `json:"info_path,omitempty"` } func exitJson(responseBody Response) { @@ -216,5 +219,16 @@ func main() { Status: finalStack.Status, }, } + + if moduleArgs.OutputDir != "" { + infoPath := filepath.Join(moduleArgs.OutputDir, "heat-stack-info.txt") + content := fmt.Sprintf("Stack Name: %s\nStack ID: %s\nStatus: %s\nTemplate: %s\n", + finalStack.Name, finalStack.ID, finalStack.Status, moduleArgs.TemplatePath) + if err := os.WriteFile(infoPath, []byte(content), 0644); err != nil { + ansible.FailJson(ansible.Response{Msg: "Failed to write stack info file: " + err.Error()}) + } + response.InfoPath = infoPath + } + exitJson(response) } diff --git a/roles/import_workloads/tasks/heat_deploy.yml b/roles/import_workloads/tasks/heat_deploy.yml index d8ad0558..526cbdd0 100644 --- a/roles/import_workloads/tasks/heat_deploy.yml +++ b/roles/import_workloads/tasks/heat_deploy.yml @@ -86,6 +86,7 @@ parameters: "{{ heat_template_generated.parameters }}" wait: true timeout: 600 + output_dir: "{{ os_migrate_vmw_data_dir }}" register: heat_stack_created when: import_workloads_heat_auto_deploy | default(true) | bool @@ -101,45 +102,7 @@ View events: openstack stack event list {{ heat_stack_created.stack.id }} when: heat_stack_created is defined and not heat_stack_created.failed -- name: Save Heat stack information to file - ansible.builtin.copy: - content: | - # Heat Stack Information - Stack Name: {{ heat_stack_created.stack.name }} - Stack ID: {{ heat_stack_created.stack.id }} - Status: {{ heat_stack_created.stack.status }} - Template: {{ heat_template_generated.template_path }} - - ## Migrated VMs - {% for vm in heat_vms_data %} - - {{ vm.name }}: - Boot Volume: {{ vm.boot_volume_id }} - Flavor: {{ vm.flavor }} - Network: {{ vm.network }} - {% endfor %} - - ## Heat Management Commands - # View stack details - openstack stack show {{ heat_stack_created.stack.id }} - - # List stack resources - openstack stack resource list {{ heat_stack_created.stack.id }} - - # View stack events - openstack stack event list {{ heat_stack_created.stack.id }} - - # Update stack (with template changes) - openstack stack update {{ heat_stack_created.stack.id }} -t {{ heat_template_generated.template_path }} - - # Delete stack (WARNING: This will delete managed resources - instances and ports) - # Note: Cinder volumes are external and will NOT be deleted - openstack stack delete {{ heat_stack_created.stack.id }} - dest: "{{ os_migrate_vmw_data_dir }}/heat-stack-info.txt" - mode: '0644' - when: heat_stack_created is defined and not heat_stack_created.failed - delegate_to: localhost - - name: Display saved stack info location ansible.builtin.debug: - msg: "Stack information saved to {{ os_migrate_vmw_data_dir }}/heat-stack-info.txt" + msg: "Stack information saved to {{ heat_stack_created.info_path }}" when: heat_stack_created is defined and not heat_stack_created.failed