Table of Contents
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.
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: 0
Until now: 664