Automation
Ansible NetApp Volume Provisioning Example With Validation Guardrails
Why the Example Needs Guardrails
Most storage automation examples show how to create a volume. Production automation needs more than that. It needs to reject unsafe input, apply approved defaults, produce evidence, and make the change easy to review later.
This example is intentionally shaped like a runbook. You can adapt it into a change workflow, CI job, or self-service request pipeline.
Request Variables
Start with a simple request file. Keep platform facts and request data separate so the same playbook can run in dev, test, and production with different inventory variables.
application: inventory
environment: prod
svm: svm_nfs01
volume_name: inventory_prod_data
size_gb: 250
aggregate_name: aggr_ssd_01
junction_path: /inventory_prod_data
snapshot_policy: hourly
tiering_policy: none
owner: app-inventory
ticket: CHG0123456
Current Module Requirements
The current Ansible community documentation lists netapp.ontap.na_ontap_volume as part of the netapp.ontap collection. It is not included in ansible-core; install it with:
ansible-galaxy collection install netapp.ontap
The module documentation currently lists Ansible 2.9 or later as required and recommends Ansible 2.12 or later. Pin and record the collection version in your automation environment so a future collection upgrade does not silently change behavior.
Validation Tasks
Validate inputs before touching ONTAP.
- name: Validate volume request
ansible.builtin.assert:
that:
- volume_name is match('^[a-z0-9_]+$')
- volume_name | length <= 64
- size_gb | int >= 10
- size_gb | int <= 2048
- environment in ['dev', 'test', 'prod']
- snapshot_policy in ['none', 'daily', 'hourly']
- tiering_policy in ['none', 'snapshot-only', 'auto']
- aggregate_name is match('^[A-Za-z0-9_.-]+$')
- junction_path is match('^/[A-Za-z0-9_./-]+$')
fail_msg: "Volume request failed storage standards validation."
The exact standards should come from your environment. The important part is that validation happens before the storage change.
Preflight Capacity and Duplicate Checks
Before creating the volume, check that the target aggregate exists, the volume does not already exist unexpectedly, and the requested size is within your free-space guardrail. The exact information-gathering module depends on your collection version, but the pattern is the same:
- name: Gather existing volume information
netapp.ontap.na_ontap_rest_info:
hostname: "{{ ontap_hostname }}"
username: "{{ ontap_username }}"
password: "{{ ontap_password }}"
https: true
validate_certs: true
gather_subset:
- storage/volumes
register: ontap_volumes
In production, fail the run when the target already exists unless the workflow explicitly supports modification. Idempotency should be deliberate, not accidental.
Provisioning Shape
- name: Create ONTAP volume
netapp.ontap.na_ontap_volume:
state: present
hostname: "{{ ontap_hostname }}"
username: "{{ ontap_username }}"
password: "{{ ontap_password }}"
https: true
validate_certs: true
vserver: "{{ svm }}"
name: "{{ volume_name }}"
aggregate_name: "{{ aggregate_name }}"
size: "{{ size_gb }}"
size_unit: gb
junction_path: "{{ junction_path }}"
snapshot_policy: "{{ snapshot_policy }}"
tiering_policy: "{{ tiering_policy }}"
Use a dedicated service account and store credentials in a vault or external secret store. Do not hard-code passwords in the playbook.
Optional Autosize Standard
If your operational standard allows autogrow, configure it deliberately instead of leaving it as an undocumented manual follow-up. Current ONTAP CLI documentation says new flexible volumes default autosize to off, except data protection mirrors.
Example policy shape:
autosize_mode: grow
autosize_max_gb: 500
autosize_grow_threshold_percent: 85
Then apply it with the collection module your environment standardizes on, or with a controlled CLI/API task if your collection version does not expose every autosize setting you need.
Post-Change Evidence
After provisioning, query the result and store the evidence with the change record.
- name: Record volume provisioning evidence
ansible.builtin.copy:
dest: "evidence/{{ ticket }}-{{ volume_name }}.txt"
content: |
ticket={{ ticket }}
volume={{ volume_name }}
svm={{ svm }}
size_gb={{ size_gb }}
aggregate={{ aggregate_name }}
junction_path={{ junction_path }}
snapshot_policy={{ snapshot_policy }}
tiering_policy={{ tiering_policy }}
owner={{ owner }}
Evidence does not need to be fancy. It needs to be easy to find during audit, troubleshooting, or handoff.
Operational Improvements
Add these once the basic workflow is stable:
- Aggregate or tier capacity preflight checks.
- SVM allowlist by environment.
- Automatic export policy or LUN mapping validation.
- Owner and ticket lookup from your ITSM system.
- A dry-run mode that prints planned changes.
- Collection version pinning and a test job that runs after collection upgrades.
- Post-change validation with
volume showor REST output stored as evidence.
Related Reading
See also: Automate NetApp Volume Provisioning with Ansible