Ansible - Notepad

Ansible

Noes from CBT Nuggets Ansible 2.4 Essentials

Chapters 1 to 4:
You only need to install ansible on the ansible server, clients do not run an agent, the ansible server uses SSH to communicate wtih clients.
yum install epel-release -y
yum install ansible -y

Create a user named ansible on the clients and add it to the sudoers file:
/usr/sbin/usermod ansible --password '$6$m6GqgmWQW8.14R570e/YgrW1YQp2x0'
/usr/bin/echo "ansible ALL=(ALL) NOPASSWD:ALL" | tee /etc/sudoers.d/ansible

Then generate and copy the ansible user's keypair from the server onto the agent:
ssh-keygen
ssh-copy-id ansible@agent1

Ansible server details:
Default inventory file location /etc/ansible/hosts
Ansible server configuration file: /etc/ansible/ansible.cfg

Example commands against an agent:
ansible agent1 -a whoami
ansible all -a whoami

Become root:
ansible agent1 -b -a 'shutdown -r'

Default module is command module (ie if you don't specify -m module-name)
ansible agent1 -m command -a 'systemctl status httpd' -b

Shell module can use pipes and redirects:
ansible agent1 -m shell -a 'rpm -qa | grep httpd' -b

There is a raw module that doesn't use python.
Order of use should be ideally command, then shell, then raw.

5. Ad-Hoc System Interaction
Install/Remove packages using the yum module
ansible agent1 -m yum -a 'name=telnet state=present' -b
ansible agent1 -m yum -a 'name=telnet state=absent' -b
ansible agent1 -m yum -a 'name=telnet state=latest' -b

Enable and run sevices using the service module
ansible agent1 -m service -a 'name=httpd enabled=true state=started' -b
ansible agent1 -m service -a 'name=httpd enabled=false state=stopped' -b

6. Ad-Hoc Filesystem Management
File module:
ansible agent1 -b -m file -a 'path=/tmp/hello.txt state=file owner=root'

Copy module from local computer to remote agent:
ansible agent1 -b -m copy -a 'src=/tmp/hello2.txt dest=/tmp/hello3.txt'

7. Ansible Playbooks: Format and Function
Show module arguments:
ansible-doc module_name

Sample playbook:
ansible-playbook playbook.yaml

- hosts: agent1
    # Become root
    become: true
    tasks:
    - name: do a uname
        shell: uname -a > /tmp/results.txt

    - name: whoami
        shell: whoami >> /tmp/results.txt

8. Ansible Playbooks: Handlers
Handlers are called by tasks.

Handler example:
- hosts: agent1
    become: yes
    tasks:
    - name: install vsftpd on centos
        yum: name=vsftpd state=latest
        ignore_errors: yes
        notify: start vsftpd

    handlers:
    - name: start vsftpd
        service: name=vsftpd state=started enabled=yes

9. Ansible Playbooks: Variables and Facts
Using variables in a playbook.
---

- hosts: agent1
    vars:
    - var1: string1
    - var2: string2
    tasks:
    - name: echo stuff
        shell: echo "var1 is {{ var1 }} var2 is {{ var2 }} OS is called {{ ansible_os_family }}" > /tmp/file.txt

Show a host's facts:
ansible hostname -m setup

10. Ansible Playbooks: Debug Module
Enable Debug:
- hosts: agent1
    vars:
    - var_thing: "never gonna"
    tasks:
    - name: show results
        debug: msg="the variable var_thing is set to {{ var_thing }}"

Use debug to show results:
- hosts: agent1
    vars:
    - var_thing: "never gonna"
    tasks:
    - name: echo stuff
        command: echo -e "{{ var_thing }}, give up,\\n {{ var_thing }}"
        register: results
    - name: show results
        debug: msg={{ results }}

You can also show a portion of the json output.
Use debug to show results:
- hosts: agent1      
    vars:
    - var_thing: "never gonna"
    tasks:
    - name: echo stuff
        command: echo -e "{{ var_thing }}, give up,\\n {{ var_thing }}"
        register: results
    - name: show results
        debug: msg={{ results.stdout_lines }}

11. Ansible Playbooks: Conditionals
---

- hosts: agent1
    become: yes
    tasks:
    - name: install apache ubuntu
        apt: name=apache2 state=latest
        when: ansible_os_family == "Debian"
    - name: install httpd centos
        yum: name=httpd state=latest
        when: ansible_os_family == "RedHat"
        register: results
    - name: show results
        debug: msg={{ results }}

12. Ansible Playbooks: Loops
Install multiple packages:
---

- hosts: agent1
    become: yes

    tasks:
    - name: install stuff
        yum: name={{ item }} state=latest
        with_items:
        - vim
        - vsftpd
        - bind-utils
        - httpd
        register: results
    - name: show results
        debug: msg=={{ results }}

13. Ansible Templates
---

- hosts: agent1
    become: yes
    vars:
    file_version: 1.0
    tasks:
    - name: install index
        template:
        src: index.html
        dest: /var/www/html/index.html

Template file containing facts:
OS is {{ ansible_os_family }}
hostname is {{ ansible_hostname }}
version is {{ file_version }}

14. Ansible Vault
Encrypts the playbook file with a vault password.  Allows you to specify the ansible user password, no SSH keys required.
When you edit or run the playbook you are prompted for the vault password.

Create an encrypted playbook:
ansible-vault encrypted something.yaml 

---

- hosts: agent1
    become: yes
    vars:
    - ansible_sudo_pass: r38!dan84
    tasks:
    - name: install httpd
        yum: name=httpd state=latest

Edit the encrypted yaml file:
ansible-vault edit encrypted.yaml

Run the ansible playbook and enter the vault password manually:
ansible-playbook test.yaml --ask-vault-pass

Run the ansible playbook and read the vault password from a file:
ansible-playbook test.yaml --vault-password-file pwd.txt 

15. Ansible Include Statement
You can use include to import a task from a yaml file.
Use import-playbook to include another playbook (the files defines hosts and can be run individually).

base playbook:
---

- import_playbook: update_yum.yaml

- hosts: agent1
    become: yes
    tasks:
    - include: install_httpd.yaml

playbook that updates yum:
---
- hosts: agent1
    become: yes

    tasks:
    - name: update yum
        yum: name=* state=latest
        when: ansible_os_family == "RedHat"

task file:
---
- name: install httpd
    yum: name=httpd state=latest
    when: ansible_os_family == "RedHat"

- name: start httpd
    service: name=httpd state=started enabled=yes
    when: ansible_os_family == "RedHat"

16. Ansible Roles: Form & Function
A basic role that installs apache and starts the service.

Directory structure:
roles/apache/{tasks,handlers}

roles/sites.yaml
---

- hosts: agent1
    become: yes
    roles:
    - apache

roles/apache/tasks/main.yml
---

- name: install httpd
    yum: name=httpd state=latest update_cache=yes
    when: ansible_os_family == "RedHat"
    notify: start httpd service

roles/apache/handlers/main.yml
---

- name: start httpd service
    service: name=httpd state=started enabled=yes
    
Run the role:
ansible-playbook roles/site.yml 

17. Ansible Roles: Ansible Galaxy:
The default location for roles is /etc/ansible/roles
Galaxy roles available at https://galaxy.ansible.com/ (similar to puppet forge)
You can use ansible-galaxy to view public roles, they are in the structure of author.role_name (geerlingguy is reliable):
ansible-galaxy search apache

Downloading roles:
sudo ansible-galaxy install geerlingguy.apache geerlingguy.mysql

Install the downloaded roles:
roles/sites.yaml

---

- hosts: agent1
    become: yes
    roles:
    - geerlingguy.apache
    - geerlingguy.mysql