Ansible is an ssh based configuration management system. These notes are primarily for my benefit so don't believe anything here!

Ansible can also be run from within packer from HashiCorp as a Provisioner.

Install pip3

root@client01:~# apt install python3-pip
root@client01:~# which pip3

Installing Ansible

Ansible is a python package and can be installed with pip:-

/usr/bin/pip3 install ansible

Testing if the python-yum module is present:-

python -c \"import yum; print('yum python OK')\"

Running playbook locally on just localhost

# ansible-playbook playbook.yml -c local

-c is connection.

Running a specific section of a playbook

ansible-playbook -vv -i hosts-ansible.ans -u ec2-user --sudo --private-key ansible_id_rsa main.yml --tags "section6.1"

Breaks down to:-

-vv verbosity required
-i hosts-ansible.ans hosts list to apply to
-u ec2-user Username to log in to instance with
–sudo Use sudo to become root
–private-key ans.rsa Private key half for key based auth
main.yml Entry point file for the playbook
–tags “sectionXX” Run only specific sections identified by tag XX

Regex bug

Running this gives a horrible error:-

  - name: 5.3.1 set minimum password length.
      state: present
      dest: /etc/security/pwquality.conf
      backrefs: yes
      regexp: '^(#).(minlen.=.)(.*$)'
      line: '\28'
TASK [cisHardening : 5.3.1 set minimum password length.] ***********************
fatal: [amazonlinux02]: FAILED! => {"changed": false, "failed": true, "module_stderr": "", "module_stdout": "Traceback (most recent call last):\r\n  File \"/home/ec2-user/.ansible/tmp/ansible-tmp-1536138790.76-173731145979288/lineinfile\", line 2515, in <module>\r\n    main()\r\n  File \"/home/ec2-user/.ansible/tmp/ansible-tmp-1536138790.76-173731145979288/lineinfile\", line 371, in main\r\n    ins_aft, ins_bef, create, backup, backrefs)\r\n  File \"/home/ec2-user/.ansible/tmp/ansible-tmp-1536138790.76-173731145979288/lineinfile\", line 236, in present\r\n    new_line = m.expand(line)\r\n  File \"/usr/lib64/python2.7/\", line 282, in _expand\r\n    return sre_parse.expand_template(template, match)\r\n  File \"/usr/lib64/python2.7/\", line 861, in expand_template\r\n    raise error, \"invalid group reference\"\r\nsre_constants.error: invalid group reference\r\n", "msg": "MODULE FAILURE", "parsed": false}

From several vague posts, it seems related to the regex handeling, but other very similar blocks of code run just fine:-

  - name: 5.3.1 require 1 digit in password
      dest: /etc/security/pwquality.conf
      backrefs: yes
      regexp: '^(#).(dcredit.=.)(.*$)'
      line: '\2-1'

Seems to be related to this line, changing the regex clears the fault:-

line: '\28'

This works:-

regexp: '^(#).(minlen.=)(.*$)'
line: '\2 8'

Maybe there is a way to quote the test (8) after the capturing group (\2).

Debug command

  - name: Add motd line
      src: ../files/js-ccoe.j2
      dest: /etc/update-motd.d/31-JS_banner
      mode: 0755
    register: jsccoe

  - debug: var=jsccoe

  - name: Run motd updater
    command: creates="/etc/update-motd.d/31-JS_banner"  /usr/sbin/update-motd
    #shell: /usr/sbin/update-motd
    when: jsccoe.changed
TASK [cisHardening : debug] ****************************************************
ok: [amazonlinux02] => {
    "jsccoe": {
        "changed": true, 
        "checksum": "f66ca742894820e4601b36d75d4f222078db1b7f", 
        "dest": "/etc/update-motd.d/31-JS_banner", 
        "gid": 0, 
        "group": "root", 
        "md5sum": "319100e8f871ea498d79cf4f0f635b82", 
        "mode": "0755", 
        "owner": "root", 
        "secontext": "system_u:object_r:etc_t:s0", 
        "size": 298, 
        "src": "/home/ec2-user/.ansible/tmp/ansible-tmp-1536673397.14-245770485880175/source", 
        "state": "file", 
        "uid": 0

Manipulating the outcome of a test

Debug can be used to show the outcome of a check, depending on the result this may affect idempotency, and can be overriden, see below.

  - debug: var=VARIABLEfromREGISTER

debug: can also show all the suffixes to a variable which can be tested such as changed and the unix rc return code from $?

# Get users with bash shell, but not root and check /home/$USER exists, throws error if no home dir. $? gives 0 if exists, 2 if no home dir
  - name: 6.2.7 Ensure all users' home directories exist (Scored)
    shell: for USER in $(cat /etc/passwd | grep -v root | grep -E "bash" | sed -r 's/(^[^:]*):(.*)/\1/'); do ls -d /home/$USER; done
    always_run: yes
    ignore_errors: yes
    register: HomeDirOK
    failed_when: HomeDirOK.rc != 0
    changed_when: HomeDirOK.rc != 0
      - scored
      - section6.2
      - section6.2.7


Copy file to remote system:-

  - name: Copy file to system
      src: ../files/
      dest: /root/
      owner: root
      group: root
      mode: 0700
      - scored

Command module:- command: creates=“/path/to/file.txt” cp xxx yyy etc… Tests specify a filename that is used to control whether or not the command needs to be run.

  - name: Create and Set Permissions on rsyslog Log Files (Scored)
    shell: touch /var/log/{{ item }} creates=/var/log/{{ item }}
        - messages
        - kern.log
        - daemon.log
        - unused.log
        - syslog
      - scored

Conditional code

- name: Create home directory for cwagent (RedHat Linux)
    path:  /home/cwagent
    state: directory
    owner: cwagent
    group: cwagent
    mode:  0750
  when: ansible_distribution_file_variety == "RedHat"

Manipulate login shell

- name: change user default shell to no-login
    name: cwdeviceuser
    shell: /sbin/nologin


Set up a hosts file for ansible with sections for each group of hosts

$ cat hosts-ansible.ans 


Run ansible directly (without playbook) to run remote command to install package:-

$ ansible -i hosts-ansible.ans -u ec2-user --sudo --private-key ansible_id_rsa webServers -a "rpm -q postfix"
amazonlinux02 | SUCCESS | rc=0 >>

amazonlinux03 | SUCCESS | rc=0 >>


rb/ansible.txt · Last modified: 05/03/2020 17:06 by andrew