vermilyear
Mission Specialist
Mission Specialist
  • 5,442 Views

Prepping for RHCE after passing RHCSA

Jump to solution

I've been studying for RHCSA for about the last four months and passed the exam yesterday on the first attempt with a 229. I am wanting to move on to the RHCE next. I am going to lean heavily on RH294 to prep for it and supplement with a few other resources. Is it reasonable to think that I could be exam ready in 6-8 weeks if I put the time in for some serious study?

The reason I am trying to complete it soon is that I have the RHLS just through January and am trying to maximize the exams I attempt in that time period. Any help from those who have been there would be awesome!

Labels (2)
25 Replies
Travis
Moderator
Moderator
  • 1,044 Views

hostvars[host]['ansible_enp0s8.ipv4.address'] 

appears to be keying in on a specific network adapter and IP address. Have you tried to use the following:

ansible_facts['default_ipv4']['address']

This should give you the default IP address of the system from the network adapter without referencing a specific adapter making the playbook more general.

Also, I would suggest ignoring Jinja2 templating for a bit until you can work out the variable and use the Debug command with a simpler playbook.

---
- name: Dump facts
  hosts: serverb
  become: false
  tasks:
    - name: Print Facts
      debug:
        var: ansible_facts
    - name: Print specific fact
      debug:
        msg: "Default Networking Information is {{ ansible_facts.default_ipv4 }}\n"

I used the first Debug to see all the facts, and the second dumped just default networking.

TASK [Print specific fact] ************************************************************************************************************************
ok: [serverb] => {
    "msg": "Default Networking Information is {'gateway': '172.25.250.254', 'interface': 'eth0', 'address': '172.25.250.11', 'broadcast': '172.25.250.255', 'netmask': '255.255.255.0', 'network': '172.25.250.0', 'prefix': '24', 'macaddress': '52:54:00:00:fa:0b', 'mtu': 1500, 'type': 'ether', 'alias': 'eth0'}\n"
}

If you want to go one step further, you can go all the way to just the IP address ... by adding .address

        msg: "Default Networking Information is {{ ansible_facts.default_ipv4.address }}\n"

 

TASK [Print specific fact] ************************************************************************************************************************
ok: [serverb] => {
    "msg": "Default Networking Information is 172.25.250.11\n"
}

NOTE: I took the lazy shortcut way here by not using fully qualified collection names or the [] notation to access the facts and the "." notation instead, but the point is still the same.

For a specific adapter ...

    - name: Print from specific adapter
      debug:
        msg: The default adapter information is {{ ansible_facts.eth0.ipv4 }}
TASK [Print from specific adapter] ****************************************************************************************************************
ok: [serverb] => {
    "msg": "The default adapter information is {'address': '172.25.250.11', 'broadcast': '172.25.250.255', 'netmask': '255.255.255.0', 'network': '172.25.250.0', 'prefix': '24'}"
}

So now I've narrowed down to what I want (almost) I need just the address portion ...

    - name: Print from specific adapter
      debug:
        msg: The IP Address for ETH0 is {{ ansible_facts.eth0.ipv4.address }}
TASK [Print from specific adapter] ****************************************************************************************************************
ok: [serverb] => {
    "msg": "The IP Address for ETH0 is 172.25.250.11"
}

Using Debug can be a powerful way to see how variables are evaluated and narrow down to what you want out of the JSON output that goes to the screen. It is important to dump the entire contents so you can work your way down to just the piece that you want.

After you've figured out the variables and the syntax and format for adding the items you want, then you can put that data back in to the playbooks (or in your case a JINJA2 template) and yield the expected resuts.

 

 

Travis Michette, RHCA XIII
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
Travis
Moderator
Moderator
  • 1,038 Views

Also, sometimes using the hostvars can be confusing too and trying your code even with something simpler, you might want to check ...

- name: Print using hostvars
debug:
msg: The hostname is {{ hostvars[inventory_hostname]['ansible_hostname'] }}

There typically isn't a host keyword like you have. When using hostvars you are typically providing a hostname, host group, or something else there from your magic variables. 

