# Ansible | | An **Ansible** is a category of fictional devices or technology capable of near-instantaneous or faster-than-light communication. It can send and receive messages to and from a corresponding device over any distance or obstacle whatsoever with no delay, even between star systems. As a name for such a device, the word "ansible" first appeared in a 1966 novel by Ursula K. Le Guin. Since that time, the term has been broadly used in the works of numerous science fiction authors, across a variety of settings and continuities. A related term is ultrawave. | |-|-| | | wikipedia:: [Ansible](https://en.wikipedia.org/wiki/Ansible) | Declarative No control server needed. Can use your own machine. But there is [[AWX & Ansible Tower]] if needed. Uses [[Python]] and [[YAML]] No agents needed on the servers - just python and ssh - requirements.yml - Playbooks - ansible-playbook - --private-key=aKey - -vvv - -vv - verbosity level 2 - -vvvv - ansible-playbook -i an\_inventory example\_playbook.yaml -v - -v - verbosity level 1 - Plays - Handlers - run once, at the end of plays - triggered by tasks - Control Flow - when: - with\_items: - {{ item }} is the loop variable - Example - name: ensure postgresql database packages are installed apt: name: "{{ item }}" update\_cache: yes become: yes with\_items: - postgresql - libpq-dev - python-psycopg2 - postgresql-client - postgresql-client-common - Tasks - Data - mail: - to: - subject: - port: - subtype: - host: - from: - body: - Controls - include: - name: Include a play after another play include: otherplays.yaml - Example - name: ensure git is installed apt: name=git-core state=present update\_cache=yes become: true - debug: - msg: "aString" - when - Loops - with\_sequence: count=3 - Highest level/top-level concept that contains most other concepts in it - roles, tasks, variables - serial - Playbooks are YAML files that express configurations, deployment, and orchestration in Ansible,\[23\] and allow Ansible to perform operations on managed nodes. Each Playbook maps a group of hosts to a set of roles. Each role is represented by calls to Ansible tasks. - Example Playbook - --- - name: "Demo" hosts: groupA tasks: - name: demo task 1 debug: msg: "task 1" - name: demo task 2 debug: msg: "task 2" - Host doesn't have python - --- name: ping hosts: web gather\_facts: False tasks: - name: ping raw: echo $HOSTNAME - Configuration - ansible.cfg - https://docs.ansible.com/ansible/2.4/intro_configuration.html - Should start with Ansible's example config file and modify from there - https://docs.ansible.com/ansible/latest/reference\_appendices/config.html - Settings - retry\_files\_enables - ansible\_python\_interpreter=usr/bin/python3 - common to add to inventory files next to the host ip - vault\_password\_file - inventory - host\_key\_checking - Ini format, parsing errors otherwise? - ansible.cfg Search Order - /etc/ansible/ansible.cfg - ANSIBLE\_CONFIG (environment variable if set) - ansible.cfg (in the current directory) - \~/.ansible.cfg (in the home directory) - default /etc/ansible/ansible.cfg - Inbox - register: result - rescue: - shell: - delegat\_to: ? - when: result is succeeded - block: ? - when: result is not succeeded - [[AWX & Ansible Tower]] - Roles - I think roles are fairly analogous to Puppet's roles and profiles, but ansible roles encompass both - Roles use conventions for file names and directories - ansible-galaxy init aRole - Will generate a new role directory structure with useful boiler plate code - Playbooks can use multiple roles - include\_role: - name: ../path/to/role - tasks\_from: aYaml.yml - Directory Structure Example - The subdirectories of the roles directory are the names of your roles - Depending on how you are running something, ansible should have access to these roles if you follow the normal naming conventions - roles - common - tasks - main.yml - git.yml - webserver - tasks - ngninx.yml - main.yml - Ansible Galaxy v - Can be vertical, as in a web server or database backend, or horizontal, as in common security or monitoring settings - 3rd Party Roles - import\_role: - name: ../path/to/role - Very flexible concept - Helps make ansible code reusable - Forks - Maximum number of concurrent hosts - https://en.wikipedia.org/wiki/Ansible\_(software) - Modules - The builtin capabilities that ansible has for you to use - Typically written in python - E.g. - git - file - service - mail - slack - firewall - Sources - Core Sources to Develop With - https://github.com/ansible/ansible - https://github.com/ansible/ansible/tree/devel/lib/ansible - https://docs.ansible.com - Module Index - https://www.linkedin.com/learning/learning-ansible @done - https://www.linkedin.com/learning/ansible-essential-training - https://docs.ansible.com/ansible/latest/user\_guide/quickstart.html - https://training.talkpython.fm/courses/explore\_ansible/introduction-to-ansible-with-python - Ad Hoc Tasks - -a = argument - not using a playbook, one-off tasks - Examples - ansible -i anInventory aLabel? -m debug -a "msg='shutdown -r now'" - ansible web -m yum -a "name=openssl state=latest" - ansible web -a /bin/date - ansible web -m ping - -m = module - ansible - Users - user: - Check Mode (Dry Run) - -C - Extensions - Roles v - Collections - Dynamic Inventories - Plugins - Ansible Galaxy - community - SSH - ansible\_ssh\_pass: - ansible\_user: - ansible\_sudo\_pass: - https://www.ansible.com - Meta Ansible - Configuration Management - Agentless - Ansible orchestrates a node by installing and running modules on the node temporarily via SSH. For the duration of an orchestration task, a process running the module communicates with the controlling machine with a JSON-based protocol via its standard input and output.\[17\] When Ansible is not managing a node, it does not consume resources on the node because no daemons are executing of software installed. - Idempotent - Connects via ssh or winrm - Conventions, Style, & Best Practices - Directory Structure - group\_vars - all file or all folder - roles - nameOfRole - tasks - otherTasks.yml - main.yml - templates? - handlers? - deployment.yml? - Controlling Machine - Files & Folders - stat - Example - create let's encrypt cert if not already created: - name: check if certificate already created stat: path: "/etc/letsencrypt/live/{{ fqdn }}" register: certs become: yes - name: create certificate with Lets Encrypt command shell: "some kind of weird lets encrypt command" become: yes when: not certs.stat.exists - https://docs.ansible.com/ansible/latest/modules/stat\_module.html - Essentially, gathers facts about a file or directory - win\_stat - https://docs.ansible.com/ansible/latest/modules/win\_stat\_module.html\#win-stat-module - Permissions - become: - false - true - become\_user: aUsername - Inventory & hosts - Example Inventory File - \[web\] host1 host2 host3 \[db\] db1 - ini format - List of possible targets - /etc/ansible/hosts by default - Ansible can also use a custom Dynamic Inventory script, which can dynamically pull data from a different system - Groups of Groups - \[atlanta\] google.com yahoo.com \[jacksonville\] bing.com lycos.com \[southeast:children\] atlanta jacksonville - Ranges - Can use ssh\_config as a dynamic inventory source - Inventory Variables - Group of Groups' Variables - \[atlanta\] google.com yahoo.com \[jacksonville\] bing.com lycos.com \[southeast:children\] atlanta jacksonville \[southeast:variables\] aKey=aValue - Host Variables - \[hosts\] google.com aKey=aValue - Group Variables - \[atlanta\] google.com yahoo.com \[atlanta:vars\] aKey=aValue - hosts: - all - aGroupSpecifiedInInventory - groups - -i anInventory - Textual - lineinfile: - Data, Variables, & Facts - lookup() - Example - name: add authorized\_key to non-root user authorized\_key: user: deployer state: present key: "{{ lookup('file', '/home/matt/first\_playbook/first\_playbook.pub') }}" - lookup('env', - lookup('file', - Can use jinja syntax - vars:: - aVar: aValue - Inventory Variables v - Can be from inventory files, group files, playbooks, cli, facts, Ansible Tower - Jinja templates - Facts - set\_fact: - aFact: aValue - when: ansible\_facts\[os\_family\] == 'Windows' - ansible localhost -m setup - to see what facts ansible collects on that system - gather\_facts: - no - The info that ansible gathers on the system before working with it - vars\_files: - ../inventory/group\_vars/all/vars - ../inventory/group\_vars/all/vault - Ansible Vault - ansible-vault - encrypt - decrypt - create - edit - ansible-playbook site.yml --vault-password-file \~/.vault\_pass.txt - ansible-playbook ask-vault-pass - ansible-lint - molecule for testing ## Specify Tasks in a Playbook with Tags - [How to run only one task in ansible playbook? - Stack Overflow](https://stackoverflow.com/questions/23945201/how-to-run-only-one-task-in-ansible-playbook) ```yaml tasks: - yum: name={{ item }} state=installed with_items: - httpd - memcached tags: - packages - template: src=templates/src.j2 dest=/etc/foo.conf tags: - configuration ``` `ansible-playbook example.yml --tags "configuration,packages"`