Le Blog Utux

HTTP 200 GET /

Ansible Jinja loop all groups except

Rédigé par uTux Aucun commentaire

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.

Vscode

Rédigé par uTux 1 commentaire

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.

Vscode

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 :)

Ansible: récupérer les clés SSH depuis BitBucket

Rédigé par uTux Aucun commentaire

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!

J'aime le libre

Rédigé par uTux 24 commentaires

J'écris cet article pour combattre une idée que je vois revenir souvent dans la blogosphère (française), qui dit que dans l'univers du logiciel libre c'est le bordel, c'est la guerre, trop de choix, des distributions qui se combattent au lieu de s'unir, et des développeurs qui se moquent de leurs utilisateurs.

J'ai un problème avec ça car le libre c'est mon métier. Je suis ingénieur systèmes Linux et si j'en suis arrivé là, c'est parce que je baigne dans un univers où on partage les connaissances, où on peut lire le code, où on peut poser des questions, et où globalement les logiciels marchent bien. Il y a 20 ans encore l'informatique c'était très majoritairement du Microsoft, un monde payant dans lequel il fallait des diplômes, des livres, des certifications, c'était quand même assez fermé et peu accessible. Aujourd'hui les produits libres en vogue tels que Docker ou Ansible publient leur documentation, des howto, des quickstart, un repo github, et si on ajoute stackoverfow/stackexchange on peut s'auto-former en quelques semaines. Bien sûr l'expérience en production est importante et ce n'est qu'après quelques mois voire années qu'on peut se vendre comme "expert" sur cette technologie, mais au moins c'est possible. Allez essayer de vous auto-former avec un Windows Server et un Exchange, outre les spécifications matérielles très élevées, hors programme MSDNA c'est juste impossible à cause du coût des licences.

Le libre c'est aussi la culture Devops dont je fais partie et où Microsoft a bien du mal à se positionner. On automatise, on industrialise, on code, on pousse sur le repo git, les tests unitaires et l'intégration sont déclenchés tout seuls, et on s'amuse. Merci au libre de nous avoir montré qu'on peut faire autre chose qu'installer des .exe à la main ou avec des logiciels très cher tels que SCCM.

Donc au final quand je tombe sur des articles présentant le monde du logiciel libre comme game of thrones, je me dis que ce n'est que la vision desktop, les 1% de parts de marché pour lesquels j'ai abandonné tout espoir. On oublie la culture qu'il y a derrière et moi j'aime travailler avec le libre, pas pour les raisons extrémistes de RMS et la FSF, mais pour l'efficacité, le partage, les compétences, l'accessibilité.

Ansible: loop, subelements, dictionnary

Rédigé par uTux Aucun commentaire

Article pense-bête. J'écris un petit rôle pour configurer firewalld, en gros je veux spécifier quelles interfaces et quels services il faut ajouter dans les zones. Mon idée c'est de définir tout ça dans un dictionnaire dans le playbook, et ensuite de récupérer les élements et sous-élements dans le rôle.

Voici ce que ça donne:

# install.yml

- hosts: nas

  roles:
    - nfs-server
    - firewalld

  vars:
    firewalld_zones:
      - zone: internal
        interfaces:
          - eth0
        services:
          - mountd
          - nfs
          - rpc-bind
  - name: Define zones for interfaces
    firewalld:
      zone: "{{ item.0.zone }}"
      permanent: true
      immediate: true
      interface: "{{ item.1 }}"
      state: enabled
    with_subelements:
      - "{{ firewalld_zones }}"
      - interfaces

  - name: Allow services for zones
    firewalld:
      zone: "{{ item.0.zone }}"
      permanent: true
      immediate: true
      service: "{{ item.1 }}"
      state: enabled
    with_subelements:
      - "{{ firewalld_zones }}"
      - services

Mouais. C'est quand même loin d'être clair ou évident. Mais c'est le seul moyen que j'ai trouvé pour le moment. Si quelqu'un connaît une méthode plus propre/lisible je suis preneur.

Fil RSS des articles de cette catégorie