Informing the IBM Community

More fun with Ansible for IBM i Messing about with Ansible for i modules

0
(0)

In this article I decided to make use of a number of the Ansible for i modules to demonstrate their use for more usual day to day CL related tasks.

A word of warning before I start. The playbook I’ve developed is relatively long and contains all the variables and tasks in one yaml file. IF I were developing this for production use the playbook would be much shorter and would make use of Ansible roles to separate out the variables and break up the tasks in to separate code chunks. My expectation is that most of the IBM i users who read this will be new to Ansible so for the sake of clarity I have created a single yaml playbook and structured it in a similar manner to a CL program.

In my previous articles I introduced you to Ansible and how to set it up to use the Ansible for i collection from IBM. I followed this up with a second article which shows how you can use Ansible for i modules to upload and install PTFs.

Overview of the playbook

I wanted to get familiar with a number of the modules so concocted a scenario that allowed this. I was particularly keen to get to know:

  • ibmi_object_find
  • ibmi_user_and _group
  • ibmi_cl_command
  • ibmi_sql_query
  • ibmi_sql_execute

The playbook does the following:

  • Checks that the user profile and library we are going to create doesn’t already exist. If either exists, then abort the playbook
  • Creates a user profile and library with the same name (ROBINSG)
  • Copies the QIWS/QCUSTCDT file into the new library and then creates and journal receiver and journal for the file. This is required as I’ll be running a DELETE FROM statement against the file
  • Changes the ownership and *PUBLIC authority for the objects to ROBINSG and *EXCLUDE respectively
  • Create an IFS home directory, /home/robinsg, for the user and then copies an rsa public key to /home/robinsg/.ssh/authorized_keys so that we can run modules as the new user
  • Run SQL SELECT and DELETE statements

Below, I’ll describe the main parts of the playbook but you can download the complete playbook here.

Playbook — Setting things up

In the first section of the playbook I’m simply setting variables and referencing the Ansible for i collection, ibm.power_ibmi.


# setup_user_and_run_SQL
– name: Set up a user, library and then run SQL statements
  hosts: all
  vars:
    usrprf: ‘ROBINSG’
    usrcls: ‘*USER’
    homedir: ‘/home/robinsg’
    curlib: “{{ usrprf }}”
    text: ‘Glenn Robinson’
    public_auth: ‘*NONE’
    srclib: ‘QIWS’
    srcfile: ‘QCUSTCDT’
    jrn: ‘ANSIBJRN’
    jrnrcv: ‘ANSIBRCV01’
    sshfile: ‘ansible_id_rsa.pub’
  gather_facts: no
  collections:
    – ibm.power_ibmi

Initial checks

Here we run a block of tasks to ensure the user profile and library do not already exist.

tasks:
  – block:
    – name: Does the user profile or library already exist?
      ibmi_object_find:
        object_name: “{{ item.obj }}”
        lib_name: “{{ item.lib }}”
        object_type_list: “{{ item.type }}”
      register: object_find
      with_items:
        – { obj: “{{ usrprf }}”, lib: ‘QSYS’, type: ‘*USRPRF’}
        – { obj: “{{ curlib }}”, lib: ‘QSYS’, type: ‘*LIB’}

– name: If user profile or library already exists then fail assertion and do not continue
      assert:
        that:
          – “{{ item.object_list | length }} == 0”
      with_items: “{{ object_find.results }}”

tags:
      – pre_checks

Be aware that ibmi_object_find is case sensitive. Searching for user profile qsecofr will fail but searching for user profile QSECOFR will succeed.

I’ve also used the with_items directive to make the ibmi_object_find task loop around to check for the user profile and then the library.

The assert module loops around the results from the ibmi_object_find module. If either of the object exists they will return the details in the object_list variable. If the object_list is greater than 0 then the object exists and the playbook aborts.

Create the objects and set authority

