with_items 파일에 포함된 jinja2 템플릿 및 변수를 사용하는 방법

with_items 파일에 포함된 jinja2 템플릿 및 변수를 사용하는 방법

jinja2 템플릿을 사용하여 구성을 구축하려고 할 때 오류가 발생하고 변수 필드가 감지되지 않습니다. 이는 ansible을 사용하여 Linux 저장소를 골드 소스에서 yum 및 apt 기반 시스템으로 동기화합니다. 각 저장소 구성은 다른 파일로 이동하고 변수 이름으로 작업을 업데이트합니다. 기본 시스템 구성은 속성 목록 뒤에 "-"를 여러 번 사용하여 파일에 넣을 수 있어야 합니다.

나는 이미 다음과 같이 댓글을 달았습니다.

jinja2의 for 루프

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

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

그리고 내가 하고 있는 일과 별로 관련이 없는 다른 일들도요.

변수 파일:

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

var 작업을 포함합니다:

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

템플릿 모듈을 사용하는 작업:

- 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'

주형:

{% 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 %}

실수:

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

jinja2 템플릿이 먼저 호출하는 역할의 속성에 관계없이 이 방식은 실패합니다. 다음을 변경하면 이름이 참조되지 않고 "i.name"이 "chrome"이 되어 비동기가 실패합니다.

변수를 가져온 것을 볼 수 있습니다

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}

"유니코드" 변수라고 적혀 있는 걸 봤고, 사전일 거라고 예상했어요. 나는 또한 with_dict를 시도했는데 변수가 사전이 아니라는 오류가 발생했습니다. 그러나 "repo:" 없이 변수 파일을 구성하면 사전 개체가 전달되지 않았다는 오류가 발생합니다.

답변1

나는 목표를 달성하는 더 좋은 방법을 찾았습니다.

목표: 사용자가 저장소 정보가 포함된 var 파일을 생성할 수 있도록 허용합니다. 하나의 파일에 여러 저장소가 일대일로 저장됩니다. (예: CentOS-Base repo 파일에는 다양한 프로젝트가 있지만 elasticsearch, epel 등은 서로 다른 파일에 배치해야 합니다.)

  1. {repo}_{pkg_mgr}_repo.yml이라는 var 파일을 만듭니다.
  2. 역할의 main.yml 파일에서 {repo}_{pkg_mgr}이 있는 모든 파일을 찾습니다.repo.yml 파일 또는 *Tower/AWX에서 전달되고 변수에 등록된 변수를 기반으로 하는 {pkg_mgr}.yml 파일입니다. AWX/Tower에서 전달된 yum 및 apt에 대해 이 작업을 수행합니다.
  3. yum 또는 apt repo 구성을 생성하는 작업에 {variable}.files를 전달합니다.
  4. 템플릿 모듈과 jinja2 템플릿 파일을 사용하여 repo 파일을 생성하고 원격 서버에 배치합니다.
  5. 작업을 실행하여 현재 저장소에 대해 모든 gpg 키를 가져왔는지 확인하세요.

** 기본 apt 저장소는 resources.list에 있고 다른 저장소는 /etc/apt/sources.list.d/에 있다는 점을 고려해야 합니다.

이는 테스트를 거쳐 yum 기반 배포판에서 작동하며 현재 APT에서 작동합니다.

답변2

{% for i in item %} 로 변경 {% for i in item.repo %}

프로젝트가 전체 dict 변수를 저장하기 때문에 이것이 작동해야 합니다. 즉, chrome 변수 아래에서 subdict 프로젝트를 호출해야 합니다 repo.

관련 정보