This presentation is an introduction to Ansible, an IT automation tool which can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.
Stephane ManciotResponsable BU JVM (Scala, JavaEE) - Ebiznext um Ebiznext
2. Main features
○ Automating remote system provisioning and
applications deployment
○ With no agents to install on remote systems
○ Using existing SSHd on remote system
○ Native OpenSSH for remote communication on
control machine
○ Parallel by default
○ Automation language that approaches plain english
3. Installation - requirements
○ Control machine requirements
● Python 2.6
● Any OS except Windows
○ Managed node requirements
● Python 2.4
9. Inventory file
○ Define how ansible will interact with remote hosts
○ Define logical groups of managed nodes
○ Default location : /etc/ansible/hosts
○ INI format
10. Inventory file - communication variables
○ ansible_connection : local, ssh or paramiko
○ ansible_ssh_host : the name of the host to connect
to
○ ansible_ssh_port : the ssh port number if not 22
○ ansible_ssh_user : the ssh user name to use
○ ansible_ssh_pass : the ssh password to use
(insecure)
○ ansible_ssh_private_key_file : private key file used
by ssh
11. Inventory file - hosts and groups
localhost ansible_connection=local
[webservers]
web[1:5].example.com ansible_connection=ssh ansible_ssh_user=webadmin
[dbservers]
db[1:2].example.com ansible_connection=ssh ansible_ssh_user=dbadmin
13. Inventory file - groups of groups
[atlanta]
host1
host2
[raleigh]
host2
host3
[southeast:children]
atlanta
raleigh
14. Inventory file - splitting out specific data
○ Define specific data using variables within YAML
files relative to the inventory file
[atlanta]
host1
host2
○ /etc/ansible/group_vars/atlanta, /etc/ansible/
host_vars/host1
---
ntp_server: acme.example.org
database_server: storage.example.org
○ /etc/ansible/group_vars/atlanta/db_settings
15. Patterns
○ Decide which hosts to manage
● all hosts in the inventory (all or *)
● a specific host name or group name (host1, webservers)
● wildcard configuration (192.168.1.*)
● OR configuration (host1:host2, webservers:dbservers)
● NOT configuration (webservers:dbservers:!production)
● AND configuration (webservers:dbservers:&staging)
● REGEX configuration (~(web|db).*.example.com)
● exclude hosts using limit flag (ansible-playbook site.yml
--limit datacenter2)
16. Vault
○ Allows keeping encrypted data in source control
○ Created encrypted files
$ ansible-vault create foo.yml
○ Editing encrypted files
$ ansible-vault edit foo.yml
○ Encrypting unencrypted files
$ ansible-vault encrypt foo.yml
○ Decrypting encrypted files
$ ansible-vault decrypt foo.yml
○ Running ad-hoc or playbook with vault
$ ansible-playbook site.yml --vault-password-file
~/.vault_pass.txt
17. Vagrant integration
# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network :private_network, ip: “192.168.33.10"
config.vm.provision :ansible do |ansible|
ansible.inventory_path = "vagrant-inventory.ini"
ansible.playbook = "dockers.yml"
ansible.extra_vars = { user: "vagrant" }
ansible.sudo = true
ansible.limit = 'all'
end
18. Ad-Hoc commands
○ $ ansible {pattern} -m {module} -a “{options}” {flags}
● pattern : which hosts
● module : which ansible module (command by default)
● options : which module options
● flags : command flags
○ -u {username}: to run the command as a different user (user
account by default)
○ -f {n}: to run the command in n parallel forks (5 by default)
○ --sudo: to run the command through sudo
○ -K: to interactively prompt you for the sudo password to use
○ -U {username}: to sudo to a user other than root
○ -i {file}: inventory file to use
○ --ask-vault-pass: to specify the vault-password interactively
○ --vault-password-file {file}: to specify the latter within a file
19. Ad-Hoc commands - samples
○ File transfer
$ ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"
○ Deploying from source control
$ ansible webservers -m git -a "repo=git://
foo.example.org/repo.git dest=/srv/myapp version=HEAD"
○ Managing services
$ ansible webservers -m service -a "name=httpd
state=started"
○ Gathering facts
$ ansible all -m setup
20. Playbook
○ Expressed in YAML language
○ Composed of one or more “plays” in a list
○ Allowing multi-machine deployments orchestration
21. Playbook - play
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
notify:
- restart apache
- name: ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service: name=httpd state=restarted
22. Playbook - hosts and users
○ hosts : one or more groups or host patterns
○ remote_user : the name of the remote user account
(per play or task)
○ sudo : run tasks using sudo (per play or task)
○ sudo_user : sudo to a different user than root
23. Playbook - tasks
○ Are executed in order against all machines matched
by the host pattern
○ May be Included from other files
tasks:
- include: tasks/foo.yml
○ Hosts with failed tasks are taken out for the entire
playbook
○ Each task executes a module with specific options
○ Modules are idempotent in order to bring the
system to the desired state
tasks:
- name: {task name}
{module}: {options}
24. Playbook - handlers
○ Notifications may be triggered at the end of each
block of tasks whenever a change has been made on
the remote system
○ Handlers are referenced by name
tasks:
- name: template configuration file
template: src=template.j2 dest=/etc/foo.conf
notify:
- restart apache
…
handlers:
- name: restart apache
service: name=apache state=restarted
25. Playbook - roles
○ Based on a known file structure
site.yml
webservers.yml
roles/
webservers/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
…
---
- hosts: webservers
roles:
- webservers
If roles/x/tasks/main.yml exists, tasks listed therein will be added to the play
If roles/x/handlers/main.yml exists, handlers listed therein will be added to the play
If roles/x/vars/main.yml exists, variables listed therein will be added to the play
If roles/x/meta/main.yml exists, any role dependencies listed therein will be added
to the list of roles (1.3 and later)
Any copy tasks can reference files in roles/x/files/ without having to path them
relatively or absolutely
Any script tasks can reference scripts in roles/x/files/ without having to path them
relatively or absolutely
Any template tasks can reference files in roles/x/templates/ without having to path
them relatively or absolutely
Any include tasks can reference files in roles/x/tasks/ without having to path them
relatively or absolutely
26. Playbook - roles
○ May be applied conditionally
---
- hosts: webservers
roles:
- { role: some_role, when: "ansible_os_family ==
'RedHat'" }
○ May be applied before or after other tasks
---
- hosts: webservers
pre_tasks:
- shell: echo 'hello'
roles:
- { role: some_role }
tasks:
- shell: echo 'still busy'
post_tasks:
- shell: echo 'goodbye'
27. Playbook - variables
○ Define directly inline
- hosts: webservers
vars:
http_port: 80
○ Default role variables defined in {role}/defaults/
main.yml file
○ Included variables
---
- hosts: all
remote_user: root
vars:
favcolor: blue
vars_files:
- /vars/external_vars.yml
29. Playbook - variables - Facts
○ Information discovered from remote system
○ Frequently used in conditionals
---
- include: "Ubuntu.yml"
when: ansible_distribution == 'Ubuntu'
○ Local facts
● {file}.fact within /etc/ansible/facts.d
[general]
foo=1
bar=2
● can be accessed in a template/playbook as
{{ ansible_local.file.general.foo }}
30. Playbook - variables - Precedence
○ -e variables
ansible-playbook release.yml --extra-vars "version=1.23.45
other_variable=foo"
○ “most everything else”
○ variables defined in inventory
○ variables defined in facts
○ role defaults
31. Playbook - conditions
○ Execute task conditionally
tasks:
- shell: echo "I've got '{{ foo }}' and am not afraid
to use it!"
when: foo is defined
○ Include tasks conditionally
- include: tasks/sometasks.yml
when: "'reticulating splines' in output"
○ Execute role conditionally
- hosts: webservers
roles:
- { role: debian_stock_config, when: ansible_os_family
== 'Debian' }