This is the main section of the playbook. The user profile is created using variables set at the beginning of the workbook. The ibmi_user_and_groups module does not have parameters to match all of the CRTUSRPRF command so the parameters keyword is used to supplement this e.g. using HOMEDIR as shown below.

A new library is created and file QIWS/QCUSTCDT copied to the library. A journal and journal receiver are created and then journaling is started on file ROBINSG/QCUSTCDT. These commands are executed using the ibmi_cl_command module.

I also create the user’s directory in the IFS using the file module. This module is a standard Ansible module, not an Ansible for i module. I also use the authorized_key module to copy the rsa public key into the user’s home directory. Again, this is a core Ansible module.

– block:
    – name: Create the user profile
      ibmi_user_and_group:
        operation: create
        user: “{{ usrprf }}”
        user_class: “{{ usrcls }}”
        status: ‘*ENABLED’
        owner: ‘*USRPRF’
        text: “{{ text }}”
        parameters: “HOMEDIR(‘{{ homedir }}’) CURLIB({{ curlib }})”  # Additional aoostophes required to correct IFS format in HOMEDIR parameter
   
    – name: Create the user’s home directory
      file:
        path: “{{ homedir }}”
        state: directory
        owner: “{{ usrprf }}”
        mode: ‘0744’

– name: Create a library for the user
      ibmi_cl_command:
        cmd: “CRTLIB LIB({{ curlib }})”

– name: Copy the database file in to the library created
      ibmi_cl_command:
        cmd: “CPYF FROMFILE({{ srclib }}/{{ srcfile }}) TOFILE({{ curlib }}/{{ srcfile }}) CRTFILE(*YES)”

– name: Create journal receiver
      ibmi_cl_command:
        cmd: CRTJRNRCV JRNRCV({{ curlib }}/{{ jrnrcv }}) TEXT(‘JOURNAL RECEIVER FOR ANSIBLE’)

– name: Create journal
      ibmi_cl_command:
        cmd: CRTJRN JRN({{ curlib }}/{{ jrn }}) JRNRCV({{ curlib }}/{{ jrnrcv }}) TEXT(‘JOURNAL FOR ANSIBLE’)

– name: Start journal for file
      ibmi_cl_command:
        cmd: STRJRNPF FILE({{ curlib }}/{{ srcfile }}) JRN({{ curlib }}/{{ jrn }})

– name: Change the owner of the library to the user profile name we created
      ibmi_cl_command:
        cmd: “CHGOBJOWN OBJ({{ curlib }}) OBJTYPE(*LIB) NEWOWN({{ usrprf }}) CUROWNAUT(*REVOKE)”

– name: Change public authority to *EXCLUDE on the library
      ibmi_object_authority:
        operation: revoke
        object_name: “{{ curlib }}”
        object_library: “*LIBL”
        object_type: “*LIB”
        user:
          – ‘*PUBLIC’
        authority:
          – ‘*ALL’

– name: Change the owner of the objects to the user profile name we created
      ibmi_cl_command:
        cmd: “CHGOBJOWN OBJ({{ item.lib }}/{{ item.obj }}) OBJTYPE({{ item.type }}) NEWOWN({{ usrprf }}) CUROWNAUT(*REVOKE)”
      with_items:
        – { obj: “{{ srcfile }}”, lib: “{{ curlib }}”, type: ‘*FILE’ }
        – { obj: “{{ jrn }}”, lib: “{{ curlib }}”, type: ‘*JRN’ }
        – { obj: “{{ jrnrcv }}”, lib: “{{ curlib }}”, type: ‘*JRNRCV’ }

– name: Change public authority to *EXCLUDE on the object in the library
      ibmi_object_authority:
        operation: revoke
        object_name: “*ALL”
        object_library: “{{ curlib }}”
        object_type: “*ALL”
        user:
          – ‘*PUBLIC’
        authority:
          – ‘*ALL’

