1

I am trying to use a template which generate the config file containing tinformations like the hosts, port, username, password, ...
I want to use one template and pass the tag in the template task, so the template will pick variables which are defined within the corresponding tag, i.e.:

- name: generate config
  template:
    src: /test/debezium_oracle_cdc_source.j2
    dest: "/config/debz-oracle-test_1.json"
  vars:
    tags: "{{ oracle['tag1']  }}"
    bootstrap_servers: "kafka:9092"

- name: generate config
  template:
    src: /test/debezium_oracle_cdc_source.j2
    dest: "/config/debz-oracle-test_2.json"
  vars:
    tags: "{{ oracle['tag2']  }}"
    bootstrap_servers: "kafka:9092"

My variable file

oracle:
   tag1:
       tables:
         - DEPT
         - EMPLOYEE
      db_host: localhost
      db_name: root
      db_user: root
      db_port: 1521
      
  tag2:
       tables:
         - SALES
         - SALES_ITEM
      db_host: localhost
      db_name: root
      db_user: root
      db_port: 1521

debezium_oracle_cdc_source.j2:

{
  "database.hostname": "{{ db_host }}",
  "database.port": "{{ db_port }}"
}

Basically, I want to make my variable file more readable.

β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83

2 Answers2

0

Your issue is coming from the fact that tags is a reserved word in Ansible, because it is an existing keyword.

This can be reproduced and confirmed with a simple task like:

- debug:
    msg: "{{ tags }}"
  vars:
    tags: I guess I am buggy?

Which does error:

fatal: [localhost]: FAILED! => 
  msg: |-
    The task includes an option with an undefined variable. 
    The error was: 'tags' is undefined. 'tags' is undefined
  
    The error appears to be in '/usr/local/ansible/play.yml': 
    line 7, column 7, but may be elsewhere in the file 
    depending on the exact syntax problem.
  
    The offending line appears to be:
  
      tasks:
        - debug:
          ^ here

This can be easily fixed, for example, by prefixing the variable with an underscore:

- debug:
    msg: "{{ _tags }}"
  vars:
    _tags: I guess I am buggy?

This yields the expected:

ok: [localhost] => 
  msg: I guess I am buggy?

So in your case with the template debezium_oracle_cdc_source.j2 containing:

{
  "database.hostname": "{{ _tags.db_host }}",
  "database.port": "{{ _tags.db_port }}"
}

And the task:

- template:
    src: debezium_oracle_cdc_source.j2
    dest: "/config/debz-oracle-test_{{ item }}.json"
  loop: "{{ range(1, 3) }}"
  vars:
    _tags: "{{ oracle['tag' ~ item]  }}"
    oracle:
      tag1:
          db_host: host1.localhost
          db_port: 1234
      tag2:
          db_host: host2.localhost
          db_port: 5678

We do get the two expected JSON:

  • /config/debz-oracle-test_1.json:
    {
      "database.hostname": "host1.localhost",
      "database.port": "1234"
    }
    
  • /config/debz-oracle-test_2.json:
    
    {
      "database.hostname": "host2.localhost",
      "database.port": "5678"
    }
    
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
  • Thanks , it worked !! Sorry for initial description from next time will try to post as much as possible in description – rahul verma Apr 04 '23 at 07:46
0

Use the dictionary tags in the template

{
  "database.hostname": "{{ tags.db_host }}",
  "database.port": "{{ tags.db_port }}"
}
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63