Ansible Workshop
hello!
I am Arie Bregman
2
What are we going to do today?
● Learn what is Ansible
● Do automation with Ansible
● Ask the instructor many question
3
What is Ansible?
● IT Automation Tool
● Focuses on simplicity and ease-of-use
● Open Source
○ More than 4,000 contributors
○ More than 40,000 contributions
4
Why using Ansible?
● “Why not simply use shell scripts?”
● “Why specifically Ansible and not Puppet or Chef or …?”
5
Let’s install a package with a shell script
6
YUM_CMD=$(which yum) # or dnf
APT_GET_CMD=$(which apt-get)
...
if [[ ! -z $YUM_CMD ]]; then
dnf install ntpdate
elif [[ ! -z $APT_GET_CMD ]]; then
apt-get install ntpdate
elif ...
...
else
echo "error can't install package ntpdate"
exit 1;
fi
Now let’s install the same package with Ansible
7
- name: install ntpdate
package:
name: ntpdate
state: present
● Works on multiple distributions
● Readable
● Describes desired status rather than the action
This is called a
“task” in Ansible
Why specifically Ansible?
8
● Python & SSH is all you need
● Simple to use
● Agentless
● Over 3300 modules!
● Great community
Time to have fun! but first, installation
9
# Fedora, RHEL 8, CentOS 8
$ dnf install ansible -y
# For older releases, use yum instead
# Ubuntu
$ apt-get install ansible -y
# Verify you can ssh without using a password to the machine you’ll use
$ ssh x.x.x.x
# No? Then run the following
$ ssh-copy-id <user>@x.x.x.x
Inventory
11
● The hosts/servers you manage with Ansible
● Types of inventory
○ Static
○ Dynamic
● Default inventory
○ /etc/ansible/hosts
We will define a static inventory
Update you inventory
12
[remote]
x.x.x.x
$ sudo vi /etc/ansible/hosts
Let’s test it! :)
ansible remote -m ping
remote | SUCCESS => {
"changed": false,
"ping": "pong"
}
x.x.x.x [remote]
X.x.x.x ansible_user=vagrant
Or Or
Using this, you can
later reference in
Ansible multiple
servers with one
name
Write your first Playbook
13
- hosts: remote
tasks:
- name: Create the file /tmp/x
file:
path: /tmp/x
state: touch
$ vi first_task.yml
* A playbooks is a collection
plays
* A play is a collection of tasks
running on a single or multiple
hosts
Run your first Playbook
14
PLAY [remote] **************************************************
TASK [Gathering Facts] *****************************************
ok: [remote]
TASK [Create the file /tmp/x] **********************************
changed: [remote]
PLAY RECAP *****************************************************
remote : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0
$ ansible-playbook first_playbook.yml
Multiple Tasks
15
- hosts: remote
tasks:
- name: Install the package htop
become: yes
package:
name: htop
state: present
- name: install the package python-routes
become: true
package:
name: python-routes
state: present
- hosts: webservers
tasks:
- name: Install the package htop
become: yes
package:
name: htop
state: present
- hosts: dbservers
tasks:
- name: install the package python-routes
become: root
package:
name: python-routes
state: present
Playbook
play
play
Exercise #1
16
● Write a playbook which will:
○ Create the file /tmp/x
○ Create the file /tmp/y
○ Create the file /tmp/z
- hosts: [host or hosts group name]
tasks:
- name: [task name]
[module name]:
path: ...
state: ...
# Commands
ansible-playbook
What modules are there?
17
$ ansible-doc <module_name>
$ ansible-doc file
$ ansible-doc -l
● List modules
● Information on specific module
ansible-doc format
18
Module source code path
Module Description
Single option (Optional)
19
Module Author and support
Examples ==
How to use the
module
Variables
20
● Used for storing values you can reference multiple times in your
playbook, in different tasks
● It’s common to find them used in conditionals, loops, ...
- hosts: remote
vars:
file_path: /tmp/x
tasks:
- name: Create the file "{{ file_path }}"
file:
name: "{{ file_path }}"
state: touch
Loops
21
● What if I need to create 10 files or install 30 package?
- hosts: remote
tasks:
- name: Create multiple files
file:
name: "{{ item }}"
state: touch
loop:
- /tmp/a
- /tmp/b
- /tmp/c
22
PLAY [remote]
********************************************************************************************************
TASK [Gathering Facts]
************************************************************************************************
ok: [192.168.33.10]
TASK [add several users]
**************************************************************************************************
changed: [192.168.33.10] => (item=/tmp/a)
changed: [192.168.33.10] => (item=/tmp/b)
changed: [192.168.33.10] => (item=/tmp/c)
PLAY RECAP
************************************************************************************************************
192.168.33.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0
Privileges
23
● Some tasks can’t be executed by a regular user
○ Installing packages
○ Adding users
● The “become” directive helps with that
- hosts: remote
tasks:
- name: Install the package python
become: yes
package:
name: python
state: present
- hosts: remote
tasks:
- name: Install the package python
become: yes
become_user: luigi
file:
path: ~/stam_file
state: present
Exercise #2
24
● Write a playbook which will:
○ Add the users
■ sarah, john, grace
○ Create the directories
■ /tmp/dir1 , /tmp/dir2, /tmp/dir3
# Commands
ansible-playbook
ansible-doc -l
ansible-doc <module_name>
# Directives
loop:
become:
become_user:
- hosts: remote
tasks:
- name: blip blop
file:
...
loop:
- ...
Facts
25
ansible remote -m setup | less
...
"ansible_user_dir": "/home/vagrant",
"ansible_user_gecos": "",
"ansible_user_gid": 1000,
"ansible_user_id": "vagrant",
"ansible_user_shell": "/bin/bash",
"ansible_user_uid": 1000,
"ansible_userspace_architecture": "x86_64",
"ansible_userspace_bits": "64",
"ansible_virtualization_role": "guest",
"ansible_virtualization_type": "virtualbox",
...
Conditionals
26
● Run task only when certain condition is met
- hosts: remote
tasks:
- name: Install apache httpd
become: yes
apt:
name: apache2
state: present
when: ansible_facts['distribution'] == "Ubuntu"
Conditionals: AND
27
- hosts: remote
tasks:
- name: Install apache httpd
become: yes
apt:
name: apache2
state: present
when:
- ansible_facts['distribution'] in ['CentOS', 'RedHat']
- my_var < 6
- install_apache
Conditionals: OR
28
- hosts: remote
tasks:
- name: Install apache httpd
become: yes
apt:
name: apache2
state: present
when: ansible_facts['distribution'] == "Ubuntu" or ansible_facts['distribution'] == "Suse"
29
{{ [32, 3, 5, 121, 6, 7] | max }}
Filters
● Transformation of data
{{ [32, 3, 5, 121, 6, 7] | min }}
{{ [32, 3, 5, 121, 6, 7] | random }}
{{ some_path | dirname }}
{{ some_string | quote }}
30
- hosts: remote
tasks:
- name: Create multiple files
file:
name: "{{ item }}"
state: touch
loop: “{{ files_list | default([]) }}” What is the result of
the task?
OK? Changed?
Skipped?
● Also useful for dealing with undefined variables
Exercise #3
31
● Write a playbook which will:
○ Install the package htop only if the major version of the
operating system is 14
○ Install the package netcat only if the major version of the
operating system is 16
○ Add one random user of the following
■ [‘ed’, ‘eddy’, ‘eddie’]
# Commands
ansible-playbook
ansible-doc -l
ansible-doc <module_name>
ansible remote -m setup | less
AD-HOC
32
● Run tasks without writing playbooks
● For quick and non-repeating changes
ansible [hosts_pattern] -m [module_name] -a “[module options]”
AD-HOC Example
33
ansible remote -m file -a "name=/tmp/ad-hoc state=touch"
192.168.33.10 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/tmp/ad-hoc",
"gid": 1000,
"group": "vagrant",
"mode": "0664",
"owner": "vagrant",
"size": 0,
"state": "file",
"uid": 1000
}
Exercise #4
34
● Create locally a file with the content
○ “I came here from a far far server”
● Using ad-hoc commands:
○ Add a user called “mario”
○ Run the service “cron” (Ubuntu) or “crond” (RHEL, Fedora)
○ Copy the file you create to the remote server
# Commands
ansible-playbook
ansible-doc -l
ansible-doc <module_name>
ansible remote -m setup | less
ansible remote -m module -a “...”
ansible [hosts_pattern] -m [module_name] -a “[module options]”
Command & Shell modules
35
● “I want to run a customized script on a remote host”
● “I’m unable to find a module for what I need”
● Solution
○ command or shell module
name: Get blipblop version
become: yes
command: "rpm -q --qf %{VERSION} blipblop"
register: blipblop_rpm_version
Register Result
36
● By registering the result of a task we can “connect” between tasks
- name: Get blipblop version
become: yes
command: "rpm -q --qf %{VERSION} blipblop"
register: blipblop_rpm_version
- name: Get blipblop version
become: yes
shell: |
echo “blip blop begin”
ls -l
echo “blip blop end”
when: blipblop_rpm_version.stdout == “1.2.3”
Register: Another Example
37
● Configure an app and run it only if configuration was successful
- name: configure X app
command: configure
args:
chdir: /x_app
register: x_app_config
- name: run X app
command: run
args:
chdir: /x_app
when: x_app_config.rc == 0
Register: One More Example
38
● Run until return code is 0
- name: run some_command
command: some_command
register: result
until: result.rc == 0
retries: 5
Exercise #5
39
● Write the following playbook:
○ Download the file
https://gist.github.com/corysimmons/8b94c08421dec18bbaa4
○ If the download was successful, log the message “I managed to
download file with Ansible. So excited…”
# Commands
ansible-playbook
ansible-doc -l
ansible-doc <module_name>
ansible remote -m setup | less
ansible remote -m module -a “...”
# Directives
loop:
when:
become: become_user:
args:
until:
# Variables
{{ x }}
{{ x | default(“”) }}
Summary
40
# Commands
ansible-playbook
ansible-doc -l
ansible-doc <module_name>
ansible remote -m setup | less
ansible remote -m module -a “...”
# Variables
{{ x }}
{{ x | default(“”) }}
# Directives
loop:
when:
become:
become_user
args:
until:
Next Steps (Suggestion)
41
● Blocks
● Ansible Roles
● Dynamic Inventory
● Error Handling
● Tests
thanks!
Any questions?
You can contact me at
linkedin@abregman
42
Credits
Special thanks to all the people who made and released
these awesome resources for free:
✘ Presentation template by SlidesCarnival
✘ Photographs by Unsplash
43