– name: Set authorized_key for the user we created taken from local rsa file
      authorized_key:
        user: “{{ usrprf }}”
        state: present
        key: “{{ lookup(‘file’, ‘/home/{{ usrprf | lower }}/.ssh/{{ sshfile }}’) }}”

tags:
      – setup_objects

You’ll notice that I have used with_items as part of the ibmi_cl_command when executing the CHGOBJOWN command. Rather than coding this three times I’ve listed the three objects in an array as part of with_items. This will force the ibmi_cl_command module to run the CHGOBJOWN command for each of the three objects.

The usrprf variable has been set up as ROBINSG. My folder in Linux where the rsa key is stored is /home/robinsg so in the aurthorized_key module I’ve forced the usrprf variable to be converted to lower case, {{ usrprf | lower }}.

Changing the running user and executing SQL

In this final section I start off by using the set_fact module. This is used to amend Ansible variables. Here, I change the ansible_ssh_user from QSECOFR to ROBINSG. This means that the following ansible tasks will connect to the IBM i SSH server as ROBINSG, the newly created user profile.

Module ibmi_sql_query is executed to run a SELECT statement against ROBINSG/QCUSTCDT and then the debug module is used to display the rows returned from ibm_sql_query.

I then use ibmi_sql_execute to DELETE selected rows from the file.

A couple of observations for you:

  • ibmi_sql_query is used to run query statements, SELECT, and does not require the file to be journaled
  • ibmi_sql_execute is used to run non-query statements like DELETE or INSERT. These require the file to be journaled.

As long as the DELETE statement is successful another query is executed and the rows displayed.

– block:
    – name: Set the user name
      set_fact:
        ansible_ssh_user: “{{ usrprf }}”

– name: Run an SQL SELECT statement
      ibmi_sql_query:
        sql: “SELECT * FROM {{ curlib }}.{{ srcfile }}
        WHERE CDTLMT > 999.99″
      register: sql_resultset

– name: Display the SQL query result set
      debug:
        msg: “{{ sql_resultset.row }}”

– name: Display the SQL query rows found
      debug:
        msg: “{{ sql_resultset.row_count }} rows found.”
 
    – name: Run an SQL DELETE statement
      ibmi_sql_execute:
        sql: “DELETE FROM {{ curlib }}.{{ srcfile }}
        WHERE CDTLMT < 1000.00″
      register: sql_delete

– block:
      – name: Display the entire file
        ibmi_sql_query:
          sql: “SELECT * FROM {{ curlib }}.{{ srcfile }}”
        register: sql_resultset
       
      – name: Display results
        debug:
          msg: “{{ sql_resultset.row }}”

– name: Display rows found
        debug:
          msg: “{{ sql_resultset.row_count }} found.”

when: sql_delete.rc == 0

tags:
      – sql

Use of tags

In previous articles I haven’t used Ansible tags. You can see three tags that I have specified in this playbook:

  • pre_checks
  • setup_objects
  • sql

These are assigned to block statements so that I can control which blocks I want to execute or skip.

If I want to skip the setup_objects block I can run:

ansible-playbook setup_user_and_run_SQL.yml –skip-tags=setup_objects

If I just want to run the pre checks:

ansible-playbook setup_user_and_run_SQL.yml –tags=pre_checks

Testing the playbook

As I was developing the playbook I had to delete the library and user profile each time I ran the playbook. I could have used a 5250 session and deleted the *USRPRF and *LIB but I actually found it easier to use ssh from my Linux session to do this.

$ ssh qsecofr@mgtsrv01 -i ~/.ssh//ansible_id_rsa  “system dltlib robinsg”

$ ssh qsecofr@mgtsrv01 -i ~/.ssh//ansible_id_rsa  “system ‘dltusrprf usrprf(robinsg) ownobjopt(*DLT)’

I can now run the playbook and not get an objects exist error..

Running the playbook

Running the playbook produces the following:

$ ansible-playbook setup_user_and_run_SQL.yml

