Le Blog Utux

HTTP 200 GET /

Merci Terraform 0.12 :)

Rédigé par uTux 2 commentaires

J'ai une relation d'amour et de haine avec Terraform. Cet outil est formidable pour discuter avec les providers de cloud et faire de la remédiation, en revanche je me casse régulièrement les dents sur le langage hcl que je trouve extrêmement limité et frustrant. Trois exemples :

  • Les variables : Toute variable doit être déclarée, typée et contenir une valeur, même si on ne s'en sert pas. Une variable ne peut pas être égale à une autre. Pas de dictionnaire.
  • Pas de if, pas de loop : On doit ruser avec count mais on perd grandement en souplesse et en lisibilité.
  • pas DRY: (Don't Repeat Yourself) on ne peut pas utiliser du code commun et envoyer des variables en fonction de l'environnement, donc on duplique pas mal de code. Ce problème est réglé par Terragrunt que je recommande.
Logo Terraform
C'est principalement pour ces deux raisons que je considère qu'il est très difficile voire impossible de faire du code générique sur Terraform. On ne peut pas créer un module qui gère tous les cas possibles à l'aide des variables, on devra obligatoirement imposer des choix.

Terraform 0.12 est une version qui était très attendue depuis près de 1 an car promettant de lever pas mal de limitations du hcl. Et en effet la nouvelle version du langage nous apporte des nouveautés très appréciables. Mes 3 préférées sont :

  • First-class expression syntax :
    • ${var.foo} devient var.foo
    • ${var.foo["key"]} devient var.foo.key
    • ${var.foo[count.index]} devient var.foo (mon préféré)
  • Generalized type system :Les variables peuvent être des "object" composés de clés de différents types. Les objets eux-mêmes peuvent faire partie d'une liste: exemple. C'est peut-être le plus gros progrès de cette version.
  • Iteration constructs : Arrivée des boucles for et des boucles dynamiques, semble en pratique plus limité que ce qu'on pourrait croire mais c'est bon à prendre. Exemple.

Terraform 0.12 couplé à Terragrunt offre une plus grande souplesse et évite de se répéter. J'ai entamé la migration de mes projets pour profiter de ces nouveautés, et j'en suis très content. Merci Terraform :)

Gitlab, bien mais gourmand

Rédigé par uTux 10 commentaires

J'adore gitlab, alternative libre à github installable chez soi ou utilisable en tant que service. Il a énormément de fonctionnalités: gestion du https avec letsencrypt, embarque sa BDD Postgresql, du CI avec des runnners, des issues, un registry Docker, et même de la métrologie... le tout avec une interface graphique intuitive et bien léchée.

Le problème de gitlab, c'est qu'il est monolithique et gourmand. Trop gourmand. J'ai installé une instance de gitlab-ce sur un serveur équipé de 2G de RAM, et au bout de quelques jours des erreurs 502 sont apparues. En me connectant sur le serveur j'ai constaté qu'il était quasi saturé: 1,7G ! Et en effet, après avoir consulté la page des requirements, j'a rapidement compris. Le minimum du minimum, c'est 4G de RAM + 4G de swap! Et la recommandation est de 8G!

Pour un usage perso, il est quand même ennuyeux de devoir louer un VPS à 8G de RAM, c'est pas donné, on tape dans la dizaine d'euros par mois voire plus. J'ai essayé quelques optimisations, comme diminuer le nombre de workers, le cache Postgresql, la métrologie... et après un redémarrage je suis à 1,5G de RAM.

Memoire Gitlab

Moui, ce n'est pas une franche réussite. Au moindre pic de consommation le serveur va ookill des processus. Gitlab est cool mais c'est un peu une usine à gaz en terme de ressources.

Même si je suis toujours fan de Gitlab et le recommande pour les entreprises et les organisations, je vais me mettre en recherche d'une alternative plus propice aux usages persos.

Thank you debops (advanced Ansible tricks)

Rédigé par uTux Aucun commentaire

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

Ansible filter by Azure tag

Rédigé par uTux Aucun commentaire

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

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.

Fil RSS des articles de cette catégorie