How to Dynamically Display Hostname in Ansible MOTD Using Jinja2 Templates


4 views

When configuring Message of the Day (MOTD) across multiple servers, it's common to want dynamic hostname inclusion. The challenge lies in making this work with Ansible's idempotent architecture while maintaining clean configuration management.

Ansible automatically gathers system facts that include the hostname. The most reliable variables are:

ansible_hostname  # Short hostname (e.g., "webserver1")
ansible_fqdn      # Fully qualified domain name
ansible_nodename  # Kernel-reported hostname

The optimal approach uses Jinja2 templating with the template module instead of copy:

- name: Configure MOTD with hostname
  template:
    src: motd.j2
    dest: /etc/motd
    owner: root
    group: root
    mode: '0644'

Create a template file with dynamic hostname insertion:

Welcome to {{ ansible_hostname }}

System Information:
- OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
- Kernel: {{ ansible_kernel }}
- Processor: {{ ansible_processor_vcpus }} vCPUs

Last configuration applied: {{ ansible_date_time.iso8601 }}

For more complex environments, you might want conditional logic:

{% if 'prod' in ansible_hostname %}
WARNING: PRODUCTION SERVER {{ ansible_hostname|upper }}
{% else %}
Development server: {{ ansible_hostname }}
{% endif %}

If facts aren't available, you can capture the hostname directly:

- name: Get hostname via command
  command: hostname
  register: hostname_result
  changed_when: false

- name: Create MOTD with command output  
  copy:
    content: "Welcome to {{ hostname_result.stdout }}"
    dest: /etc/motd

Always validate your MOTD configuration:

- name: Verify MOTD content
  command: cat /etc/motd
  register: motd_content
  changed_when: false

- debug:
    var: motd_content.stdout

When configuring Message of the Day (MOTD) across multiple servers, we often need to display the host-specific information. The challenge is to dynamically insert each machine's hostname into a centralized template.

Ansible automatically gathers system facts, including the hostname, which we can access through the ansible_hostname variable. This is available without any additional setup:


- name: Display hostname
  debug:
    var: ansible_hostname

Instead of using the copy module, switch to the template module with Jinja2 templating:


- name: Configure MOTD with hostname
  template:
    src: motd.j2
    dest: /etc/motd
    owner: root
    group: root
    mode: '0644'

Create a file named motd.j2 in your templates directory with this content:


Welcome to {{ ansible_hostname }}

System Information:
- OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
- Kernel: {{ ansible_kernel }}
- Processor: {{ ansible_processor_vcpus }} vCPUs

If you need the fully qualified domain name instead:


Welcome to {{ ansible_fqdn }}

Or for systems where the hostname command output is preferred:


- name: Get hostname via command
  command: hostname
  register: hostname_result

# Then reference it as:
{{ hostname_result.stdout }}

For systems where facts might not be available (rare), you can use this fallback:


{{ ansible_hostname | default(ansible_fqdn | default(hostname_result.stdout | default('localhost'))) }}

Here's how your role might look in practice:


# tasks/main.yml
- name: Ensure MOTD directory exists
  file:
    path: /etc/motd.d
    state: directory

- name: Deploy MOTD template
  template:
    src: motd.j2
    dest: /etc/motd.d/00-main
    mode: '0644'

- name: Update MOTD processing
  copy:
    content: |
      #!/bin/sh
      cat /etc/motd.d/* > /etc/motd
    dest: /etc/update-motd.d/99-custom
    mode: '0755'