PLAY [Set up a user, library and then run SQL statements] ********************************************************************

TASK [Does the user profile or library already exist?] ********************************************************************
ok: [mgtsvr01] => (item={u’type’: u’*USRPRF’, u’obj’: u’ROBINSG’, u’lib’: u’QSYS’})
ok: [mgtsvr01] => (item={u’type’: u’*LIB’, u’obj’: u’ROBINSG’, u’lib’: u’QSYS’})

TASK [If user profile or library already exists then fail assertion and do not continue] ********************************************************************
ok: [mgtsvr01] => (item={u’ansible_loop_var’: u’item’, u’end’: u’2020-09-15 11:35:43.635118′, u’job_log’: [], u’item’: {u’obj’: u’ROBINSG’, u’type’: u’*USRPRF’, u’lib’: u’QSYS’}, u’changed’: False, u’rc’: 0, u’start’: u’2020-09-15 11:35:43.419300′, u’sql’: u”select * from ( SELECT OBJNAME, OBJTYPE, OBJOWNER, OBJDEFINER, OBJCREATED, TEXT, (SELECT SYSTEM_SCHEMA_NAME FROM QSYS2.SYSSCHEMAS WHERE SCHEMA_NAME = OBJLONGSCHEMA) AS OBJLIB, IASP_NUMBER, LAST_USED_TIMESTAMP,  LAST_RESET_TIMESTAMP, BIGINT(OBJSIZE) AS OBJSIZE, OBJATTRIBUTE, OBJLONGSCHEMA  FROM TABLE (QSYS2.OBJECT_STATISTICS(‘QSYS’,’*USRPRF’,’ROBINSG’)) X ) A WHERE 1 = 1 “, u’delta’: u’0:00:00.215818′, u’invocation’: {u’module_args’: {u’age’: None, u’age_stamp’: u’ctime’, u’object_name’: u’ROBINSG’, u’object_type_list’: u’*USRPRF’, u’iasp_name’: u’*SYSBAS’, u’joblog’: False, u’use_regex’: False, u’lib_name’: u’QSYS’, u’size’: None}}, u’object_list’: [], u’failed’: False}) => {
    “ansible_loop_var”: “item”,
    “changed”: false,
    “item”: {
        “ansible_loop_var”: “item”,
        “changed”: false,
        “delta”: “0:00:00.215818”,
        “end”: “2020-09-15 11:35:43.635118”,
        “failed”: false,
        “invocation”: {
            “module_args”: {
                “age”: null,
                “age_stamp”: “ctime”,
                “iasp_name”: “*SYSBAS”,
                “joblog”: false,
                “lib_name”: “QSYS”,
                “object_name”: “ROBINSG”,
                “object_type_list”: “*USRPRF”,
                “size”: null,
                “use_regex”: false
            }
        },
        “item”: {
            “lib”: “QSYS”,
            “obj”: “ROBINSG”,
            “type”: “*USRPRF”
        },
        “job_log”: [],
        “object_list”: [],
        “rc”: 0,
        “sql”: “select * from ( SELECT OBJNAME, OBJTYPE, OBJOWNER, OBJDEFINER, OBJCREATED, TEXT, (SELECT SYSTEM_SCHEMA_NAME FROM QSYS2.SYSSCHEMAS WHERE SCHEMA_NAME = OBJLONGSCHEMA) AS OBJLIB, IASP_NUMBER, LAST_USED_TIMESTAMP,  LAST_RESET_TIMESTAMP, BIGINT(OBJSIZE) AS OBJSIZE, OBJATTRIBUTE, OBJLONGSCHEMA  FROM TABLE (QSYS2.OBJECT_STATISTICS(‘QSYS’,’*USRPRF’,’ROBINSG’)) X ) A WHERE 1 = 1 “,
        “start”: “2020-09-15 11:35:43.419300”
    },
    “msg”: “All assertions passed”
}
ok: [mgtsvr01] => (item={u’ansible_loop_var’: u’item’, u’end’: u’2020-09-15 11:35:44.680324′, u’job_log’: [], u’item’: {u’obj’: u’ROBINSG’, u’type’: u’*LIB’, u’lib’: u’QSYS’}, u’changed’: False, u’rc’: 0, u’start’: u’2020-09-15 11:35:44.460176′, u’sql’: u”select * from ( SELECT OBJNAME, OBJTYPE, OBJOWNER, OBJDEFINER, OBJCREATED, TEXT, (SELECT SYSTEM_SCHEMA_NAME FROM QSYS2.SYSSCHEMAS WHERE SCHEMA_NAME = OBJLONGSCHEMA) AS OBJLIB, IASP_NUMBER, LAST_USED_TIMESTAMP,  LAST_RESET_TIMESTAMP, BIGINT(OBJSIZE) AS OBJSIZE, OBJATTRIBUTE, OBJLONGSCHEMA  FROM TABLE (QSYS2.OBJECT_STATISTICS(‘QSYS’,’*LIB’,’ROBINSG’)) X ) A WHERE 1 = 1 “, u’delta’: u’0:00:00.220148′, u’invocation’: {u’module_args’: {u’age’: None, u’age_stamp’: u’ctime’, u’object_name’: u’ROBINSG’, u’object_type_list’: u’*LIB’, u’iasp_name’: u’*SYSBAS’, u’joblog’: False, u’use_regex’: False, u’lib_name’: u’QSYS’, u’size’: None}}, u’object_list’: [], u’failed’: False}) => {
    “ansible_loop_var”: “item”,
    “changed”: false,
    “item”: {
        “ansible_loop_var”: “item”,
        “changed”: false,
        “delta”: “0:00:00.220148”,
        “end”: “2020-09-15 11:35:44.680324”,
        “failed”: false,
        “invocation”: {
            “module_args”: {
                “age”: null,
                “age_stamp”: “ctime”,
                “iasp_name”: “*SYSBAS”,
                “joblog”: false,
                “lib_name”: “QSYS”,
                “object_name”: “ROBINSG”,
                “object_type_list”: “*LIB”,
                “size”: null,
                “use_regex”: false
            }
        },
        “item”: {
            “lib”: “QSYS”,
            “obj”: “ROBINSG”,
            “type”: “*LIB”
        },
        “job_log”: [],
        “object_list”: [],
        “rc”: 0,
        “sql”: “select * from ( SELECT OBJNAME, OBJTYPE, OBJOWNER, OBJDEFINER, OBJCREATED, TEXT, (SELECT SYSTEM_SCHEMA_NAME FROM QSYS2.SYSSCHEMAS WHERE SCHEMA_NAME = OBJLONGSCHEMA) AS OBJLIB, IASP_NUMBER, LAST_USED_TIMESTAMP,  LAST_RESET_TIMESTAMP, BIGINT(OBJSIZE) AS OBJSIZE, OBJATTRIBUTE, OBJLONGSCHEMA  FROM TABLE (QSYS2.OBJECT_STATISTICS(‘QSYS’,’*LIB’,’ROBINSG’)) X ) A WHERE 1 = 1 “,
        “start”: “2020-09-15 11:35:44.460176”
    },
    “msg”: “All assertions passed”
}

