0

As per today, I have the following role, this role simulate a basic installation of the product:

- name: Install Server.msi primary_appserver
  ansible.windows.win_package:
    path: C:\product.msi
    log_path: C:\InstallProduct.log
    arguments:
     ADDLOCAL=DB,Agent
    state: present
  become: true
  become_method: runas
  vars:
    ansible_become_user: "{{ ansible_user }}"
    ansible_become_password: "{{ ansible_password }}"
  when: "'primary_appservers' in group_names"

I want to simulate an "advanced" installation, which I select additional feature in the Installation wizard

I the installation wizard, I can select one or more features, meaining ADDLOCAL argumnet can be: ADDLOCAL=DB,Agent - that's the basic OR ADDLOCAL=DB,Agent,Feature_A OR ADDLOCAL=DB,Agent,Feature_A,Feature_B

Things are become complicated for me, since Feature_C for example demands additional arguments list to install it for example: RABBIT_LOCAL_PORT, RABBIT_QUEUE_NAME, RABBIT_TTL...

Using vars in Ansible or extraVars in Jenkins - overwrite the values in the playbook\role

Is there a way to add the value to the existing value in the playbook\role, so for example when I select to install Feature_a and\or Feature_b - ADDLOCAL value in the role will changed into ADDLOCAL=DB,Agent,Feature_A,Feature_B? or in the second case when I add Feature_C, the ADDLOCAL value in the role will changed into ADDLOCAL=DB,Agent,Feature_C and arguments key will include in addition: RABBIT_LOCAL_PORT, RABBIT_QUEUE_NAME, RABBIT_TTL arguments?

Hiddai
  • 87
  • 1
  • 3
  • 14

1 Answers1

0

There are two options to implement desired behavior:

Treat arguments variable as list

While generating arguments treat them as structure (map of lists in my example). You can add or remove any features/arguments depending on your use case. This approach adds some complexity though:

- name: set default arguments
  set_fact:
    arguments_map:
      ADDLOCAL:
      - feature1
      - feature2
- name: set feature3
  set_fact:
    arguments_map: "{{ arguments_map | combine({'ADDLOCAL':['feature3']}, recursive=True, list_merge='append') }}"
- name: set feature4
  set_fact:
    arguments_map: "{{ arguments_map | combine({'ADDLOCAL':['feature4'], 'RABBIT_LOCAL_PORT':5672, 'RABBIT_QUEUE_NAME':'test'}, recursive=True, list_merge='append') }}"
- name: generate arguments string
  set_fact:
    arguments: "{% for argument in arguments_map | dict2items %}{{ argument['key'] }}={{ (argument['value'] | join(',')) if (argument['value'] | type_debug == 'list') else (argument['value']) }} {% endfor %}"
- debug:
    var: arguments

This produces following string:

ADDLOCAL=feature1,feature2,feature3,feature4 RABBIT_LOCAL_PORT=5672 RABBIT_QUEUE_NAME=test 

You can move all pre-defined sets to var files for readability.

Gradually concatenate to arguments string

More straightforward but less flexible:

- name: set default arguments
  set_fact:
    arguments: 'ADDLOCAL=DB,Agent'
- name: set feature1
  set_fact:
    arguments: "{{ arguments + ',feature1' }}"
- name: set feature2
  set_fact:
    arguments: "{{ arguments + ',feature2' }}"
- name: set additional arguments
  set_fact:
    arguments: "{{ arguments + ' RABBIT_LOCAL_PORT=5672 RABBIT_QUEUE_NAME=test' }}"
  when: arguments is search('feature2')
- debug:
    var: arguments

Produces following string:

ADDLOCAL=DB,Agent,feature1,feature2 RABBIT_LOCAL_PORT=5672 RABBIT_QUEUE_NAME=test
Vladimir
  • 576
  • 3
  • 5