OpenStack + Terraform : Connecter deux routeurs à un réseau

Soit l’architecture suivante, composée de deux routeurs router_interne et router_dmz connectés à un unique réseau network_dmz :

Capture d_écran 2017-12-06 à 10.40.23

Pour déployer ce schéma avec Terraform et OpenStack, on pourrait penser à utiliser simplement des ressources openstack_networking_router_interface_v2 :

resource "openstack_networking_router_interface_v2" "router_interface_dmz" {
  router_id = "${openstack_networking_router_v2.router_dmz.id}"
  subnet_id = "${openstack_networking_subnet_v2.subnet_dmz.id}"
}

resource "openstack_networking_router_interface_v2" "router_interface_dmz_interne" {
  router_id = "${openstack_networking_router_v2.router_interne.id}"
  subnet_id = "${openstack_networking_subnet_v2.subnet_dmz.id}"
}

Seulement voilà, ça ne fonctionnera pas :

* openstack_networking_router_interface_v2.router_interface_dmz: Error creating OpenStack Neutron router interface: Expected HTTP response code [200] when accessing [PUT http://openstack:9696/v2.0/routers/c33fd7ee-43ab-41ea-a12b-2067760540eb/add_router_interface%5D, but got 409 instead
{« NeutronError »: {« message »: « IP address 192.168.0.1 already allocated in subnet 9610ea1a-e9fd-4c63-bedd-da9f80219038 », « type »: « IpAddressAlreadyAllocated », « detail »: «  »}}

En effet, utiliser openstack_networking_router_interface_v2 avec router_id + subnet_id définit automatiquement le routeur comme gateway… et il ne peut y avoir qu’une seule gateway.

Solution, passer par des ports avec des IP fixes (ou pas) :

resource "openstack_networking_port_v2" "port_dmz" {
  network_id = "${openstack_networking_network_v2.network_dmz.id}"
  admin_state_up = "true"
  fixed_ip {
    subnet_id = "${openstack_networking_subnet_v2.subnet_dmz.id}"
    ip_address = "192.168.0.254"
  }
}

resource "openstack_networking_port_v2" "port_dmz_interne" {
  network_id = "${openstack_networking_network_v2.network_dmz.id}"
  admin_state_up = "true"
  fixed_ip {
    subnet_id = "${openstack_networking_subnet_v2.subnet_dmz.id}"
    ip_address = "192.168.0.253"
  }
}

resource "openstack_networking_router_interface_v2" "router_interface_dmz" {
  router_id = "${openstack_networking_router_v2.router_dmz.id}"
  port_id = "${openstack_networking_port_v2.port_dmz.id}"
}

resource "openstack_networking_router_interface_v2" "router_interface_dmz_interne" {
  router_id = "${openstack_networking_router_v2.router_interne.id}"
  port_id = "${openstack_networking_port_v2.port_dmz_interne.id}"
}

nfsd + Vagrant : Can’t export : No such file or directory (2)

Depuis quelques jours, je voyais régulièrement dans les logs d’OS X Sierra le message d’erreur suivant revenant plusieurs fois par seconde :

09:42:57.473404 +0100 nfsd Can’t export /Users/simon/Documents/tests/rundeck: No such file or directory (2)

Ce répertoire était exposé via un partage NFS dans une VM VirtualBox / Vagrant comme on peut le voir en regardant /etc/exports :

cat /etc/exports
# VAGRANT-BEGIN: 347515540 d60690ec-3e66-462b-8cd6-555fd15b3061
"/Users/simon/Documents/tests/rundeck" 172.28.128.3 -alldirs -mapall=347515540:2018407520
# VAGRANT-END: 347515540 d60690ec-3e66-462b-8cd6-555fd15b3061

Pour corriger l’erreur directement, j’ai carrément vidé le fichier :

cat /dev/null | sudo tee /etc/exports

Bien entendu, si d’autres partages sont présents, n’effacez que les lignes concernées…

Cloner tous les repos d’une organisation sur Github

Je cherchais un moyen rapide de cloner tous les repos publics d’une organisation sur Github. D’autres se sont bien sûr posés la question mais les solutions proposées m’ont toutes semblées trop complexes / tordues.

Résultat, j’ai fait la mienne :

bash -x <(curl -s "https://api.github.com/orgs/alphagov/repos" | jq -r '.[].git_url | "git clone " + sub("git://"; "https://")')

L’organisation est ici alphagov, à remplacer évidemment.

Il y a trois étapes :

  1. curl -s "https://api.github.com/orgs/alphagov/repos" récupère la liste des repos de l’organisation au format JSON. Il y a pas mal d’informations dedans (toutes les URLs, nombre de forks, de watchers, etc.).
  2. On passe à jq, un outil (très puissant) en ligne de commande pour parser du JSON qui a son propre langage.
    1. .[].git_url indique de conserver uniquement l’URL du repo. Ce qui donne :
      $ curl -s "https://api.github.com/orgs/alphagov/repos" | jq -r '.[].git_url'
      git://github.com/alphagov/static.git
      git://github.com/alphagov/slimmer.git
      (...)
      
    2. sub("git://"; "https://") permet ainsi de remplacer les git:// par des https:// car je ne suis pas authentifié sur Github. Ce qui donne :
      $ curl -s "https://api.github.com/orgs/alphagov/repos" | jq -r '.[].git_url | "git clone " + sub("git://"; "https://")'
      git clone https://github.com/alphagov/static.git
      git clone https://github.com/alphagov/slimmer.git
      (...)
      
  3. Le tout est envoyé en entrée à bash qui va exécuter les commandes et cloner tous les répertoires !

Bonus : Pourquoi alphagov ? Car c’est une très bonne source d’inspiration tant en Ruby (la plupart sont des applications Rails) qu’en Puppet et en Terraform (ici et ici).

Installer Terraform avec Homebrew et chtf

Yleisradio propose sur Github un utilitaire dénommé chtf pour gérer plusieurs versions de Terraform, un peu à la façon de RVM. Il est fourni à travers une formule + un repo Homebrew.

Installation de chtf

On commence par ajouter le repository :

brew tap Yleisradio/terraforms

Installation proprement dite de chtf :

brew install chtf

Sortie :

Add the following to the ~/.bashrc or ~/.zshrc file:

    source /usr/local/opt/chtf/share/chtf/chtf.sh

Then you can choose (and automatically install) a specified Terraform
version, e.g.:

    chtf 0.6.8

A ajouter dans son .bash_profile :

[[ -s "/usr/local/share/chtf/chtf.sh" ]] && source "/usr/local/share/chtf/chtf.sh"

Utilisation

Pour lister les versions disponibles :

chtf_install

Sortie :

chtf: Installing Terraform version 
Error: Cask 'terraform-' is unavailable: No Cask with this name exists. Did you mean one of these?
terraform-0.10.0           terraform-0.10.0-rc1       terraform-0.10.3           terraform-0.10.6           terraform-0.11.0-beta1     terraform-0.6.12           terraform-0.6.14+cf
terraform-0.10.0-beta1     terraform-0.10.1           terraform-0.10.4           terraform-0.10.7           terraform-0.6.10           terraform-0.6.13           terraform-0.6.15
terraform-0.10.0-beta2     terraform-0.10.2           terraform-0.10.5           terraform-0.10.8           terraform-0.6.11           terraform-0.6.14

Ne reste plus qu’à en installer une, ici la dernière en date :

chtf_install 0.10.8
chtf: Installing Terraform version 0.10.8
==> Satisfying dependencies
==> Downloading https://releases.hashicorp.com/terraform/0.10.8/terraform_0.10.8_darwin_amd64.zip
######################################################################## 100,0%
==> Verifying checksum for Cask terraform-0.10.8
==> Installing Cask terraform-0.10.8
==> Extracting nested container terraform
🍺  terraform-0.10.8 was successfully installed!

La commande chtf retourne les versions installées :

$ chtf
 * 0.10.8
   0.6.15

Le choix se fait avec chtf_use [la version] :

chtf_use 0.10.8

Démonstration :

$ chtf_use 0.10.8 && terraform version
Terraform v0.10.8

$ chtf_use 0.6.15 && terraform version
Terraform v0.6.15

Your version of Terraform is out of date! The latest version
is 0.10.8. You can update by downloading from www.terraform.io

Attention : contrairement à RVM, il n’y a pas de version par défaut de Terraform. Si on ouvre un nouveau shell, il faut refaire un chtf_use sinon la commande n’existe pas.

Voir le changelog d’un package avec DNF (Fedora)

Pour voir le changelog (nouveautés) d’un package sous Fedora 22+ :

dnf updateinfo --info --refresh [nom du package]

Exemple avec libreoffice-core :

$ dnf updateinfo --info --refresh libreoffice-core
===============================================================================
  libreoffice-5.3.6.1-4.fc26
===============================================================================
ID de mise à jour : FEDORA-2017-76f5e02c37
             Type : correction d’anomalie
      Mis à jour  : 2017-09-09 22:54:31
      Description : - tdf#110737 animations starved of redraw events in dual head mode
                  : - fix redraw of embedded calc in writer

L’argument --refresh force DNF à récupérer les informations sur le repo (dnf update ne le fait pas).

Remplacer --info par --list pour avoir quelque chose de plus synthétique :

$ dnf updateinfo --list --refresh libreoffice-core
FEDORA-2017-76f5e02c37 correction d’anomalie libreoffice-core-1:5.3.6.1-4.fc26.x86_64

A noter que le package yum-changelog est toujours proposé dans les repos Fedora 26 mais que son installation n’est pas nécessaire, updateinfo fait parti intégrante de dnf.

epp(): Invalid EPP: This Variable has no effect. A value was produced and then forgotten

Contexte : Puppet 5.1.0, template au format EPP

Message d’erreur à l’exécution :

Error: Evaluation Error: Error while evaluating a Function Call, epp(): Invalid EPP: This Variable has no effect. A value was produced and then forgotten (one or more preceding expressions may have the wrong form) at /opt/puppetlabs/puppet/modules/monitoring/templates/mongodb.epp:11:98

Cette erreur cryptique indique qu’une variable dans le template EPP ne sert pas.

Exemple :

<% $user %>

$user n’est ni affichée (ce serait ), ni dans une condition ni utilisée pour une boucle.

La plupart du temps, c’est afficher la variable que l’on souhaite, ne manque donc que le = :

<%= $user %>