TASK [Create the user profile] ********************************************************************
changed: [mgtsvr01]

TASK [Create the user’s home directory] ********************************************************************
changed: [mgtsvr01]

TASK [Create a library for the user] ********************************************************************
ok: [mgtsvr01]

TASK [Copy the database file in to the library created] ********************************************************************
ok: [mgtsvr01]

TASK [Create journal receiver] ********************************************************************
ok: [mgtsvr01]

TASK [Create journal] ********************************************************************
ok: [mgtsvr01]

TASK [Start journal for file] ********************************************************************
ok: [mgtsvr01]

TASK [Change the owner of the library to the user profile name we created] ********************************************************************
ok: [mgtsvr01]

TASK [Change public authority to *EXCLUDE on the library] ********************************************************************
changed: [mgtsvr01]

TASK [Change the owner of the objects to the user profile name we created] ********************************************************************
ok: [mgtsvr01] => (item={u’type’: u’*FILE’, u’obj’: u’QCUSTCDT’, u’lib’: u’ROBINSG’})
ok: [mgtsvr01] => (item={u’type’: u’*JRN’, u’obj’: u’ANSIBJRN’, u’lib’: u’ROBINSG’})
ok: [mgtsvr01] => (item={u’type’: u’*JRNRCV’, u’obj’: u’ANSIBRCV01′, u’lib’: u’ROBINSG’})

TASK [Change public authority to *EXCLUDE on the object in the library] ********************************************************************
changed: [mgtsvr01]

TASK [Set authorized key for the user we created taken from local rsa file] ********************************************************************
changed: [mgtsvr01]

TASK [Set the user name] ********************************************************************
ok: [mgtsvr01]

TASK [Run an SQL SELECT statement] ********************************************************************
ok: [mgtsvr01]

TASK [Display the SQL query result set] ********************************************************************
ok: [mgtsvr01] => {
    “msg”: [
        {
            “BALDUE”: 37.0,
            “CDTDUE”: “”,
            “CDTLMT”: 5000.0,
            “CHGCOD”: 3.0,
            “CITY”: “Dallas”,
            “CUSNUM”: 938472.0,
            “INIT”: “G K”,
            “LSTNAM”: “Henning “,
            “STATE”: “TX”,
            “STREET”: “4859 Elm Ave “,
            “ZIPCOD”: 75217.0
        },
        {
            “BALDUE”: 3987.5,
            “CDTDUE”: 33.5,
            “CDTLMT”: 9999.0,
            “CHGCOD”: 2.0,
            “CITY”: “Helen “,
            “CUSNUM”: 938485.0,
            “INIT”: “J A”,
            “LSTNAM”: “Johnson “,
            “STATE”: “GA”,
            “STREET”: “3 Alpine Way “,
            “ZIPCOD”: 30545.0
        },
        {
            “BALDUE”: “”,
            “CDTDUE”: “”,
            “CDTLMT”: 1000.0,
            “CHGCOD”: 1.0,
            “CITY”: “Hector”,
            “CUSNUM”: 397267.0,
            “INIT”: “W E”,
            “LSTNAM”: “Tyron   “,
            “STATE”: “NY”,
            “STREET”: “13 Myrtle Dr “,
            “ZIPCOD”: 14841.0
        },
        {
            “BALDUE”: 10.0,
            “CDTDUE”: “”,
            “CDTLMT”: 5000.0,
            “CHGCOD”: 3.0,
            “CITY”: “Isle  “,
            “CUSNUM”: 846283.0,
            “INIT”: “J S”,
            “LSTNAM”: “Alison  “,
            “STATE”: “MN”,
            “STREET”: “787 Lake Dr  “,
            “ZIPCOD”: 56342.0
        },
        {
            “BALDUE”: “”,
            “CDTDUE”: “”,
            “CDTLMT”: 9999.0,
            “CHGCOD”: 2.0,
            “CITY”: “Casper”,
            “CUSNUM”: 693829.0,
            “INIT”: “A N”,
            “LSTNAM”: “Thomas  “,
            “STATE”: “WY”,
            “STREET”: “3 Dove Circle”,
            “ZIPCOD”: 82609.0
        },
        {
            “BALDUE”: 500.0,
            “CDTDUE”: “”,
            “CDTLMT”: 9999.0,
            “CHGCOD”: 3.0,
            “CITY”: “Isle  “,
            “CUSNUM”: 583990.0,
            “INIT”: “M T”,
            “LSTNAM”: “Abraham “,
            “STATE”: “MN”,
            “STREET”: “392 Mill St  “,
            “ZIPCOD”: 56342.0
        }
    ]
}

