如何在CloudStack的cs_instance模块中按变量定义状态添加/移除标签
I'm using the Ansible cs_instance module to create CloudStack instances, here's my sample code:
- name: create or update instance cs_instance: display_name: web-vm-1 template: Linux Debian 7 64-bit service_offering: Tiny ssh_key: john@example.com tags: - { key: admin, value: john } - { key: group, value: "{{ vm_group_tab }}" } user_data: | #cloud-config packages: - nginx
I want to add or remove the group tag depending on whether the vm_group_tab variable is defined. Specifically, when vm_group_tab isn't defined, I only want the admin tag to be present. How can I achieve this?
Great question! There are a couple of clean, straightforward ways to handle this dynamic tag list in Ansible, depending on your preference:
Method 1: Jinja2 Conditionals Directly in the Task
The simplest approach is to use Jinja2's conditional syntax to include the group tag only when vm_group_tab is defined. This keeps everything contained within your cs_instance task:
- name: create or update instance cs_instance: display_name: web-vm-1 template: Linux Debian 7 64-bit service_offering: Tiny ssh_key: john@example.com tags: - { key: admin, value: john } {% if vm_group_tab is defined %} - { key: group, value: "{{ vm_group_tab }}" } {% endif %} user_data: | #cloud-config packages: - nginx
When vm_group_tab exists, the group tag gets added; when it doesn't, only the admin tag remains. It's easy to read and requires no extra tasks.
Method 2: Build Tags List with set_fact First
If you prefer a cleaner task structure (or need to reuse the tags list elsewhere in your playbook), you can construct the dynamic tags list in a separate set_fact task:
- name: Build dynamic instance tags list set_fact: instance_tags: - { key: admin, value: john } {% if vm_group_tab is defined %} - { key: group, value: "{{ vm_group_tab }}" } {% endif %} - name: create or update instance cs_instance: display_name: web-vm-1 template: Linux Debian 7 64-bit service_offering: Tiny ssh_key: john@example.com tags: "{{ instance_tags }}" user_data: | #cloud-config packages: - nginx
This separates the tag logic from the instance creation task, making it easier to modify or reuse later.
Method 3: Filter with Ansible Native Filters
For a more "Ansible-native" approach without Jinja2 conditionals, you can build a full list of potential tags and filter out the ones with undefined values:
- name: create or update instance cs_instance: display_name: web-vm-1 template: Linux Debian 7 64-bit service_offering: Tiny ssh_key: john@example.com tags: "{{ [ { key: 'admin', value: 'john' }, { key: 'group', value: vm_group_tab | default(None) } ] | selectattr('value', 'defined') | list }}" user_data: | #cloud-config packages: - nginx
Here, we use default(None) to set the group tag's value to None if vm_group_tab is undefined, then selectattr('value', 'defined') filters out any tag where the value isn't present. This keeps the task self-contained without extra syntax blocks.
All three methods will give you exactly the behavior you want: the group tag is only included when vm_group_tab is defined.
内容的提问来源于stack exchange,提问作者nbari

