Ansible

ansible - docker 容器中環境變數的模板 json

  • April 6, 2021

我正在嘗試將單行 json 字元串分配給 docker 容器中的環境變數。這是json的樣子:

{"ip_access": {"IP_whitelist": {"192.168.99.19/32": "grafana/status (Provider)"}}, "vhosts": {"prometheus1": {"dns_names": ["prometheus1.company.internal"], "add_lines_443": ["include IP_whitelist;", "set $prometheus http://prometheus:9090;", "location / { proxy_pass $prometheus; }"], "options": {"cert_path": "/etc/ssl/certs/prometheus1.crt", "key_path": "/etc/ssl/private/prometheus1.key"}}}}

因此,["prometheus1.company.internal"]我不想擁有["{{ inventory_hostname }} .company.internal"](以及其他prometheus1.

我正在使用 docker_container 如下:

- name: create nginx reverse proxy container
 docker_container:
   image: registry.company.com/devops/nginx-reverseproxy:{{ nginx_version }}
   name: nginx-reverseproxy
   labels:
     role=metrics
   volumes:
     - /etc/ssl/certs/{{ inventory_hostname }}.crt:/etc/ssl/certs/{{ inventory_hostname }}.crt
     - /etc/ssl/private/{{ inventory_hostname }}.key:/etc/ssl/private/{{ inventory_hostname }}.key
   container_default_behavior: compatibility
   networks_cli_compatible: yes
   network_mode: default
   purge_networks: yes
   networks:
     - name: metrics-net
     - name: proxy-net
   env:
     STAGING_ENVIRONMENT: 'production'
     NGINX_VHOSTS_JSON: '{{ lookup("template", "rproxy/nginx_vhosts_prometheus_develop.j2") }}'

不幸的是,我不斷得到:

TASK [prometheus : create nginx reverse proxy container] **********************************************
fatal: [prometheus_vag]: FAILED! => {"changed": false, "msg": "Non-string value found for env option. Ambiguous env options must be wrapped in quotes to avoid them being interpreted. Key: NGINX_VHOSTS_JSON"}

奇怪的是,如果我只是使用模板模組,它會按預期工作:

 template:
   src: rproxy/nginx_vhosts_prometheus_develop.j2
   dest: /tmp/tempo.json
 when: "prometheus_host in inventory_hostname"
 tags:
   - copytmp

inventory_hostname將被庫存中的實際價值取代,我得到了正確的東西。此外,如果我將這個確切的結果作為 yaml playbook 中 NGINX_VHOSTS_JSON 的值粘貼到 playbook 中,它也可以正常工作。

但是查找模板似乎沒有提供預期的字元串。

有什麼想法可以解決這個問題嗎?

當它們看起來像結構的字元串表示時,Ansible 的模板通常會自動將它們轉換為資料結構。

在這種情況下,您可以通過在需要時將其顯式轉換為 JSON 來避免這種情況:

NGINX_VHOSTS_JSON: '{{ lookup("template", "rproxy/nginx_vhosts_prometheus_develop.j2") | to_json }}'

就個人而言,我會以更人性化的表示形式(例如 YAML)對其進行模板化,然後將其轉換為 JSON:

test.j2:

ip_access:
 IP_whitelist:
   192.168.99.19/32: grafana/status (Provider)
vhosts:
 {{ inventory_hostname }}.company.internal:
   add_lines_443:
   - include IP_whitelist;
   - set $prometheus http://prometheus:9090;
   - location / { proxy_pass $prometheus; }
   dns_names:
   - {{ inventory_hostname }}.company.internal
   options:
     cert_path: /etc/ssl/certs/{{ inventory_hostname }}.company.internal.crt
     key_path: /etc/ssl/private/{{ inventory_hostname }}.company.internal.key

test.yml:

- hosts: localhost
 gather_facts: false
 tasks:
   - debug:
       msg: "{{ lookup('template', 'test.j2') | from_yaml | to_json }}"

結果:

ok: [localhost] => {
   "msg": "{\"ip_access\": {\"IP_whitelist\": {\"192.168.99.19/32\": \"grafana/status (Provider)\"}}, \"vhosts\": {\"localhost.company.internal\": {\"add_lines_443\": [\"include IP_whitelist;\", \"set $prometheus http://prometheus:9090;\", \"location / { proxy_pass $prometheus; }\"], \"dns_names\": [\"localhost.company.internal\"], \"options\": {\"cert_path\": \"/etc/ssl/certs/localhost.company.internal.crt\", \"key_path\": \"/etc/ssl/private/localhost.company.internal.key\"}}}}"
}

引用自:https://serverfault.com/questions/1059481