ansibleopenstackvolumecinder

how to write a playbook to delete OpenStack volume snapshot of older than 10 days using os_volume_snapshot module


---
- name: Creating a volume snapshot
  hosts: Test-ctrl
  gather_facts: True
  tasks:
  - name: Creating snapshot of Test
    os_volume_snapshot:
      auth:
        auth_url: http://20.10.X.X:5000/v3/
        username: XXXXXXX
        password: XCXCXCXC
        project_name: test-stack
        project_domain_name: Default
        user_domain_name: Default
      state: absent
      validate_certs: False
      display_name: Test- {{ lookup('pipe','date +%Y-%m-%d-%H-%M-%S') }}
      volume: Test-1
      force: yes

how to write a playbook to delete OpenStack volume snapshot of older than 10 days

Here my playbook to create volume. But customize to delete volume older than 10 days or 5 days ????


Solution

  • I also have a need to do this but, sadly, it is not possible with the os_volume_snapshot module. Neither is it possible using any of the OpenStack modules in Ansible (2.9). Also the os_volume_snapshot makes the volume parameter mandatory (which is silly - as you don't need to know the name of the original volume to delete a snapshot).

    So, it you "must" use the os_volume_snapshot then you're out of luck.

    The built-in os_ modules are very much a "work in progress" with regard to comprehensive control of OpenStack clusters in Ansible, and it is of little use to you for the task you've identified.

    But ... hold on ...

    Like you, I need to automate this and it can be accomplished using Ansible and the official python-openstackclient module. OK - it's not "pure" Ansible (i.e. it's not using purely built-in modules) but it's a playbook that uses the built-in command module and it works.

    (BTW - no warranty provided in the following - and use at your own risk)

    So, here's a playbook that I'm running that deletes snapshot volumes that have reached a defined age in days. You will need to provide the following variables...

    Yes, there are better ways to provide OpenStack variables (like cloud files or OS_ environment variables etc.) but I've made all those that are required explicit so it's easier to know what's actually required.

    And

    A summary of what the playbook does: -

    1. It uses openstack volume snapshot list to get a list of snapshot volumes in the project
    2. It then uses openstack volume snapshot show to get information about each snapshot (i.e. its created_at date) and builds a lit of volume ages (in days)
    3. It then uses openstack volume snapshot delete to delete all volumes that are considered too old
    ---
    
    - hosts: localhost
      tasks:
    
      # Delete all project snapshots that are too old.
    
      # The user is expected to define the variable 'retirement_age_days'
      # where all volumes that have reached that age are deleted.
      # If 0 all snapshots are deleted.
      #
      # The user is also required to define OpenStack variables.
    
      - name: Assert control variables
        assert:
          that:
          - retirement_age_days is defined
          - retirement_age_days|int >= 0
          - os_auth_url is defined
          - os_username is defined
          - os_password is defined
          - os_project_name is defined
          - os_project_domain_name is defined
          - os_user_domain_name is defined
    
      # Expectation here is that you have the following OpenStack information: -
      #
      # - auth_url (i.e. "https://example.com:5000/v3")
      # - username
      # - password
      # - project_name
      # - project_domain_name (i.e. "Default")
      # - user_domain_name
    
      # We rely in the OpenStack client - the Ansible "os_" module
      # (Ansible 2.9) does not do what we need, so we need the client.
      # It' Python so make sure it's available...
    
      - name: Install prerequisite Python modules
        pip:
          name:
          - python-openstackclient==5.3.1
          extra_args: --user
    
      - name: Set snapshot command
        set_fact:
          snapshot_cmd: openstack volume snapshot
    
      # To avoid cluttering the command-line we
      # define all the credential material as a map of variables
      # that we then apply as the 'environment' for each command invocation.
    
      - name: Define OpenStack environment
        set_fact:
          os_env:
            OS_AUTH_URL: "{{ os_auth_url }}"
            OS_USERNAME: "{{ os_username }}"
            OS_PASSWORD: "{{ os_password }}"
            OS_PROJECT_NAME: "{{ os_project_name }}"
            OS_PROJECT_DOMAIN_NAME: "{{ os_project_domain_name }}"
            OS_USER_DOMAIN_NAME: "{{ os_user_domain_name }}"
    
      # Get all the snapshot names in the project.
      # The result is a json structure that we parse
      # in order to get just the names...
    
      - name: Get snapshots
        command: "{{ snapshot_cmd }} list --format json"
        environment: "{{ os_env }}"
        changed_when: false
        register: snap_result
    
      - name: Collect snapshot volume names
        set_fact:
          snap_volume_names: "{{ snap_result.stdout|from_json|json_query(query)|flatten }}"
        vars:
          query: "[*].Name"
    
      - name: Display existing snapshot volumes
        debug:
          var: snap_volume_names
    
      # For each snapshot, get its 'info'.
      # The combined results are then parsed in order to
      # locate each volume's 'created_at' date.
      # We compare that to 'now' in order to build a list of
      # volume ages (in days)...
    
      - name: Get snapshot volume info
        command: "{{ snapshot_cmd }} show {{ item }} --format json"
        environment: "{{ os_env }}"
        changed_when: false
        register: snap_volume_info
        loop: "{{ snap_volume_names }}"
    
      - name: Create snapshot age list (days)
        set_fact:
          snap_volume_ages: >-
            {{
              snap_volume_ages|default([]) +
              [ ((ansible_date_time.iso8601|to_datetime(fmt_1)) -
                 (item.stdout|from_json|json_query(query)|to_datetime(fmt_2))).days ]
            }}
        vars:
          query: "created_at"
          fmt_1: "%Y-%m-%dT%H:%M:%SZ"
          fmt_2: "%Y-%m-%dT%H:%M:%S.%f"
        loop: "{{ snap_volume_info.results }}"
    
      # Using the combined volume names and ages lists
      # iterate through the ages and delete volumes have reached their age limit...
    
      - name: Delete old snapshots
        command: "{{ snapshot_cmd }} delete {{ item.1 }}"
        environment: "{{ os_env }}"
        changed_when: true
        when: item.0 >= retirement_age_days|int
        with_together:
        - "{{ snap_volume_ages|default([]) }}"
        - "{{ snap_volume_names|default([]) }}"