Reputation: 37
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:
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
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
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