Now looking at your JINJA2 template, you are wanting to loop, so host is technically a valid variable, however, one could argue that still technically isn't needed as you don't need "hostvars" at all to get/access/print/consume the information you are wanting. It looks like you are just trying to create an /etc/hosts type file from your Ansible inventory.

Travis Michette, RHCA XIII
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
0 Kudos
Travis
Moderator
Moderator
  • 1,071 Views

This has nothing to do with missed packages or missing items as you did verify that the ad-hoc command with the "setup" module gathers the facts that you want. 

If you look at the error message, it related to an undefined variable.

 

"AnsibleUndefinedVariable: 'ansible.vars.hostvars.HostVarsVars object' has no attribute 'ansible_enp0s8.ipv4.address'"}

Namely, the way you are attempting to access the data is slightly incorrect. 

Travis Michette, RHCA XIII
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
Travis
Moderator
Moderator
  • 1,036 Views

So the real problem as I expected is the use of hostvars and trying to access the elements. I went ahead and created a playbook, the Jinja2 template and everything else that would work to generate and create an /etc/hosts style file.

Playbook:

https://github.com/tmichett/RH294/blob/master/Ansible_Playbooks/Chapter3/Build_ETC_Hosts.yml

Jinja2 Template: https://github.com/tmichett/RH294/blob/master/Ansible_Playbooks/Chapter3/etc_hosts.j2

Essentially, it is the accessing of the variables that you had issues with as you were combining two different methods. When using the [] that needs to separate everything with the "." so you had yours kinda combined.

{% for host in groups['all'] %}
{{ hostvars[inventory_hostname]['ansible_facts']['eth0']['ipv4']['address'] }} {{ hostvars[inventory_hostname]['ansible_facts']['fqdn'] }} {{ hostvars[inventory_hostname]['ansible_facts']['hostname'] }}
{% endfor %}

 

Yours was 

{% for host in groups['all'] %}
{{ hostvars[host]['ansible_enp0s8.ipv4.address'] }} {{ hostvars[host]['ansible_fqdn'] }} {{ hostvars[host]['ansible_hostname'] }}
{% endfor %}

And it couldn't access the variable as it didn't exist.

The respository links I posted here are part of a larger repository with demo playbooks for Ansible focused around the RH294 course. Feel free to use those to assist in learning Ansible and practicing.

Again, the large caution here, but I made my JINJA tempalte and playbook to match is that you are using a "named" network interface. That interface will not exist on all systems. The better thing there is default IPv4 address because if you are constructing /etc/host files, that is what should be used. Otherwise, you will need to use way more advanced Ansible features like templates, queries, lookups, filters to determine the names of the network devices before you grab the IP addresses. The playbook with a fixed Network device name will FAIL on systems that don't have a device with that name.

Hope that helps

Travis Michette, RHCA XIII
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
cvb97
Flight Engineer
Flight Engineer
  • 1,007 Views

Hi Travis, thanks a mil for your input, My LAB setup needs to point to a specific network interface wihich will be 'enp0s8'. What is confusing me is thr 'for; statement on the jinja2 templating. According to ethe RH294 students guide my template is correct .

I see you use [inventory_hostname] which makes sense whereas the book uses [host]

as the variable for {% for host in groups['all'] %} which fails with the errors 

TASK [deploy template] ******
********************
skipping: [node2]
skipping: [node3]
skipping: [node5]
skipping: [node4]
fatal: [node1]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'ansible.vars.hostvars.HostVarsVars object' has no attribute 'ansible_enp0s8.ipv4.address'"}

cvb97_0-1693194763166.png

where you're way works.

TASK [deploy template] ***************************************************************************************************************TASK [deploy hosts template] *****************************************************************************************************************************
skipping: [node2]
skipping: [node3]
skipping: [node4]
skipping: [node5]
ok: [node1]

0 Kudos
cvb97
Flight Engineer
Flight Engineer
  • 1,001 Views

Thanks Travis, I figured it out. they work both ways, I must be carefull on the way I write it.

template error while templating string: expected token ',',

Join the discussion
You must log in to join this conversation.