Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.
Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.
Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.
Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.
👩🏾 💻 local
⬇️ SSH
🖥️ Server
👨🏿 💻 local
⬇️ SSH ⬇️ SSH ⬇️ SSH
🖥️ 🖥️ 🖥️ Servers
👩🏼 💻 local
⬇️ GIT
🖥️ Gitlab & Gitlab-CI
⬇️ SSH ⬇️ SSH ⬇️ SSH
🖥️ 🖥️ 🖥️ Servers
⚠ YAML
all-the-things ⚠
file
, copy
, apt
, …)hosts
file group_vars/
variables host_vars/
variables
(e.g. file
, copy
, apt
, …)
file
module
file
moduleParameter | Choices/Defaults | Comments |
---|---|---|
path required | path to the file being managed. Aliases: dest, name | |
state | Choices: absent directory file ← hard link touch | If directory, all intermediate subdirectories will be created if they do not exist. Since Ansible 1.7 they will be created with the supplied permissions. If file, the file will NOT be created if it does not exist; see the touch value or the copy or template module if you want that behavior. If link, the symbolic link will be created or changed. Use hard for hardlinks. If absent, directories will be recursively deleted, and files or symlinks will be unlinked. Note that absent will not cause file to fail if the path does not exist as the state did not change. If touch (new in 1.4), an empty file will be created if the path does not exist, while an existing file or directory will receive updated file access and modification times (similar to the way `touch` works from the command line). |
force bool | Choices: no ← yes | … |
group | … | |
mode | … | |
owner | … |
file
module- name: Create nginx needed directories
file:
path: /etc/nginx/conf.d
state: directory
file
module👨🏻 💻 Run a single module with
> ansible -m file --args "state=touch path=/tmp/coucou" localhost
localhost | SUCCESS => {
"changed": true,
"dest": "/tmp/coucou",
"failed": false,
"gid": 27,
"group": "sudo",
"mode": "0644",
"owner": "paul",
"size": 0,
"state": "file",
"uid": 1000
}
> ls -l /tmp/coucou
-rw-r--r-- 1 paul sudo 0 Aug 27 14:48 /tmp/coucou
apt
module- name: Install nginx.
apt:
update_cache: yes
cache_valid_time: 86400
name: nginx
state: present
At the time of writing taken from https://docs.ansible.com/ansible/latest/modules/
file
, copy
, apt
, …)hosts
file group_vars/
variables host_vars/
variables (A packaged set of tasks)
vendor/
├── docker-gc
├── docker-ubuntu
├── geerlingguy.varnish
├── gitlab-runner
└── rbenv
5 directories, 0 files
👩🏼 💻 Installed with
> ansible-galaxy install --roles-path vendor/ -r requirements.yml
roles/
├── ...
├── common
├── docker
├── ...
├── local_setup
├── ...
├── nginx
├── ...
└── slack_bot
20 directories, 0 files
roles/nginx/
├── defaults/
├── vars/
├── handlers/
├── tasks/
├── files/
└── templates/
6 directories, 0 files
roles/nginx/tasks/nginx-app.yml
file
- name: remove previous conf files
file:
path: "{{ item }}"
state: absent
with_fileglob:
- /etc/nginx/sites-enabled/www.*.conf
- name: Upload main CT nginx configuration
template:
src: www.conf.j2
dest: "/etc/nginx/sites-enabled/www.{{ item.key }}.conf"
with_dict: "{{ nginx_vhosts }}"
notify: nginx reload
roles/nginx/handlers/all.yml
file
- name: nginx reload
service:
name: nginx
state: reloaded
roles/nginx/defaults/main.yml
file
nginx_user: www-data
nginx_vhosts: {}
# ...
roles/nginx/templates/www.conf.j2
file
{% set server = item.value %}
{% set vhost = item.key %}
server {
server_name {{ server.server_name }};
listen {{ server.port | default(80) }};
access_log /var/log/nginx/www-{{ vhost }}.log;
error_log /var/log/nginx/www-{{ vhost }}-error.log;
location / {
proxy_pass http://{{ server.proxy_destination }};
}
}
file
, copy
, apt
, …)hosts
file group_vars/
variables host_vars/
variables (A list of servers and associated vars)
ansible> find . -name hosts
./inventories/production/hosts
./inventories/integration/hosts
./inventories/infra/hosts
inventories/production/
├── group_vars/
├── host_vars/
└── hosts
2 directories, 1 file
hosts
file
[nginx]
web[1:2].prod.example.org
[app]
sa[6:9].prod.example.org
group_vars/nginx/vars.yml
file
nginx_vhosts:
www.example.org:
port: 8080
server_name: "www.example.org example.org"
proxy_destination: "localhost:5000"
host_vars/web1.prod.example.org/vars.yml
file
private_ip: 172.16.10.1
group_vars/nginx/vault.yml
file
$ANSIBLE_VAULT;1.1;AES256
33326630376138613334303363306434623065383236366162616132383566386662636663666563
6133333065326439306366313532633561663266353665350a393932366364623236313330653734
34383239373434653835633131366636343736633766316532613230336132326138636165346461
3365656562336633360a636235343166366537383861643136336435343865383233376262613139
37626163316532636266636662373335343764626562376437653535303562633164313836376565
35613861346538303837653438383535663563643138313333333962383962326632323838386431
65646633646435396630623462626665326262393538613939396265333435366431633031323535
33353232656437356663
👨🏻 💻 Edit vaulted variable file with
> ansible-vault edit production/group_vars/nginx/vault.yml
Vault password: *********
group_vars/nginx/vault.yml
file (decrypted)
nginx_secret: MySuperSecretValue
ssl_cert: |
-----BEGIN CERTIFICATE-----
JLlkjjj2qjj...
file
, copy
, apt
, …)hosts
file group_vars/
variables host_vars/
variables (Applying a set of roles to an inventory)
> git ls-files *.yml
# Deploy Software
clever_deploy.yml
# Configure local system
local.yml
# Configure remote systems
app.yml
webservers.yml
# Orchestrate
restart.yml
upgrade.yml
setup.yml
# Ability to include other playbook
- include: notify_begin.yml
when: app_name is defined
- hosts: all
serial: [ "34%", "34%", "100%" ]
roles:
- role: common
# ...
- role: nginx
when: "nginx_setup | default(false)"
tags: ['nginx']
# ...
- role: redis
when: "'redis' in group_names"
tags: ['redis']
- role: ruby
deploy_step: 'prepare'
when: rbenv is defined
tags: [ 'ruby' ]
# ...
- include: notify_end.yml
when: app_name is defined
> ansible-playbook \
--inventory production \
--limit web1.prod.example.org \
--tag nginx \
setup.yml
file
, copy
, apt
, …)hosts
file group_vars/
variables host_vars/
variables Forgot which binary to use?
> make
app-specific-env make app-specific-env app_name=<app> output_dir=/tmp env=integration limit=dev
console make console # Run an ansible console
debug make debug host=myhost # Debug a host's variable
deploy make deploy app_name=<app> env=integration limit=dev # Launch an app deploy
dry-run make dry-run [playbook=setup] [env=integration] [tag=<ansible-tag>] [limit=<ansible-host-limit>] [args=<ansiblearguments>] # Run a playbook in dry run mode
facts make facts group=all # Gather facts from your hosts
install make install # Install roles dependencies
inventory-report make inventory-report #
lint make lint playbook=setup # Check syntax of a playbook
list make list # List hosts inventory
run make run [playbook=setup] [env=integration] [tag=<ansible-tag>] [limit=<ansible-host-limit>] [args=<ansiblearguments>] # Run a playbook
vault make vault file=/tmp/vault.yml # Edit or create a vaulted file
Questions?
— Thanks!