https://docs.ansible.com/ansible/latest/installation_guide/index.html
Ubuntu
$ sudo apt update$ sudo apt install software-properties-common$ sudo apt-add-repository --yes --update ppa:ansible/ansible$ sudo apt install ansibleDebian
Add the following line to /etc/apt/sources.list:
deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main
Then run these commands:
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367$ sudo apt update$ sudo apt install ansiblehttps://docs.ansible.com/ansible/latest/network/user_guide/network_best_practices_2.5.html
# You can specify only the server ip169.126.125.126# You can specify the server with eliasproduction ansible_host=169.126.125.126# You can specify the server with elias & usernameproduction ansible_host=169.126.125.126 ansible_user=bobAll servers belong to the group "all". Those that do not belong to any group are belong to the group "ungrouped".
List servers and groups in the config file:
ansible-inventory --listansible-inventory --graphModules infoansible-doc -lhttps://docs.ansible.com/ansible/latest/user_guide/sample_setup.html
We can using vars file instead of declare a variable in hosts file.
group_vars/ # Make directory for vars files
some_group.yml # here we assign variables to particular groups
group2.yml
host_vars/
hostname1.yml # here we assign variables to particular systems
hostname2.yml
some_group.yml
---
ansible_user: bob
ansible_ssh_private_key_file: /home/user/.ssh/id_rsa
...
Running playbooks:
ansible-playbook playbook.yml -f 10 -
-v --verbose - to see detailed output from successful modules as well as unsuccessful ones.
-C --check - don’t make any changes; instead, try to predict some of the changes that may occur
-e, --extra-vars - set additional variables as key=value or YAML/JSON, if filename prepend with @
https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html#ansible-playbook
Sample extra-vars
ansible-playbook playbook.yml -e "servers=Ubuntu"
playbook.yml
---
- name: test
host: "{{ server }}"
become: yes
roles:
- common
hosts.txt
[Ubuntu]
production ansible_host=169.126.125.126
Sample ping.yml
---
- name: Test Connection
hosts: all
# Like root
become: yes
tasks:
- name: Ping
ping:
Upgrade system
- name: System update
hosts: all
become: yes
tasks:
- name: Update cache
apt:
update_cache: yes
- name: Upgrade
apt:
upgrade: yes
Sample mkdir & mkfile
tasks:
- name: Make directory
file:
path: /home/dir
state: directory
mode: 0755
- name: Make file
copy:
dest: /home/dir/file.txt
content: |
string_1
string_2
{{ var }}
Sample Apache installation Apache.yml for Centos
---
- name: Install default Apache WEB Server
host: all
become: yes
tasks:
- name: Install Apache
yum: name=httpd state=latest
- name: Start Apache and Enable it on the every boot
service: name=httpd state=started enabled=yes
Sample Apache installation Apache.yml for debian
---
- name: Install default Apache WEB Server
host: all
become: yes
tasks:
- name: Install Apache
apt:
pkg: apache2
state:present
Multiple installations:
---
- name: multiple installation
host: all
become: yes
tasks:
- name: multiple installation
apt:
pkg:
- apache2
- htop
- tree
state: present
Create user & groups
---
- name: Create user & groups
hosts: all
become: yes
tasks:
- name: Create groups
group:
name: "{{item}}"
state: present
loop:
- dev
- test
- name: Create user
user:
name: bob
shell: /bin/bash
groups: dev,test
append: yes
home: /home/bob
Sample copy file & Apache installation Apache.yml & Handlers
---
- name: Install Apache and Upload my WEB Server
host: all
become: yes
vars:
source_file: ./Directory/index.html
destin_file: /var/www/html
tasks:
- name: Install Apache
yum: name=httpd state=latest
- name: Copy page
copy: src={{ source_file }} dest={{ destin_file }} mode=0555
notify: Restart apache
- name: Start Apache and Enable it on the every boot
service: name=httpd state=started enables=yes
handlers:
- name: Restart apache
service: name=httpd state=restarted
*handlers are called by notify.
Only copy file
---
- name: copy file
host: all
become: yes
tasks:
- name: copy file
copy:
src: ./dir/file
dest: /where/
mode: 777
debug, msg, set_fact, register
msg - A string with a generic message relayed to the user.
Multiple installations with vars:
---
- name: multiple installations with vars
host: all
become: yes
vars:
packages:
- apache2
- htop
- tree
tasks:
- name: multiple installations with vars
apt:
pkg: "{{packages}}"
state: present
Variables in debug
---
- name: Sample of variables
hosts: all
become: yes
vars:
var1: Hello
var2: World
tasks:
- name: Print variable
debug:
var: var1
- debug:
msg: "{{ var1 }} World"
- set_fact: full_message="{{ var1 }} {{ var2 }} "
- debug:
var: full_message
Show variable from ansible_facts (Print var from "-m setup")
---
- name: Ansible variable
hosts: all
become: yes
tasks:
- debug:
var: ansible_os_family
Return output & specific output
---
- name: Ansible output
hosts: all
become: yes
tasks:
- shell: uptime
register: results
- debug:
var: results
- debug:
var: results.stdout
Install Apache to CentOS & Debian using block condition when. block - create logical groups of tasks, also offer ways to handle task errors.
---
- name: Install Apache to CentOS & Debian
host: all
become: yes
vars:
source_file: ./Directory/index.html
destin_file: /var/www/html
tasks:
- block:
- name: Install Apache for CentOS
yum: name=httpd state=latest
- name: Copy page
copy: src={{ source_file }} dest={{ destin_file }} mode=0555
notify: Restart apache RedHat
- name: Start & Enable Apache for CentOS
service: name=httpd state=started enables=yes
when: ansible_os_family == "RedHat"
- block:
- name: Install Apache for Debian
yum: name=apache2 state=latest
- name: Copy page
copy: src={{ source_file }} dest={{ destin_file }} mode=0555
notify: Restart apache Debian
- name: Start & Enable Apache for Debian
service: name=apache2 state=started enables=yes
when: ansible_os_family == "Debian"
handlers:
- name: Restart apache RedHat
service: name=httpd state=restarted
- name: Restart apache Debian
service: name=apache2 state=restarted
Loop
Repeated tasks can be written as standard loops over a simple list of strings.
---
- name: Install Apache to CentOS & Debian
hosts: all
become: yes
tasks:
- name: Register loop output as a variable
debug: msg="number {{ item }}"
loop:
- one
- two
- name: Install packets using loop
apt: name={{ item }} state=latest
loop:
- apache2
- mariadb
Until
This is different to using when task argument for instance, where we only execute task IF condition is met. Here the condition MUST be met before we execute next task.
- name: Wait until web app status is "READY"
uri:
url: "{{ app_url }}/status"
register: app_status
until: app_status.json.status == "READY"
retries: 10
delay: 1
As an example, below task will keep sending GET request to specified URL until the "status" key in response is equal to "READY". We ask Ansible to make 10 attempts in total with delay of 1 second between each attempt. If after final attempt condition in until is still not met task is marked as failed.
mkdir roles
ansible-galaxy init name_of_role
tasks/main.yml - the main list of tasks that the role executes.
handlers/main.yml - handlers, which may be used within or outside this role.
library/my_module.py - modules, which may be used within this role (see Embedding modules and plugins in roles for more information).
defaults/main.yml - default variables for the role (see Using Variables for more information). These variables have the lowest priority of any variables available, and can be easily overridden by any other variable, including inventory variables.
vars/main.yml - other variables for the role (see Using Variables for more information).
files/main.yml - files that the role deploys.
templates/main.yml - templates that the role deploys.
meta/main.yml - metadata for the role, including role dependencies.
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html
Usefull role collection:
https://galaxy.ansible.com/ui/
The classic way to run a couple of roles:
---
- hosts: webservers
roles:
- common
- webservers
Run a playbook with roles:
ansible-playbook -i hosts side.yaml
When you use a conditional on an include_* statement, the condition is applied only to the include task itself and not to any other tasks within the included file(s).
tasks
- name: Include task
include: task.yml
- name: Include task
import: task.yml
- name: Delegate
shell: echo {{ ansible_hostname }} {{ ansible_default_ipv4.address }} >> ./info.log
delegate_to: 127.0.0.1
*shell wil be run only on 127.0.0.1
Rebooting
- name: Reboot
shell: sleep 2 && reboot now
async: 1
poll: 0
- name:
wait_for:
host: "{{ }}"
state: started
delay: 5
timeout: 40
delegate_to: 127.0.0.1
If you want a task to run only on the first host in your batch of hosts, set run_once to true on that task:
---
tasks:
- command: /opt/application/upgrade_db.py
run_once: true
---
- name: sample error
host: localhost
# Stop all after ferst error
any_errors_fatal: true
become: yes
tasks:
# For ignoring errors ##########
- name: Hello
shell: echo "Hello World"
ignore_errors: yes
#################################
# Print results #################
- name: Hello 2
shell: echo "Hello World"
register: results
# Additional condition by word
failed_when: "'World' in results.stdout"
# Additional condition by code
failed_when: results.rc == 0
- debug:
var: results
#################################
Encryption file
ansible-vault create secret.txt
Enter password
Enter data
Decryption file
ansible-vault view secret.txt
Enter password
Change encryption file
ansible-vault edit secret.txt
Enter password
Change password
ansible-vault rekey secret.txt
Enter password
Enter newpassword
Encryption existing file
ansible-vault encrypt playbook.yml
Decryption existing file
ansible-vault decrypt playbook.yml
Run ecryption file or variable
ansible-playbook playbook.yml --ask-vault-pass
ansible-playbook playbook.yml --ask-vault-password-file passwordfile.txt
Encryption variable
ansible-vault encrypt_string --stdin-name "password"
echo -n "Pa$$woRD" | ansible-vault encrypt_string
Issue - Response fom ping test:
Asterisk | FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Shared connection to 185.86.79.154 closed.\r\n",
"module_stdout": "/bin/sh: /usr/bin/python3: No such file or directory\r\n",
"msg": "MODULE FAILURE"
}
Answer
sudo ln -s /usr/bin/python3.6 /usr/bin/python3
Issue - do not work on CentOS
Answer:
sudo ln -s /etc/alternatives/python3 /usr/bin/python
sudo ln -s /usr/bin/python3.8 /usr/bin/python