Introduction
Once inventory and access work, a common next task is deploying baseline files. Baseline files might include banners, service snippets, or compliance markers that should be consistent across hosts but still contain host-specific values.
In this lab, you will create a small multi-host inventory, define group variables, write a template, run a playbook, and verify per-host baseline files.
Create the Baseline Deployment Project
In this step, you will create a project with inventory, templates, files, and playbooks. The structure separates reusable source content from playbook logic.
Create and enter the project.
cd /home/labex/project
mkdir -p rhce-ansible/{inventory/group_vars,playbooks,files,templates,managed}
cd rhce-ansible
Create ansible.cfg.
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
retry_files_enabled = False
interpreter_python = auto_silent
EOF
The directories separate roles in the workflow: files holds content copied unchanged, templates holds content rendered with variables, playbooks holds automation logic, and managed will show the final per-host result.
Create Inventory and Baseline Variables
In this step, you will define two managed host aliases and shared baseline variables. The variables will be used later in a template.
Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
Create the inventory.
cat > inventory/hosts <<'EOF'
[managed]
node1 ansible_connection=local
node2 ansible_connection=local
EOF
The two aliases let one playbook produce two separate managed outputs. Even though both aliases run on the same VM, Ansible still renders inventory_hostname differently for each host.
Create group variables for managed hosts.
cat > inventory/group_vars/managed.yml <<'EOF'
baseline_owner: labex
baseline_environment: training
EOF
These variables apply to every host in the managed group. They represent values that should be shared across the baseline, while the host name will remain host-specific.
Create Source File and Template
In this step, you will create source content. The plain file is copied unchanged. The Jinja2 template uses variables such as inventory_hostname and baseline_environment to render host-specific output.
Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
Create a shared banner file.
cat > files/banner.txt <<'EOF'
Managed by RHCE Ansible Prep
EOF
The banner is plain source content. It will be copied exactly as written, so it is useful for text that should not vary by host.
Create a template.
cat > templates/baseline.conf.j2 <<'EOF'
host={{ inventory_hostname }}
environment={{ baseline_environment }}
owner={{ baseline_owner }}
EOF
The template contains Jinja2 expressions. When Ansible renders it, inventory_hostname becomes node1 or node2, while the baseline variables come from inventory/group_vars/managed.yml.
Write the Baseline Deployment Playbook
In this step, you will write a playbook that creates one directory per host alias and deploys both the shared banner and rendered template. Because the playbook is stored in playbooks, source paths use ../files and ../templates.
Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
Create the playbook.
cat > playbooks/deploy-baseline.yml <<'EOF'
---
- name: Deploy baseline files to managed aliases
hosts: managed
gather_facts: false
tasks:
- name: Create per-host baseline directory
ansible.builtin.file:
path: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}"
state: directory
mode: '0755'
- name: Copy shared banner
ansible.builtin.copy:
src: ../files/banner.txt
dest: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}/banner.txt"
mode: '0644'
- name: Render baseline configuration
ansible.builtin.template:
src: ../templates/baseline.conf.j2
dest: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}/baseline.conf"
mode: '0644'
EOF
Read the three tasks as a complete deployment sequence. First the destination directory is created for each host alias, then the static banner is copied, and finally the template is rendered into a host-specific configuration file.
Run a syntax check.
ansible-playbook playbooks/deploy-baseline.yml --syntax-check
The syntax check should print a playbook: line. It confirms Ansible can parse the relative source paths before the playbook writes any managed files.
Run and Verify the Baseline Deployment
In this step, you will run the playbook and inspect the rendered files. The rendered configuration should differ by host name while keeping the shared environment and owner values.
Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
Run the playbook.
ansible-playbook playbooks/deploy-baseline.yml
The first run should report changes because the managed directories and files do not exist yet. A successful recap with failed=0 means every host alias received the baseline.
Inspect the deployed files.
find managed -maxdepth 3 -type f -print
cat managed/node1/banner.txt managed/node1/baseline.conf managed/node2/banner.txt managed/node2/baseline.conf
The banner.txt files should match each other exactly. The baseline.conf files should share the same environment and owner values but differ in the host= line.
Summary
You deployed baseline files to managed host aliases using inventory variables, a shared source file, and a Jinja2 template. This completes the foundation for repeatable managed-node state changes.