TASK [Display the SQL query rows found] ********************************************************************
ok: [mgtsvr01] => {
    “msg”: “6 rows found.”
}

TASK [Run an SQL DELETE statement] ********************************************************************
ok: [mgtsvr01]

TASK [Display the entire file] ********************************************************************
ok: [mgtsvr01]

TASK [Display results] ********************************************************************
ok: [mgtsvr01] => {
    “msg”: [
        {
            “BALDUE”: 37.0,
            “CDTDUE”: “”,
            “CDTLMT”: 5000.0,
            “CHGCOD”: 3.0,
            “CITY”: “Dallas”,
            “CUSNUM”: 938472.0,
            “INIT”: “G K”,
            “LSTNAM”: “Henning “,
            “STATE”: “TX”,
            “STREET”: “4859 Elm Ave “,
            “ZIPCOD”: 75217.0
        },
        {
            “BALDUE”: 3987.5,
            “CDTDUE”: 33.5,
            “CDTLMT”: 9999.0,
            “CHGCOD”: 2.0,
            “CITY”: “Helen “,
            “CUSNUM”: 938485.0,
            “INIT”: “J A”,
            “LSTNAM”: “Johnson “,
            “STATE”: “GA”,
            “STREET”: “3 Alpine Way “,
            “ZIPCOD”: 30545.0
        },
        {
            “BALDUE”: “”,
            “CDTDUE”: “”,
            “CDTLMT”: 1000.0,
            “CHGCOD”: 1.0,
            “CITY”: “Hector”,
            “CUSNUM”: 397267.0,
            “INIT”: “W E”,
            “LSTNAM”: “Tyron   “,
            “STATE”: “NY”,
            “STREET”: “13 Myrtle Dr “,
            “ZIPCOD”: 14841.0
        },
        {
            “BALDUE”: 10.0,
            “CDTDUE”: “”,
            “CDTLMT”: 5000.0,
            “CHGCOD”: 3.0,
            “CITY”: “Isle  “,
            “CUSNUM”: 846283.0,
            “INIT”: “J S”,
            “LSTNAM”: “Alison  “,
            “STATE”: “MN”,
            “STREET”: “787 Lake Dr  “,
            “ZIPCOD”: 56342.0
        },
        {
            “BALDUE”: “”,
            “CDTDUE”: “”,
            “CDTLMT”: 9999.0,
            “CHGCOD”: 2.0,
            “CITY”: “Casper”,
            “CUSNUM”: 693829.0,
            “INIT”: “A N”,
            “LSTNAM”: “Thomas  “,
            “STATE”: “WY”,
            “STREET”: “3 Dove Circle”,
            “ZIPCOD”: 82609.0
        },
        {
            “BALDUE”: 500.0,
            “CDTDUE”: “”,
            “CDTLMT”: 9999.0,
            “CHGCOD”: 3.0,
            “CITY”: “Isle  “,
            “CUSNUM”: 583990.0,
            “INIT”: “M T”,
            “LSTNAM”: “Abraham “,
            “STATE”: “MN”,
            “STREET”: “392 Mill St  “,
            “ZIPCOD”: 56342.0
        }
    ]
}

TASK [Display rows found] ********************************************************************
ok: [mgtsvr01] => {
    “msg”: “6 found.”
}

PLAY RECAP ********************************************************************
mgtsvr01                   : ok=22   changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

References

Full playbook yaml file: https://gist.github.com/robinsg/ffddb9626c9d3735517cb62cb5e9514c

Ansible for i documentation: https://ibm.github.io/ansible-for-i/modules.html

Ansible Automation on Power: https://www.ibm.com/support/pages/power-vug-technical-webinar-series#96

By Glenn Robinson on September 16, 2020.

Canonical link

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *