Skip to content

Commit

Permalink
Add new azure_manage_snapshot role (#101)
Browse files Browse the repository at this point in the history
* Add new azure_manage_snapshot role

New role azure_manage_snapshot will help in creating, restoring and
deleting snapshots.

* Add support for creating vm from snapshot
  • Loading branch information
p3ck authored Jan 30, 2025
1 parent 5212df8 commit 3b2c2d1
Show file tree
Hide file tree
Showing 26 changed files with 537 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .ansible-lint
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
profile: production
profile: shared

exclude_paths:
- tests/integration/
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- Added support for swap_os_disk which allows you to create a VM from a Snapshot
74 changes: 74 additions & 0 deletions roles/azure_manage_snapshot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
azure_manage_snapshot
==================

A role to Create/Delete/Restore an Azure OS Disk Snapshot.

Requirements
------------

* Azure User Account with valid permission

Role Variables
--------------

* **azure_manage_snapshot_operation**: Operation to perform. Valid values are 'create', 'delete', 'restore'. Default is 'create'.
* **azure_manage_snapshot_resource_group**: (Required) Resource group on/from which the snapshot will reside.
* **azure_manage_snapshot_location**: The location to use, if not specified it will use the location of the virtual machine.
* **azure_manage_snapshot_name**: (Required) The name of the snapshot volume.
* **azure_manage_snapshot_vm_name**: The name of the virtual machine where the snapshot came from or will be applied.
* **azure_manage_snapshot_disk_name**: The name of the disk that the snapshot will be restored to.

Limitations
------------

- NA

Dependencies
------------

- NA

Example Playbook
----------------

- hosts: localhost
tasks:
- name: Create a snapshot from a virtual machine
ansible.builtin.include_role:
name: cloud.azure_ops.azure_manage_snapshot
vars:
azure_manage_snapshot_operation: create
azure_manage_snapshot_resource_group: 'resource-group'
azure_manage_snapshot_vm_name: 'example-vm'
azure_manage_snapshot_name: 'example-snapshot-volume'
azure_manage_disk_name: 'example-disk-volume'

- name: Restore a snapshot to a virtual machine
ansible.builtin.include_role:
name: cloud.azure_ops.azure_manage_snapshot
vars:
azure_manage_snapshot_operation: restore
azure_manage_snapshot_resource_group: 'resource-group'
azure_manage_snapshot_vm_name: 'example-vm'
azure_manage_snapshot_name: 'example-snapshot-volume'
azure_manage_disk_name: 'example-disk-volume'

- name: Delete a snapshot
ansible.builtin.include_role:
name: cloud.azure_ops.azure_manage_snapshot
vars:
azure_manage_snapshot_operation: delete
azure_manage_snapshot_resource_group: 'resource-group'
azure_manage_snapshot_name: 'example-snapshot-volume'

License
-------

GNU General Public License v3.0 or later

See [LICENCE](https://github.com/redhat-cop/cloud.azure_ops/blob/main/LICENSE) to see the full text.

Author Information
------------------

- Ansible Cloud Content Team
3 changes: 3 additions & 0 deletions roles/azure_manage_snapshot/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
azure_manage_snapshot_operation: create
azure_manage_snapshot_disk_name: "{{ azure_manage_snapshot_name }}-disk"
36 changes: 36 additions & 0 deletions roles/azure_manage_snapshot/meta/argument_specs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
argument_specs:
main:
version_added: 3.1.0
short_description: A role to manage a snapshot to an Azure Virtual Machine.
description:
- A role to manage a snapshot to an Azure Virtual Machine.
- This role requires an azure user account with valid permission.
options:
azure_manage_snapshot_operation:
description:
- Operation to perform
default: "create"
choices: ["create", "delete", "restore"]
azure_manage_snapshot_resource_group:
description:
- Resource group from which the snapshot resides.
required: true
azure_manage_snapshot_name:
description:
- Name of the snapshot volume.
required: true
azure_manage_snapshot_vm_name:
description:
- Name of the virtual machine to perform the snapshot operation on.
required: false
azure_manage_snapshot_disk_name:
description:
- Optional name of the Managed Disk.
- Default value is I(azure_manage_snapshot_name).
required: false
azure_manage_snapshot_location:
description:
- Optional location to use.
- Default value is the location of the Virtual Machine or Snapshot.
required: false
24 changes: 24 additions & 0 deletions roles/azure_manage_snapshot/tasks/create.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
- name: Get virtualmachine info
azure.azcollection.azure_rm_virtualmachine_info:
resource_group: "{{ azure_manage_snapshot_resource_group }}"
name: "{{ azure_manage_snapshot_vm_name }}"
register: azure_manage_snapshot_vm_info

- name: Confirm OS is Managed Disk
ansible.builtin.fail:
msg: "{{ azure_manage_snapshot_vm_name }} OS Disk is not of Managed Type"
when: '"managed_disk" not in azure_manage_snapshot_vm_info.vms[0].os_disk'

- name: Set OS Disk ID
ansible.builtin.set_fact:
azure_manage_snapshot_os_disk_id: "{{ azure_manage_snapshot_vm_info.vms[0].os_disk.managed_disk.id }}"

- name: Create a snapshot
azure.azcollection.azure_rm_snapshot:
resource_group: "{{ azure_manage_snapshot_resource_group }}"
name: "{{ azure_manage_snapshot_name }}"
location: "{{ azure_manage_snapshot_location | default(azure_manage_snapshot_vm_info.vms[0].location) }}"
creation_data:
create_option: Copy
source_id: "{{ azure_manage_snapshot_os_disk_id }}"
6 changes: 6 additions & 0 deletions roles/azure_manage_snapshot/tasks/delete.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
- name: Delete snapshot
azure.azcollection.azure_rm_snapshot:
resource_group: "{{ azure_manage_snapshot_resource_group }}"
name: "{{ azure_manage_snapshot_name }}"
state: absent
3 changes: 3 additions & 0 deletions roles/azure_manage_snapshot/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- name: Create, delete or restore Snapshot
ansible.builtin.include_tasks: "{{ azure_manage_snapshot_operation }}.yml"
when: azure_manage_snapshot_operation in ['create', 'delete', 'restore']
24 changes: 24 additions & 0 deletions roles/azure_manage_snapshot/tasks/restore.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
- name: Get snapshot info
azure.azcollection.azure_rm_snapshot_info:
resource_group: "{{ azure_manage_snapshot_resource_group }}"
name: "{{ azure_manage_snapshot_name }}"
register: azure_manage_snapshot_info

- name: Create Managed disk from Snapshot
azure.azcollection.azure_rm_manageddisk:
name: "{{ azure_manage_snapshot_disk_name | default(azure_manage_snapshot_name) }}"
location: "{{ azure_manage_snapshot_location | default(azure_manage_snapshot_info.state[0].location) }}"
resource_group: "{{ azure_manage_snapshot_resource_group }}"
create_option: copy
source_uri: "{{ azure_manage_snapshot_info.state[0].id }}"
storage_account_type: "{{ azure_manage_snapshot_info.state[0].sku.name }}"
register: azure_manage_snapshot_disk

- name: Swap OS Disk
azure.azcollection.azure_rm_virtualmachine:
name: "{{ azure_manage_snapshot_vm_name }}"
resource_group: "{{ azure_manage_snapshot_resource_group }}"
swap_os_disk:
os_disk_id: "{{ azure_manage_snapshot_disk.state.id }}"
os_disk_resource_group: "{{ azure_manage_snapshot_resource_group }}"
4 changes: 4 additions & 0 deletions roles/azure_virtual_machine_with_public_ip/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ Role Variables
- **load_balancer_backend_address_pools**: List of existing load balancer backend address pools in which the network interface will be load balanced.
- **os**: Type of Operating System. Default is 'Linux'
- **image**: The image used to build the VM. For custom images, the name of the image. To narrow the search to a specific resource group, a dict with the keys name and resource_group. For Marketplace images, a dict with the keys publisher, offer, sku, and version. Set version=latest to get the most recent version of a given image.
- **swap_os_disk**: The managed disk to use as the OS disk.
- **os_disk_id**: The swap OS disk's ID.
- **os_disk_name**: The swap OS disk's name.
- **os_disk_resource_group**: The swap OS disk's resource group.
- **managed_disk_type**: Managed OS disk type.
- **ssh_pw_enabled**: Enable/disable SSH passwords. Valid values are 'true', 'false'. When `os='Linux'` and `ssh_pw_enabled='false'` requires the use of SSH keys.
Default value is 'true'.
Expand Down
17 changes: 17 additions & 0 deletions roles/azure_virtual_machine_with_public_ip/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,23 @@ argument_specs:
- The image used to build the VM. For custom images, the name of the image. To narrow the search to a specific resource group, a dict with the keys name and resource_group.
- For Marketplace images, a dict with the keys publisher, offer, sku, and version.
- Set O(version=latest) to get the most recent version of a given image.
swap_os_disk:
description:
- The Managed disk to swap in as the OS Disk.
type: dict
options:
os_disk_id:
description:
- The swap OS disk's ID.
type: str
os_disk_name:
description:
- The swap OS disk's name.
type: str
os_disk_resource_group:
description:
- The swap OS disk's resource group.
type: str
managed_disk_type:
type: "str"
description:
Expand Down
13 changes: 9 additions & 4 deletions roles/azure_virtual_machine_with_public_ip/tasks/create.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
- name: Ensure admin username is defined
ansible.builtin.fail:
msg: "Missing parameter: key 'admin_username' not found in azure_virtual_machine_with_public_ip_vm"
when: azure_virtual_machine_with_public_ip_vm.admin_username is not defined
when:
- azure_virtual_machine_with_public_ip_vm.swap_os_disk is not defined
- azure_virtual_machine_with_public_ip_vm.admin_username is not defined

- name: Ensure vm size is defined
ansible.builtin.fail:
msg: "Missing parameter: key 'size' not found in azure_virtual_machine_with_public_ip_vm"
when: azure_virtual_machine_with_public_ip_vm.size is not defined

- name: Ensure vm image is defined
- name: Ensure vm image or swap_os_disk is defined
ansible.builtin.fail:
msg: "Missing parameter: key 'image' not found in azure_virtual_machine_with_public_ip_vm"
when: azure_virtual_machine_with_public_ip_vm.image is not defined
msg: "Missing parameter: key 'image' or 'swap_os_disk' not found in azure_virtual_machine_with_public_ip_vm"
when:
- azure_virtual_machine_with_public_ip_vm.image is not defined
- azure_virtual_machine_with_public_ip_vm.swap_os_disk is not defined

- name: Check that Azure Region is known
ansible.builtin.fail:
Expand Down Expand Up @@ -135,6 +139,7 @@
managed_disk_type: "{{ azure_virtual_machine_with_public_ip_vm.managed_disk_type | default(omit) }}"
availability_set: "{{ azure_virtual_machine_with_public_ip_availability_set.name | default(omit) }}"
image: "{{ azure_virtual_machine_with_public_ip_vm.image | default(omit) }}"
swap_os_disk: "{{ azure_virtual_machine_with_public_ip_vm.swap_os_disk | default(omit) }}"
admin_username: "{{ azure_virtual_machine_with_public_ip_vm.admin_username | default(omit) }}"
admin_password: "{{ azure_virtual_machine_with_public_ip_vm.admin_password | default(omit) }}"
ssh_password_enabled: "{{ azure_virtual_machine_with_public_ip_vm.ssh_pw_enabled | default(omit) }}"
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/requirements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
collections:
- community.crypto
- azure.azcollection
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cloud/azure
role/azure_manage_snapshot
time=10m
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
vm_name: "{{ resource_prefix }}-vm"
vm_from_snapshot_name: "{{ resource_prefix }}-vm-from-snapshot"
vm_from_snapshot_disk_name: "{{ resource_prefix }}-disk-from-snapshot"
vm_image:
offer: RHEL
publisher: RedHat
sku: 8-LVM
version: latest
vm_username: 'azureuser'
vm_size: Standard_B1s
vm_managed_disk_type: Premium_LRS
snapshot_name: "{{ resource_prefix }}-snapshot"
before_snapshot_file: "/home/{{ vm_username }}/before_snapshot"
after_snapshot_file: "/home/{{ vm_username }}/after_snapshot"
ssh_public_key_path_default: "~/.ssh/id_rsa.pub"
ssh_private_key_path_default: "~/.ssh/id_rsa"
ssh_port_default: 22
resource_group_name: "{{ resource_prefix }}-{{ resource_group }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
- name: Wait 300 seconds, but only start checking after 10 seconds
ansible.builtin.wait_for_connection:
delay: 10
timeout: 300
delegate_to: "{{ groups['azure'][0] }}"

- name: Touch a file
ansible.builtin.file:
path: "{{ after_snapshot_file }}"
state: touch
mode: '0755'
delegate_to: "{{ groups['azure'][0] }}"

- name: Sync Filesystems
ansible.builtin.command: sync
register: my_output
changed_when: my_output.rc != 0
delegate_to: "{{ groups['azure'][0] }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
- name: Wait 300 seconds, but only start checking after 10 seconds
ansible.builtin.wait_for_connection:
delay: 10
timeout: 300
delegate_to: "{{ groups['azure'][0] }}"

- name: Touch a file
ansible.builtin.file:
path: "{{ before_snapshot_file }}"
state: touch
mode: '0755'
delegate_to: "{{ groups['azure'][0] }}"

- name: Sync Filesystems
ansible.builtin.command: sync
register: my_output
changed_when: my_output.rc != 0
delegate_to: "{{ groups['azure'][0] }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
- name: Create snapshot
ansible.builtin.include_role:
name: cloud.azure_ops.azure_manage_snapshot
vars:
azure_manage_snapshot_operation: create
azure_manage_snapshot_name: "{{ snapshot_name }}"
azure_manage_snapshot_vm_name: "{{ vm_name }}"
azure_manage_snapshot_resource_group: "{{ resource_group_name }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Delete snapshot
ansible.builtin.include_role:
name: cloud.azure_ops.azure_manage_snapshot
vars:
azure_manage_snapshot_operation: delete
azure_manage_snapshot_name: "{{ snapshot_name }}"
azure_manage_snapshot_resource_group: "{{ resource_group_name }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
- name: Wrap test in block
block:
- name: Setup
ansible.builtin.include_tasks: setup.yml

- name: Before snapshot
ansible.builtin.include_tasks: before_snapshot.yml

- name: Create snapshot
ansible.builtin.include_tasks: create_snapshot.yml

- name: After snapshot
ansible.builtin.include_tasks: after_snapshot.yml

- name: Restore snapshot
ansible.builtin.include_tasks: restore_snapshot.yml

- name: Validate snapshot
ansible.builtin.include_tasks: validate_snapshot.yml

- name: Create VM from snapshot
ansible.builtin.include_tasks: vm_from_snapshot.yml

- name: Validate vm from snapshot
ansible.builtin.include_tasks: validate_vm_from_snapshot.yml
always:
- name: Teardown
ansible.builtin.include_tasks: teardown.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
- name: Restore snapshot
ansible.builtin.include_role:
name: cloud.azure_ops.azure_manage_snapshot
vars:
azure_manage_snapshot_operation: restore
azure_manage_snapshot_name: "{{ snapshot_name }}"
azure_manage_snapshot_vm_name: "{{ vm_name }}"
azure_manage_snapshot_resource_group: "{{ resource_group_name }}"
Loading

0 comments on commit 3b2c2d1

Please sign in to comment.