Search code examples
ansiblejinja2ansible-2.xansible-template

Ansible: Copy one server hostname to another using jinja template


I have two windows server, assume serverA and serverB. I need to take the hostname of serverA as a variable and replace it in Jinja template and copy it in serverB. I am not able to find any solution how to use dependency of servers in Ansible. Is there any solution that work in this scenario?

I have tried to use ansible.builtin.hostname but it does not allows to register hostname unless only allow to change

- name: Set a hostname
  ansible.builtin.hostname:
    name: web01

Solution

  • Where to gather the info

    Inventory

    A first approach would be to have your relevant hostnames directly in your inventory:

    inventory/hosts.yml

    ---
    all:
      hosts:
        nameOfServerA.company.loc:
        nameOfServerB.company.loc:
    

    You can then retrieve the short or full hostname for the current target with respectively {{ inventory_hostname }} and {{ inventory_hostname_short }}

    target server facts

    If for whatever reason you only have aliases in your inventory, or your inventory names do not match the hosts in your inventory, you can retrieve the current configured host name from the gathered facts. Of course your play needs to run with gather_facts: true (default). You can then retrieve that info for the current host in the {{ ansible_hostname }} variable

    Getting the info for an other host

    This is not more different that getting any other fact/var from an other host as explained for example in the playbook guide. Here is a short playbook.yml example for the above situations:

    ---
    - name: Make sure we gather facts from all hosts in inventory
      # Note: this play is only necessary for gathering the hostname from facts.
      # Getting it from inventory does not require to gather_facts.
      hosts: all
      gather_facts: true  # default so you can skip it if you want.
    
    - name: Display hostname for serverB from serverA
      hosts: nameOfServerA.company.loc
      # Facts are already gathered
      gather_facts: false
    
      vars:
        target: nameOfServerB.company.loc
    
      tasks:
        - name: "Display info for {{ target }}"
          ansible.builtin.debug:
            msg:
              - inventory_hostname is {{ hostvars[target].inventory_hostname }}
              - inventory_hostname_short is {{ hostvars[target].inventory_hostname_short }}
              - ansible_hostname is {{ hostvars[target].ansible_hostname }}
    

    Playing the above with: ansible-playbook -i inventory/ playbook.yml should give something like:

    PLAY [Make sure we gather facts from all hosts in inventory] **********************************************************************************************************************************************
    
    TASK [Gathering Facts] ************************************************************************************************************************************************************************************
    ok: [nameOfServerB.company.loc]
    ok: [nameOfServerA.company.loc]
    
    PLAY [Display hostname for serverB from serverA] **********************************************************************************************************************************************************
    
    TASK [Display info for nameOfServerB.company.loc] ********************************************************************************************************************************************************************************************
    ok: [nameOfServerA.company.loc] => {
        "msg": [
            "inventory_hostname is nameOfServerB.company.loc",
            "inventory_hostname_short is nameOfServerB",
            "ansible_hostname is <some hostname configured on serverB>"
        ]
    }
    
    PLAY RECAP ************************************************************************************************************************************************************************************************
    nameOfServerA.company.loc  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    nameOfServerB.company.loc  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0