2

I am trying to create an ansible playbook which will help me download files and install it into our system using a rest call from a certain website. My current playbook looks like below.

---
- name: install apps
  hosts: myserversservers
  tasks:
    - name: app installer
      uri:
        url: 'https://127.0.0.1:8089/services/apps/local'
        method: POST
        body: 'auth=XXXXXh&filename=true&name=https://XX.domain.com/app/2934/release/2.2.0/download'
        headers:
          Content-Type: application/x-www-form-urlencoded
        url_username: admin
        url_password: mypass
        validate_certs: false
        status_code: 201
      register: result

is there a way to load multiple values to the URL in a while read kind of style so that instead of writing multiple tasks to install multiple apps i can simply use jinja to load all the variables in a single play so that with one task all the apps get installed? for example instead of writing the URL like below

https://XX.domain.com/app/**2934**/release/**2.2.0**/download

can i replace it using Jinja somehow by referencing a yaml file (include vars)? If possible how should the YAML file be formatted and how should it be referenced into the play?

https://XX.domain.com/app/{{ app number }}/release/{{ version number}}/download

i can maintain a file with all the variables that i need like

app1 ver3
app3 ver55
app99 ver99

2 Answers 2

2

For example, given the file

shell> cat app_ver.csv
app1 ver3
app3 ver55
app99 ver99

use module community.general.read_csv

    - community.general.read_csv:
        path: app_ver.csv
        fieldnames: [app, ver]
        delimiter: ' '
      register: app_ver

gives

  app_ver.list:
    - {app: app1, ver: ver3}
    - {app: app3, ver: ver55}
    - {app: app99, ver: ver99}

Test the iteration

    - debug:
        msg: |
          body: 'auth=XXXXXh&filename=true&name={{ http }}'
      loop: "{{ app_ver.list }}"
      vars:
        http: 'https://XX.domain.com/app/{{ item.app }}/release/{{ item.ver }}/download'

gives

TASK [debug] **********************************************************************************
ok: [localhost] => (item={'app': 'app1', 'ver': 'ver3'}) => 
  msg: |-
    body: 'auth=XXXXXh&filename=true&name=https://XX.domain.com/app/app1/release/ver3/download'
ok: [localhost] => (item={'app': 'app3', 'ver': 'ver55'}) => 
  msg: |-
    body: 'auth=XXXXXh&filename=true&name=https://XX.domain.com/app/app3/release/ver55/download'
ok: [localhost] => (item={'app': 'app99', 'ver': 'ver99'}) => 
  msg: |-
    body: 'auth=XXXXXh&filename=true&name=https://XX.domain.com/app/app99/release/ver99/download'

Example of a complete playbook for testing

- hosts: localhost

  tasks:

    - community.general.read_csv:
        path: app_ver.csv
        fieldnames: [app, ver]
        delimiter: ' '
      register: app_ver

    - debug:
        var: app_ver.list|to_yaml

    - debug:
        msg: |
          body: 'auth=XXXXXh&filename=true&name={{ http }}'
      loop: "{{ app_ver.list }}"
      vars:
        http: 'https://XX.domain.com/app/{{ item.app }}/release/{{ item.ver }}/download'
1

Yea thats pretty much it. Create vars for your app number and and version number and iterate through each. As far as formatting goes, I think you hit the nail right on the head.

vars:
 app_number: [app1, app3, app99]
 version_number: [ver3, ver55, ver99]

debug: 
  msg: https://XX.domain.com/app/{{ item.0 }}/release/{{ item.1 }}/download
loop: "{{ list_one | zip(list_two) | list }}"

There is a nice post below that will help you with multiple lists at the same time:

https://stackoverflow.com/questions/46411107/iterating-over-two-lists-in-ansible

1
  • i also thought about that approach like declaring all the variables on my playbook but i had a ton of apps and version numbers, so i was looking for a CSV option. Bu yea.. even your approach would have worked if the number of apps were low. Thanks for your answer. Oct 20, 2022 at 11:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .