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
I want to generate a /usr/local/etc/backuppc/hosts with all hosts from the ansible inventory, but exclude a group.
Inventory:
[dbservers]
db1
db2
db3
[DisableBackup]
db3
hosts.j2:
# {{ ansible_managed }}
{% for hosts in groups['all'] | difference(groups['DisableBackup']) %}
{{ hosts }}
{% endfor %}
tasks/generate_hosts.yml:
- name: Generate hosts file
template:
src: hosts.j2
dest: "{{ backuppc__confdir }}/hosts"
owner: "{{ backuppc__user }}"
group: "{{ backuppc__group }}"
mode: 0644
force: yes
Run:
ansible-playbook -i inventory install_backuppc.yml
Result:
cat /usr/local/etc/backuppc/hosts
# Ansible managed
db1
db2
Source.
Depuis la publication de ce billet, vscode est à la mode. Et pourtant il y a de quoi grincer des dents, on pense immédiatement à Visual Studio et à Microsoft, s'agit-il d'une usine à gaz propriétaire qui sert à pondre du code pour IE6? Pas du tout.
vscode n'est pas Visual Studio, c'est un éditeur de texte avancé plutôt léger, sous licence libre (Expat), avec pas mal de plugins pour les différents langages. Et oui il s'agit de Microsoft, mais comme beaucoup j'ai passé l'âge de jouer à l'intégriste, et on peut dire qu'ils font des efforts depuis quelques années. En ce qui me concerne j'ai toujours codé avec vim, mon premier contact avec vscode fut donc un premier contact avec ce genre d'éditeur de texte. Et pour le moment je me prends au jeu, j'utilise vscode, c'est vraiment pas mal.
J'aime la possibilité de visionner mon arborescence, travailler sur un fichier tout en ayant un terminal à disposition (par exemple pour tester des playbook Ansible). Il y a un léger temps d'adaptation pour apprendre les raccourcis (ctrl+s), mais ça reste plus facile que vim :) Je n'ai pas réussi à configurer l'utilisation d'un proxy http (oui, ça existe encore dans certaines entreprises...) ce qui m'a obligé à passer par proxychains.
Je n'aime pas l'autocomplétion, par exemple quand je veux ajouter un <strong> devant un mot, il ajoute automatiquement le </strong> mais pas au bon endroit. Pareil quand on manipule les double quote " dans les yaml, l'ajout et suppression peut devenir un enfer. Mais bon c'est toujours moins pire que vim et son indentation agaçante dans les dernières versions :) et ça se maîtrise.
Je continue à utiliser vscode, on verra si dans 6 mois je suis revenu sur vim ou pas :)
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!
Fil RSS des articles de cette catégorie