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'