0

I am having an error where the fields of my variable are not being detected when trying to build a configuration using a jinja2 template. This is to sync Linux repositories to yum and apt based systems from a golden source using ansible. Each repository configuration would go into a different file and the task updated with the variable name. Base system configs should be able to be put in one file using multiple uses of "-" then a list of attributes.

I have reviewed:

for loop in jinja2

https://omarkhawaja.com/accessing-ansible-variables-with-jinja2-loops/

https://stackoverflow.com/questions/25418158/templating-multiple-yum-repo-files-with-ansible-template-module

as well as others that are less relevant to what I am doing.

var file:

---
repo:
  - name: google_chrome
    async: 1
    url: http://dl.google.com/linux/chrome/rpm/stable/x86_6
...

include var task:

- name: Include var into the 'chrome' variable.
  include_vars:
    file: google_chrome_repo.yaml
    name: chrome

task to use template module:

- name: generate config for Centos
  template:
    src: yum_template.j2
    dest: "/etc/yum.repos.d/{{ item }}.repo"
    backup: yes
  with_items:
    - chrome
  when:
    - ansible_distribution == 'CentOS'

template:

{% for i in item %}
[ {{ i.name }} ]
async = {{ i.async }}
baseurl = {{ i.url }}
enabled = {{ i.repo_enable }}
enablegroups = {{ i.pkggrp_enable }}
failovermethod = {{ i.ha_method }}
gpgkey = {{ i.gpgkey_url }}
http_caching = {{ i.http_caching }}
keepcache = {{ i.keepcache }}
metadata_expire = {{ i.metadata_expire }}
mirrorlist = {{ i.mirrorlist }}
mirrorlist_expire = {{ i.mirrorlist_expire }}
name = {{ i.descrip }}
protect = {{ i.protect }}
proxy = {{ i.proxy_config }}
proxy_password =  {{ i.proxy_username }}
proxy_username = {{ i.proxy_password }}
repo_gpgcheck = {{ i.repo_gpgcheck }}
retries = {{ i.repo_retry_count }}
s3_enabled = {{ i.s3_enabled }}
sslverify = {{ i.ssl_verify }}
timeout = {{ i.timeout }}
{% endfor %}

error:

failed: [192.168.33.31] (item=chrome) => {"changed": false, "item": "chrome", "msg": "AnsibleUndefinedVariable: 'unicode object' has no attribute 'name'"}

whichever attribute in role is first called by the jinja2 template will fail in this way. If I change the following so name isn't referenced and "i.name" becomes just "chrome" it will fail on async

I can see the variable is imported

ok: [192.168.33.31] => {"ansible_facts": {"chrome": {"repo": [{"async": 1, "descrip": "Google Chrome Repository", "gpgkey_url": "https://dl.google.com/linux/linux_signing_key.pub", "ha_method": "roundrobin", "http_caching": 1, "keepcache": 1, "metadata_expire": 21600, "mirrorlist": null, "mirrorlist_expire": 21600, "name": "google_chrome", "pkggrp_enable": 1, "protect": 0, "proxy_config": "__None__", "proxy_password": null, "proxy_username": null, "repo_enable": 1, "repo_gpgcheck": 1, "repo_retry_count": 10, "s3_enabled": 0, "ssl_verify": 1, "timeout": 1, "url": "http://dl.google.com/linux/chrome/rpm/stable/x86_6"}]}}, "ansible_included_var_files": ["/var/lib/awx/projects/_6__trowe/playbooks/roles/Manage_Linux_Repos/vars/google_chrome_repo.yaml"], "changed": false}

I do see it says "unicode" variable where I would expect it to be a dict. I have also tried with_dict and the error says that the variable is not a dictionary. However if I structure the variable file without "repo:", it will error saying it was not passed a dictionary object...

0

I figured out a better way of accomplishing the goal.

goal: allow users to make var files with repository information. multiple repositories in one file and one to one. (ex: CentOS-Base repo file has a bunch of different items, but elasticsearch, epel, etc should go in in distinct files)

  1. create var files, named {repo}_{pkg_mgr}_repo.yml
  2. in the main.yml file of the role, find all files with {repo}_{pkg_mgr}repo.yml files OR *{pkg_mgr}.yml files, based on variable passed from Tower/AWX and register to a variable. do this for both yum and apt, as passed from AWX/Tower
  3. pass {variable}.files to the task that generates the yum or apt repo configurations.
  4. use the template module and jinja2 template file to create the repo file and drop it on the remote server.
  5. run task to ensure all gpg keys are imported for current repos

** need to take into account default apt repos are placed in sources.list and others are in /etc/apt/sources.list.d/

this is tested and working for yum based distributions, working on APT currently.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.