Ansible

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

http://books.stuartherbert.com/putting-ansible-to-work/working-with-config-files.html

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

https://www.youtube.com/watch?v=jBiueVhDg1Q

Install pip3

root@client01:~# apt install python3-pip
root@client01:~# which pip3
/usr/bin/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.
    lineinfile:
      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/re.py\", line 282, in _expand\r\n    return sre_parse.expand_template(template, match)\r\n  File \"/usr/lib64/python2.7/sre_parse.py\", 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
    lineinfile:
      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
    copy:
      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
    tags:
      - scored
      - section6.2
      - section6.2.7

Tips

Copy file to remote system:-

  - name: Copy file to system
    copy:
      src: ../files/checkRootPathEnv.sh
      dest: /root/checkRootPathEnv.sh
      owner: root
      group: root
      mode: 0700
    tags:
      - 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: 4.2.1.4 Create and Set Permissions on rsyslog Log Files (Scored)
    shell: touch /var/log/{{ item }} creates=/var/log/{{ item }}
    with_items:
        - messages
        - kern.log
        - daemon.log
        - unused.log
        - syslog
    tags:
      - scored

Conditional code

- name: Create home directory for cwagent (RedHat Linux)
  file:
    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
  user:
    name: cwdeviceuser
    shell: /sbin/nologin

Examples

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

$ cat hosts-ansible.ans 
[webServers]
amazonlinux02
amazonlinux03

[databaseServers]
amazonlinux03 

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 >>
postfix-2.10.1-6.amzn2.0.1.x86_64

amazonlinux03 | SUCCESS | rc=0 >>
postfix-2.10.1-6.amzn2.0.1.x86_64

andrew@puppet:~/ansible$ 

Install NTP (Chrony?)

 - name: 3.6 Configure Network Time Protocol (ipv4) (Scored)
    service: >
      name=ntpd
      state=started
      enabled=yes
    tags:
      - scored
      - section3.6

  - name: 3.6 Configure Network Time Protocol (ipv4) (Scored)
    lineinfile: >
      dest=/etc/ntp.conf
      state=present
      regexp="^restrict default"
      line="restrict default kod nomodify notrap nopeer noquery"
      insertafter=EOF
    tags:
      - scored
      - section3.6

  - name: 3.6 Configure Network Time Protocol (ipv6) (Scored)
    lineinfile: >
      dest=/etc/ntp.conf
      state=present
      regexp="^restrict -6 default"
      line="restrict -6 default kod nomodify notrap nopeer noquery"
      insertafter=EOF
    tags:
      - scored
      - section3.6

This page has been accessed for:-
Today: 1
Yesterday: 1
Until now: 523

 
cloud/ansible.txt · Last modified: 02/10/2023 10:10 by andrew