Hi gentlemen,
We are using the Ansible to manage many servers, and we like the dry run
mode which with parameters "--check" and "--diff". We always run with these
parameters first to verify that if the changes will be made correctly.
The customized facts are very helpful, to generate some dynamic facts. But
the trouble is, when we ran with "--check", ansible skipped the customized
module.
So we can't use the dry run to check before we push if there are some
customized facts used in templates files.
Is there a way to fix this or work around?

Here are the detailed informations:

[root@idc1-server1 ansible]# cat roles/myfacts/tasks/main.yml
---
- name: run myfacts module to get customized facts
   myfacts: get_facts=yes

- name: update file with the customized facts
   template: src=myfacts.txt.j2 dest=/tmp/myfacts.txt

[root@idc1-server1 ansible]# cat roles/myfacts/templates/myfacts.txt.j2
ansible_private_ipv4_address : {{ ansible_private_ipv4_address }}

[root@idc1-server1 ansible]# cat library/heylinux/myfacts

#!/usr/bin/python

import sys
import json
import shlex
import commands
import re

def get_ansible_private_ipv4_address():
     iprex = "(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1])"
     output = commands.getoutput("""/sbin/ifconfig |grep "Link encap" |awk '{print $1}' |grep -wv 'lo'""")
     nics = output.split('\n')
     for i in nics:
         ipaddr = commands.getoutput("""/sbin/ifconfig %s |grep -w "inet addr" |cut -d: -f2 | awk '{print $1}'""" % (i))
         if re.match(iprex,ipaddr):
             ansible_private_ipv4_address = ipaddr
             return ansible_private_ipv4_address

ansible_facts_dict = {
         "changed" : False,
         "ansible_facts" : {
             }
     }

args_file = sys.argv[1]
args_data = file(args_file).read()

arguments = shlex.split(args_data)
for arg in arguments:
     if "=" in arg:
         (key, value) = arg.split("=")
         if key == "get_facts" and value == "yes":
             ansible_private_ipv4_address = get_ansible_private_ipv4_address()
             ansible_facts_dict['ansible_facts']['ansible_private_ipv4_address'] = ansible_private_ipv4_address

print json.dumps(ansible_facts_dict)


[root@idc1-server1 ansible]# cat myfacts.yml
---
- hosts: all
   roles:
   - myfacts

[root@idc1-server1 ansible]#ansroot myfacts.yml -i hosts.idc1 --limit
idc1-server1
PLAY [all]
********************************************************************

GATHERING FACTS
***************************************************************
ok: [idc1-server1]

TASK: [myfacts | run myfacts module to get customized facts] **************
ok: [idc1-server1]

TASK: [myfacts | update file with the customized facts]
*********************
changed: [idc1-server1]

PLAY RECAP
********************************************************************
idc1-server1 : ok=3 changed=1 unreachable=0
failed=0

[root@idc1-server1 ansible]#ansroot myfacts.yml -i hosts.idc1 --limit
idc1-server1 --check --diff
PLAY [all]
********************************************************************

GATHERING FACTS
***************************************************************

ok: [idc1-server1]

TASK: [myfacts | run myfacts module to get customized facts] **************
skipping: [idc1-server1]

TASK: [myfacts | update file with the customized facts]
*********************
fatal: [idc1-server1] => {'msg': "One or more undefined variables:
'ansible_private_ipv4_address' is undefined", 'failed': True}
fatal: [idc1-server1] => {'msg': "One or more undefined variables:
'ansible_private_ipv4_address' is undefined", 'failed': True}

FATAL: all hosts have already failed -- aborting

PLAY RECAP
********************************************************************
            to retry, use: --limit @/root/myfacts.retry

idc1-server1 : ok=1 changed=0 unreachable=1
failed=0

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-project+unsubscribe@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/1211128a-820e-4b4b-bc18-8a62aaea2a0f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Brian Coca at Dec 19, 2014 at 3:09 pm
    You need to let ansible know your module supports check mode, this is
    done by instantiating the module class and adding
    'supports_check_mode=True'.

    --
    Brian Coca

    --
    You received this message because you are subscribed to the Google Groups "Ansible Project" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to ansible-project+unsubscribe@googlegroups.com.
    To post to this group, send email to ansible-project@googlegroups.com.
    To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/CAJ5XC8nKPf-rsm43fdUn3KSo_UvpH3CN__a07Wap1ftNs8X7TQ%40mail.gmail.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dong Guo at Dec 25, 2014 at 10:44 am
    Thanks Brian Coca!
    I fixed the issue by updating my custom module as follow:

    #!/usr/bin/python

    import json
    import commands
    import re

    def get_ansible_private_ipv4_address():
         iprex = "(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1])"
         output = commands.getoutput("""/sbin/ifconfig |grep "Link encap" |awk '{print $1}' |grep -wv 'lo'""")
         nics = output.split('\n')
         for i in nics:
             ipaddr = commands.getoutput("""/sbin/ifconfig %s |grep -w "inet addr" |cut -d: -f2 | awk '{print $1}'""" % (i))
             if re.match(iprex,ipaddr):
                 ansible_private_ipv4_address = ipaddr
                 return ansible_private_ipv4_address

    def main():
         global module
         module = AnsibleModule(
             argument_spec = dict(
                 get_facts=dict(default="yes", required=False),
             ),
             supports_check_mode = True,
         )

         ansible_facts_dict = {
             "changed" : False,
             "ansible_facts": {
                 }
         }

         if module.params['get_facts'] == 'yes':
             ansible_private_ipv4_address = get_ansible_private_ipv4_address()
             ansible_facts_dict['ansible_facts']['ansible_private_ipv4_address'] = ansible_private_ipv4_address

         print json.dumps(ansible_facts_dict)

    from ansible.module_utils.basic import *
    from ansible.module_utils.facts import *
    main()


    On Friday, December 19, 2014 11:35:27 AM UTC+8, Dong Guo wrote:

    Hi gentlemen,
    We are using the Ansible to manage many servers, and we like the dry run
    mode which with parameters "--check" and "--diff". We always run with these
    parameters first to verify that if the changes will be made correctly.
    The customized facts are very helpful, to generate some dynamic facts. But
    the trouble is, when we ran with "--check", ansible skipped the customized
    module.
    So we can't use the dry run to check before we push if there are some
    customized facts used in templates files.
    Is there a way to fix this or work around?

    Here are the detailed informations:

    [root@idc1-server1 ansible]# cat roles/myfacts/tasks/main.yml
    ---
    - name: run myfacts module to get customized facts
    myfacts: get_facts=yes

    - name: update file with the customized facts
    template: src=myfacts.txt.j2 dest=/tmp/myfacts.txt

    [root@idc1-server1 ansible]# cat roles/myfacts/templates/myfacts.txt.j2
    ansible_private_ipv4_address : {{ ansible_private_ipv4_address }}

    [root@idc1-server1 ansible]# cat library/heylinux/myfacts

    #!/usr/bin/python

    import sys
    import json
    import shlex
    import commands
    import re

    def get_ansible_private_ipv4_address():
    iprex = "(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1])"
    output = commands.getoutput("""/sbin/ifconfig |grep "Link encap" |awk '{print $1}' |grep -wv 'lo'""")
    nics = output.split('\n')
    for i in nics:
    ipaddr = commands.getoutput("""/sbin/ifconfig %s |grep -w "inet addr" |cut -d: -f2 | awk '{print $1}'""" % (i))
    if re.match(iprex,ipaddr):
    ansible_private_ipv4_address = ipaddr
    return ansible_private_ipv4_address

    ansible_facts_dict = {
    "changed" : False,
    "ansible_facts" : {
    }
    }

    args_file = sys.argv[1]
    args_data = file(args_file).read()

    arguments = shlex.split(args_data)
    for arg in arguments:
    if "=" in arg:
    (key, value) = arg.split("=")
    if key == "get_facts" and value == "yes":
    ansible_private_ipv4_address = get_ansible_private_ipv4_address()
    ansible_facts_dict['ansible_facts']['ansible_private_ipv4_address'] = ansible_private_ipv4_address

    print json.dumps(ansible_facts_dict)


    [root@idc1-server1 ansible]# cat myfacts.yml
    ---
    - hosts: all
    roles:
    - myfacts

    [root@idc1-server1 ansible]#ansroot myfacts.yml -i hosts.idc1 --limit
    idc1-server1
    PLAY [all]
    ********************************************************************

    GATHERING FACTS
    ***************************************************************
    ok: [idc1-server1]

    TASK: [myfacts | run myfacts module to get customized facts] **************
    ok: [idc1-server1]

    TASK: [myfacts | update file with the customized facts]
    *********************
    changed: [idc1-server1]

    PLAY RECAP
    ********************************************************************
    idc1-server1 : ok=3 changed=1 unreachable=0
    failed=0

    [root@idc1-server1 ansible]#ansroot myfacts.yml -i hosts.idc1 --limit
    idc1-server1 --check --diff
    PLAY [all]
    ********************************************************************

    GATHERING FACTS
    ***************************************************************

    ok: [idc1-server1]

    TASK: [myfacts | run myfacts module to get customized facts] **************
    skipping: [idc1-server1]

    TASK: [myfacts | update file with the customized facts]
    *********************
    fatal: [idc1-server1] => {'msg': "One or more undefined variables:
    'ansible_private_ipv4_address' is undefined", 'failed': True}
    fatal: [idc1-server1] => {'msg': "One or more undefined variables:
    'ansible_private_ipv4_address' is undefined", 'failed': True}

    FATAL: all hosts have already failed -- aborting

    PLAY RECAP
    ********************************************************************
    to retry, use: --limit @/root/myfacts.retry

    idc1-server1 : ok=1 changed=0 unreachable=1
    failed=0
    --
    You received this message because you are subscribed to the Google Groups "Ansible Project" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to ansible-project+unsubscribe@googlegroups.com.
    To post to this group, send email to ansible-project@googlegroups.com.
    To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/54ae0617-dbbf-44ee-991e-142f243be60a%40googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupansible-project @
postedDec 19, '14 at 2:27p
activeDec 25, '14 at 10:44a
posts3
users2

2 users in discussion

Dong Guo: 2 posts Brian Coca: 1 post

People

Translate

site design / logo © 2022 Grokbase