Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined 'ansible_host' in local_action hostvars #21269

Closed
dgoodwin opened this issue Feb 10, 2017 · 6 comments
Closed

Undefined 'ansible_host' in local_action hostvars #21269

dgoodwin opened this issue Feb 10, 2017 · 6 comments
Labels
affects_2.2 This issue/PR affects Ansible v2.2 bug This issue/PR relates to a bug.

Comments

@dgoodwin
Copy link

ISSUE TYPE
  • Bug Report
COMPONENT NAME

local_action

ANSIBLE VERSION
ansible 2.2.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
CONFIGURATION
OS / ENVIRONMENT

Seen on Fedora 25 and RHEL 7.

SUMMARY

There appears to be a problem where the ansible_host inventory variable appears unset if used within a local_action.

STEPS TO REPRODUCE
---
- name: Test Play
  hosts:  yourhostgroup
  gather_facts: no
  remote_user: root
  tasks:
  - name: Task 1
    debug: var=inventory_hostname

  - name: Task 2
    debug: var=ansible_host

  - name: Task 3
    local_action:
      module: debug
        var=ansible_host

  - name: Task 4
    local_action:
      module: debug
        var=hostvars[inventory_hostname]['ansible_host']
EXPECTED RESULTS

We expected Task 4 to output the ansible_host value of "54.158.245.48".

Per #16139 it appears that this is the recommended way to do something like wait_for in a local_action when waiting for a system to restart. Without it, there appears to be no way to access the host in situations where inventory_hostname cannot be reached from the local system running ansible.

ACTUAL RESULTS

Solution from #16139 appears to no longer work as ansible_host is not defined by default within inventory_vars. (unless you set it yourself explicitly)

PLAY [Test Play] ***************************************************************

TASK [Task 1] ******************************************************************
ok: [ded-int-aws-master-dbea1] => {
    "inventory_hostname": "ded-int-aws-master-dbea1"
}
ok: [ded-int-aws-master-4b25f] => {
    "inventory_hostname": "ded-int-aws-master-4b25f"
}
ok: [ded-int-aws-master-9938e] => {
    "inventory_hostname": "ded-int-aws-master-9938e"
}

TASK [Task 2] ******************************************************************
ok: [ded-int-aws-master-dbea1] => {
    "ansible_host": "54.158.245.48"
}
ok: [ded-int-aws-master-4b25f] => {
    "ansible_host": "54.227.231.254"
}
ok: [ded-int-aws-master-9938e] => {
    "ansible_host": "54.242.207.100"
}

TASK [Task 3] ******************************************************************
ok: [ded-int-aws-master-dbea1 -> localhost] => {
    "ansible_host": "localhost"
}
ok: [ded-int-aws-master-4b25f -> localhost] => {
    "ansible_host": "localhost"
}
ok: [ded-int-aws-master-9938e -> localhost] => {
    "ansible_host": "localhost"
}

TASK [Task 4] ******************************************************************
ok: [ded-int-aws-master-dbea1 -> localhost] => {
    "hostvars[inventory_hostname]['ansible_host']": "VARIABLE IS NOT DEFINED!"
}
ok: [ded-int-aws-master-4b25f -> localhost] => {
    "hostvars[inventory_hostname]['ansible_host']": "VARIABLE IS NOT DEFINED!"
}
ok: [ded-int-aws-master-9938e -> localhost] => {
    "hostvars[inventory_hostname]['ansible_host']": "VARIABLE IS NOT DEFINED!"
}

PLAY RECAP *********************************************************************
ded-int-aws-master-4b25f   : ok=4    changed=0    unreachable=0    failed=0   
ded-int-aws-master-9938e   : ok=4    changed=0    unreachable=0    failed=0   
ded-int-aws-master-dbea1   : ok=4    changed=0    unreachable=0    failed=0   

We did find a simple workaround just using a set_fact to assign some variable to the value of ansible_host, then using it within the local_action.

@bcoca
Copy link
Member

bcoca commented Feb 13, 2017

ansible_host is set after an attempted connection, which you don't.

Also debug in any case ignores connections as it runs 'in memory' on the controller at all times, using local_action is irrelevant for this type of module.

Can you show any other case in which this is an issue that does not match the above?

@bcoca bcoca added needs_info This issue requires further information. Please answer any outstanding questions. and removed needs_triage Needs a first human triage before being processed. labels Feb 13, 2017
@dgoodwin
Copy link
Author

The bug surfaced when trying to wait for a host to reboot with a task like this:

  - name: Wait for master to restart
    local_action:
      module: wait_for
        host="{{ hostvars[inventory_hostname]['ansible_host'] }}"
        port="{{ ansible_port | default(22,boolean=True) }}"
        delay=10
        state=started
        timeout=600
    become: no

This appeared to be best option in environments where inventory_hostname is not necessarily reachable (which ours is), as described in workaround for #16139. debug was just our attempt to replicate as simply as possible.

@ansibot ansibot removed the needs_info This issue requires further information. Please answer any outstanding questions. label Feb 13, 2017
@bcoca
Copy link
Member

bcoca commented Feb 13, 2017

well, this wouldn't work for the same reason, ansible_host would correspond to localhost as you delegate_to it, use connection: local instead, but that will only preserve the connection info from the original host, if the variable was not set for it, it still won't appear.

@dgoodwin
Copy link
Author

Sorry @bcoca I am confused.

We picked up this example from #16139, it appeared that going to hostvars[inventory_hostname]['ansible_host'] might work, given that inventory_hostname would still point to the remote system we're waiting for. Are you saying it's expected for ansible_host to not be defined in that context?

I do notice that:

  - name: Task 2
    debug: var=ansible_host
  - name: Task 5
    debug: var=hostvars[inventory_hostname]['ansible_host']

Task 2 will show the host, task 5 will not, which confused us.

If this is not a bug and there is not expected to be any way to access the remote IP if inventory_hostname isn't reachable feel free to close, we have the set_fact workaround it just felt like this might be a bug.

@bcoca
Copy link
Member

bcoca commented Feb 13, 2017

it would be a bug if you defined ansible_host in inventory and it is not appearing when you reference it, it is not a bug if you are expecting the return of the connection to define it.

@dgoodwin
Copy link
Author

I understand, thanks @bcoca .

CC @mwoodson @detiber

@ansibot ansibot added bug This issue/PR relates to a bug. and removed bug_report labels Mar 7, 2018
@ansible ansible locked and limited conversation to collaborators Apr 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.2 This issue/PR affects Ansible v2.2 bug This issue/PR relates to a bug.
Projects
None yet
Development

No branches or pull requests

3 participants