Vinay Upadhyay
Vinay Upadhyay

Reputation: 37

Unable to create a VM from captured azure image using ansible

I am trying to create an Azure windows image using Ansible as a part of my infra automation project. On executing the playbook every thing goes through:

enter image description here

My playbook looks something like this :

---

- hosts: localhost
  gather_facts: yes
  roles:
   - role: azure_vmcreator


- hosts: azure_vms
  gather_facts: no
  roles:
   - role: Generalize-windows



- hosts: localhost
  gather_facts: yes
  roles: 
    - role: azure_imagecreator

There are two roles Generalize-windows and azure-imageCreator.

The generalize-windows.yml generalizes the windows from inside like this:

---
- name: sysprep windows
  win_shell: Start-Process -FilePath C:\Windows\System32\Sysprep\Sysprep.exe -Verb RunAs -ArgumentList '/generalize /oobe /reboot /quite'

where as the azure-imageCreator deallocates, generalize and capture the image :

- name: deallocate vm
  azure_rm_virtualmachine:
  resource_group: "{{ resource_group_vm }}"
  name: "{{ vm_name }}{{random_suffix}}-image"
  allocated: no


- name: Call REST API - VirtualMachines_Generalize
  azure_rm_resource:
     api_version: '2017-12-01'
     method: POST
     resource_group: "{{ resource_group_vm }}"
     provider: compute
     resource_type: virtualmachines
     resource_name: "{{ vm_name }}{{random_suffix}}"
     subresource:
       - type: generalize  

- name: Create an image from a virtual machine
  azure_rm_image:
    resource_group: "{{ resource_group_vm }}"
    os_type: Windows
    name: "{{ vm_name }}{{random_suffix}}-image"
    source: "{{ vm_name }}{{random_suffix}}"

now when i create an vm out of the image created by ansible i get below error:

"details": [
    {
      "code": "Conflict",
      "message": "{\r\n  \"status\": \"Failed\",\r\n  \"error\": {\r\n    \"code\": \"ResourceDeploymentFailure\",\r\n    \"message\": \"The resource operation completed with terminal provisioning state 'Failed'.\",\r\n    \"details\": [\r\n      {\r\n        \"code\": \"OSProvisioningClientError\",\r\n        \"message\": \"OS Provisioning for VM 'p' did not finish in the allotted time. However, the VM guest agent was detected running. This suggests the guest OS has not been properly prepared to be used as a VM image (with CreateOption=FromImage). To resolve this issue, either use the VHD as is with CreateOption=Attach or prepare it properly for use as an image:\\r\\n * Instructions for Windows: https://azure.microsoft.com/documentation/articles/virtual-machines-windows-upload-image/ \\r\\n * Instructions for Linux: https://azure.microsoft.com/documentation/articles/virtual-machines-linux-capture-image/ \"\r\n      }\r\n    ]\r\n  }\r\n}"
    }
  ]
}

Can someone please tell me where am I wrong?

Upvotes: 0

Views: 1379

Answers (2)

AlbinoAnteater
AlbinoAnteater

Reputation: 26

@vinay, I had the same issue.
The problem I was having was 3 fold.
First is that the deallocation causes the Azure VM to change the powersteate to stopped. and the 'generalized: true' required the powerstate to be running.
Second was that that win_shell did not behave as I expected it (more reading for me to do on that) and that win_command recieved an error: "An exception occurred during task execution. To see the full traceback, use -vvv. The error was: InvalidCredentialsError: the specified credentials were rejected by the server."
This was due to sysprep ending all connections to the server in order to generalize it.
The 3rd is the wait time after the Sysprep has be run.

Once i realized that i needed to use /quit rather than /shutdown and that I needed to use win_command and that I needed a wait time, all was well.
In the end it looks something like this.
This is with ansible 2.8.6 BTW.

tasks:
  - name: "Sysprep VM"
    win_command: C:\Windows\System32\Sysprep\Sysprep.exe /generalize /oobe /quiet /mode:vm /quit
    ignore_errors: True

  - name: "Sysprep Wait Time"
    pause:
      minutes: 5

  - name: "Generalize VM"
    delegate_to: localhost
    azure_rm_virtualmachine:
      name:           "{{ vmss_template_name }}"
      resource_group: "{{ resource_template_group }}"
      generalized:    true

  - name: "Check if VM is generalized"
    delegate_to: localhost
    azure_rm_virtualmachine_facts:
        resource_group: "{{ resource_template_group }}"
        name: "{{ vmss_template_name }}"
    register: generalized_output

  - assert:
      that: generalized_output.vms[0].power_state == 'generalized'

  - name: "Create Image from VM"
    delegate_to: localhost
    azure_rm_image:
      name:           "{{ vmss_template_name }}"
      resource_group: "{{ resource_template_group }}"
      source:         "{{ vmss_template_name }}"

In the end I'm sure there are more/better ways, but I'm fairly new to ansible and this worked for my POC.
Hope this helps.

AA

Upvotes: 1

Bharath Kumar
Bharath Kumar

Reputation: 1

@vinay, After VM deallocate, we need to wait for 3-4 mins for complete deallocation process. Once VM stopped, proceed with generalization.

Upvotes: 0

Related Questions