Ansible for Beginners

  • 1.
  • 2.
  • 3.
    What are wegoing to do today? ● Learn what is Ansible ● Do automation with Ansible ● Ask the instructor many question 3
  • 4.
    What is Ansible? ●IT Automation Tool ● Focuses on simplicity and ease-of-use ● Open Source ○ More than 4,000 contributors ○ More than 40,000 contributions 4
  • 5.
    Why using Ansible? ●“Why not simply use shell scripts?” ● “Why specifically Ansible and not Puppet or Chef or …?” 5
  • 6.
    Let’s install apackage with a shell script 6 YUM_CMD=$(which yum) # or dnf APT_GET_CMD=$(which apt-get) ... if [[ ! -z $YUM_CMD ]]; then dnf install ntpdate elif [[ ! -z $APT_GET_CMD ]]; then apt-get install ntpdate elif ... ... else echo "error can't install package ntpdate" exit 1; fi
  • 7.
    Now let’s installthe same package with Ansible 7 - name: install ntpdate package: name: ntpdate state: present ● Works on multiple distributions ● Readable ● Describes desired status rather than the action This is called a “task” in Ansible
  • 8.
    Why specifically Ansible? 8 ●Python & SSH is all you need ● Simple to use ● Agentless ● Over 3300 modules! ● Great community
  • 9.
    Time to havefun! but first, installation 9 # Fedora, RHEL 8, CentOS 8 $ dnf install ansible -y # For older releases, use yum instead # Ubuntu $ apt-get install ansible -y # Verify you can ssh without using a password to the machine you’ll use $ ssh x.x.x.x # No? Then run the following $ ssh-copy-id <user>@x.x.x.x
  • 11.
    Inventory 11 ● The hosts/serversyou manage with Ansible ● Types of inventory ○ Static ○ Dynamic ● Default inventory ○ /etc/ansible/hosts We will define a static inventory
  • 12.
    Update you inventory 12 [remote] x.x.x.x $sudo vi /etc/ansible/hosts Let’s test it! :) ansible remote -m ping remote | SUCCESS => { "changed": false, "ping": "pong" } x.x.x.x [remote] X.x.x.x ansible_user=vagrant Or Or Using this, you can later reference in Ansible multiple servers with one name
  • 13.
    Write your firstPlaybook 13 - hosts: remote tasks: - name: Create the file /tmp/x file: path: /tmp/x state: touch $ vi first_task.yml * A playbooks is a collection plays * A play is a collection of tasks running on a single or multiple hosts
  • 14.
    Run your firstPlaybook 14 PLAY [remote] ************************************************** TASK [Gathering Facts] ***************************************** ok: [remote] TASK [Create the file /tmp/x] ********************************** changed: [remote] PLAY RECAP ***************************************************** remote : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 $ ansible-playbook first_playbook.yml
  • 15.
    Multiple Tasks 15 - hosts:remote tasks: - name: Install the package htop become: yes package: name: htop state: present - name: install the package python-routes become: true package: name: python-routes state: present - hosts: webservers tasks: - name: Install the package htop become: yes package: name: htop state: present - hosts: dbservers tasks: - name: install the package python-routes become: root package: name: python-routes state: present Playbook play play
  • 16.
    Exercise #1 16 ● Writea playbook which will: ○ Create the file /tmp/x ○ Create the file /tmp/y ○ Create the file /tmp/z - hosts: [host or hosts group name] tasks: - name: [task name] [module name]: path: ... state: ... # Commands ansible-playbook
  • 17.
    What modules arethere? 17 $ ansible-doc <module_name> $ ansible-doc file $ ansible-doc -l ● List modules ● Information on specific module
  • 18.
    ansible-doc format 18 Module sourcecode path Module Description Single option (Optional)
  • 19.
    19 Module Author andsupport Examples == How to use the module
  • 20.
    Variables 20 ● Used forstoring values you can reference multiple times in your playbook, in different tasks ● It’s common to find them used in conditionals, loops, ... - hosts: remote vars: file_path: /tmp/x tasks: - name: Create the file "{{ file_path }}" file: name: "{{ file_path }}" state: touch
  • 21.
    Loops 21 ● What ifI need to create 10 files or install 30 package? - hosts: remote tasks: - name: Create multiple files file: name: "{{ item }}" state: touch loop: - /tmp/a - /tmp/b - /tmp/c
  • 22.
    22 PLAY [remote] ******************************************************************************************************** TASK [GatheringFacts] ************************************************************************************************ ok: [192.168.33.10] TASK [add several users] ************************************************************************************************** changed: [192.168.33.10] => (item=/tmp/a) changed: [192.168.33.10] => (item=/tmp/b) changed: [192.168.33.10] => (item=/tmp/c) PLAY RECAP ************************************************************************************************************ 192.168.33.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0
  • 23.
    Privileges 23 ● Some taskscan’t be executed by a regular user ○ Installing packages ○ Adding users ● The “become” directive helps with that - hosts: remote tasks: - name: Install the package python become: yes package: name: python state: present - hosts: remote tasks: - name: Install the package python become: yes become_user: luigi file: path: ~/stam_file state: present
  • 24.
    Exercise #2 24 ● Writea playbook which will: ○ Add the users ■ sarah, john, grace ○ Create the directories ■ /tmp/dir1 , /tmp/dir2, /tmp/dir3 # Commands ansible-playbook ansible-doc -l ansible-doc <module_name> # Directives loop: become: become_user: - hosts: remote tasks: - name: blip blop file: ... loop: - ...
  • 25.
    Facts 25 ansible remote -msetup | less ... "ansible_user_dir": "/home/vagrant", "ansible_user_gecos": "", "ansible_user_gid": 1000, "ansible_user_id": "vagrant", "ansible_user_shell": "/bin/bash", "ansible_user_uid": 1000, "ansible_userspace_architecture": "x86_64", "ansible_userspace_bits": "64", "ansible_virtualization_role": "guest", "ansible_virtualization_type": "virtualbox", ...
  • 26.
    Conditionals 26 ● Run taskonly when certain condition is met - hosts: remote tasks: - name: Install apache httpd become: yes apt: name: apache2 state: present when: ansible_facts['distribution'] == "Ubuntu"
  • 27.
    Conditionals: AND 27 - hosts:remote tasks: - name: Install apache httpd become: yes apt: name: apache2 state: present when: - ansible_facts['distribution'] in ['CentOS', 'RedHat'] - my_var < 6 - install_apache
  • 28.
    Conditionals: OR 28 - hosts:remote tasks: - name: Install apache httpd become: yes apt: name: apache2 state: present when: ansible_facts['distribution'] == "Ubuntu" or ansible_facts['distribution'] == "Suse"
  • 29.
    29 {{ [32, 3,5, 121, 6, 7] | max }} Filters ● Transformation of data {{ [32, 3, 5, 121, 6, 7] | min }} {{ [32, 3, 5, 121, 6, 7] | random }} {{ some_path | dirname }} {{ some_string | quote }}
  • 30.
    30 - hosts: remote tasks: -name: Create multiple files file: name: "{{ item }}" state: touch loop: “{{ files_list | default([]) }}” What is the result of the task? OK? Changed? Skipped? ● Also useful for dealing with undefined variables
  • 31.
    Exercise #3 31 ● Writea playbook which will: ○ Install the package htop only if the major version of the operating system is 14 ○ Install the package netcat only if the major version of the operating system is 16 ○ Add one random user of the following ■ [‘ed’, ‘eddy’, ‘eddie’] # Commands ansible-playbook ansible-doc -l ansible-doc <module_name> ansible remote -m setup | less
  • 32.
    AD-HOC 32 ● Run taskswithout writing playbooks ● For quick and non-repeating changes ansible [hosts_pattern] -m [module_name] -a “[module options]”
  • 33.
    AD-HOC Example 33 ansible remote-m file -a "name=/tmp/ad-hoc state=touch" 192.168.33.10 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/tmp/ad-hoc", "gid": 1000, "group": "vagrant", "mode": "0664", "owner": "vagrant", "size": 0, "state": "file", "uid": 1000 }
  • 34.
    Exercise #4 34 ● Createlocally a file with the content ○ “I came here from a far far server” ● Using ad-hoc commands: ○ Add a user called “mario” ○ Run the service “cron” (Ubuntu) or “crond” (RHEL, Fedora) ○ Copy the file you create to the remote server # Commands ansible-playbook ansible-doc -l ansible-doc <module_name> ansible remote -m setup | less ansible remote -m module -a “...” ansible [hosts_pattern] -m [module_name] -a “[module options]”
  • 35.
    Command & Shellmodules 35 ● “I want to run a customized script on a remote host” ● “I’m unable to find a module for what I need” ● Solution ○ command or shell module name: Get blipblop version become: yes command: "rpm -q --qf %{VERSION} blipblop" register: blipblop_rpm_version
  • 36.
    Register Result 36 ● Byregistering the result of a task we can “connect” between tasks - name: Get blipblop version become: yes command: "rpm -q --qf %{VERSION} blipblop" register: blipblop_rpm_version - name: Get blipblop version become: yes shell: | echo “blip blop begin” ls -l echo “blip blop end” when: blipblop_rpm_version.stdout == “1.2.3”
  • 37.
    Register: Another Example 37 ●Configure an app and run it only if configuration was successful - name: configure X app command: configure args: chdir: /x_app register: x_app_config - name: run X app command: run args: chdir: /x_app when: x_app_config.rc == 0
  • 38.
    Register: One MoreExample 38 ● Run until return code is 0 - name: run some_command command: some_command register: result until: result.rc == 0 retries: 5
  • 39.
    Exercise #5 39 ● Writethe following playbook: ○ Download the file https://gist.github.com/corysimmons/8b94c08421dec18bbaa4 ○ If the download was successful, log the message “I managed to download file with Ansible. So excited…” # Commands ansible-playbook ansible-doc -l ansible-doc <module_name> ansible remote -m setup | less ansible remote -m module -a “...” # Directives loop: when: become: become_user: args: until: # Variables {{ x }} {{ x | default(“”) }}
  • 40.
    Summary 40 # Commands ansible-playbook ansible-doc -l ansible-doc<module_name> ansible remote -m setup | less ansible remote -m module -a “...” # Variables {{ x }} {{ x | default(“”) }} # Directives loop: when: become: become_user args: until:
  • 41.
    Next Steps (Suggestion) 41 ●Blocks ● Ansible Roles ● Dynamic Inventory ● Error Handling ● Tests
  • 42.
    thanks! Any questions? You cancontact me at linkedin@abregman 42
  • 43.
    Credits Special thanks toall the people who made and released these awesome resources for free: ✘ Presentation template by SlidesCarnival ✘ Photographs by Unsplash 43