I think debops developers are really good and I learn a lot of advanced stuff when I read their roles. I think they should be the reference for Ansible best practises. Here is 3 useful tricks that I did not know.
if in variables
From debops/ansible-docker:
docker__upstream: '{{ True
if (docker__distribution_release == "stretch")
else False }}'
Self explanatory.
Variables mapping
From debops/ansible-docker::
docker__upstream_arch_map:
'x86_64': 'amd64'
'armhf': 'armhf'
docker__upstream_repository: '{{ "deb [arch="
+ docker__upstream_arch_map[ansible_architecture]
+ "] https://download.docker.com/linux/" + docker__distribution|lower + " "
+ docker__distribution_release + " " + docker__upstream_channel }}'
The fact ansible_architecture is x86_64, so the variable docker__upstream_arch_map[ansible_architecture] will be resolve to amd64.
YAML to json j2
From debops/ansible-docker:
{{ docker__tpl_options | to_nice_json }}
In a variable file, simply set a YAML dictionnary, ie /defaults/main.yml:
docker__tpl_options:
data-root: /var/lib/docker
storage-driver: overlay2
In templates/daemon.j2:
{{ docker__tpl_options | to_nice_json }}
Thank you debops :)
It took me some time to figure out how to use Azure tags as a filter for Ansible. Well it's not that hard, azure_rm.py will automatically generate groups based on tags with this pattern:
- Tag: role:webserver
- Becomes group: role_webserver
Yes, that's the trick, ":" becomes "_". Let's say you want to run a playbook only on machines tagged with role:webserver, just use the following command:
$ ansible-playbook -i azure_rm.py playbook.yml --limit role_webserver
Je m'attaque aux API REST et en particulier celle de BitBucket pour y récupérer mes clés SSH que je déploie ensuite sur mes serveurs, le tout avec Ansible. Voilà un petit bout de code sur lequel j'ai passé une bonne soirée car autant c'est facile d'interroger l'API, autant ça l'est un peu moins de faire rentrer les bons champs dans des variables ;)
Pré requis:
- Sur votre compte BitBucket
- Settings > App passwords
- Créez un password avec l'autorisation Account / read.
Allons-y (à mettre dans votre tasks/main.yml par exemple):
---
- name: GET authorized_keys from REST API
uri:
url: "{{ authorized_keys.api_url }}"
method: "{{ authorized_keys.api_method }}"
user: "{{ authorized_keys.api_user }}"
password: "{{ authorized_keys.api_password }}"
force_basic_auth: "{{ authorized_keys.api_force_basic }}"
register: authorized_keys__json_response
delegate_to: localhost
run_once: True
# Delegate to localhost and run 1 time because
# we don't need to query the API from each remote host
- name: Set Keys as a Var
set_fact:
authorized_keys__keys: "{{ authorized_keys__json_response.json | json_query('values[*].key') }}"
delegate_to: localhost
run_once: True
# Extract the fields 'key' in a variable
- name: Concatenate Keys
set_fact:
authorized_keys__keys_concatenate: "{{ authorized_keys__keys | join('\n') }}"
delegate_to: localhost
run_once: True
# Ansible authorized_keys module with 'exclusive' option requires all keys in one batch
# separated by a newline \n
La variable authorized_keys__keys contient la liste des clés publiques. La variable authorized_keys__keys_concatenate n'est pas une liste mais un champ contenant toutes les clés séparées par un retour à la ligne et elle est utile si vous souhaitez utiliser le module authorized_keys avec exclusive: yes car ce dernier ne marche pas bien avec une liste, il faut donc lui fournir 1 seul "batch".
Complétez ensuite vos variables, par exemple:
# group_vars/all/vars.yml
authorized_keys:
api_user: john
api_url: "https://api.bitbucket.org/2.0/users/john/ssh-keys"
api_method: GET
api_force_basic: yes
api_password: password créé dans l'interface bitbucket
Bien sûr en vrai on mettra le password dans un vault ;)
Et voilà, vous pouvez utiliser authorized_keys__keys ou authorized_keys__keys_concatenate pour la suite!