cogini.elixir-release

elixir-release

Ce rôle Ansible déploie des versions d'Elixir/Phoenix.

Il utilise les "versions" d'Erlang avec systemd pour la supervision des processus, comme décrit dans "Déployer des applications Elixir avec Ansible" et "Meilleures pratiques pour déployer des applications Elixir".

Structure du répertoire

Il utilise une structure similaire à Capistrano pour gérer les fichiers de version. Le répertoire de base est nommé pour l'application, par exemple /srv/foo, avec un répertoire releases en dessous. Lorsque le rôle déploie une version, il crée un répertoire nommé par un timestamp, par exemple /srv/foo/releases/20190603T072116. Il décompresse les fichiers à l'intérieur, crée un lien symbolique de /srv/foo/current vers le nouveau répertoire.

Redémarrage

Après avoir déployé la version, il redémarre l'application pour la mettre en ligne.

Par défaut, lorsque elixir_release_restart_method: systemctl, cela se fait en exécutant :

sudo /bin/systemctl restart foo

Le compte utilisateur déployé doit avoir des permissions suffisantes pour redémarrer l'application. Au lieu de donner tous les droits sudo au compte de déploiement, un fichier de configuration sudo spécifique à l'utilisateur précise quelles commandes il peut exécuter, par exemple /etc/sudoers.d/deploy-foo:

deploy ALL=(ALL) NOPASSWD: /bin/systemctl start foo, /bin/systemctl stop foo, /bin/systemctl restart foo

Il est préférable de ne pas nécessiter de permissions sudo du tout. Une option est de tirer parti de systemd pour redémarrer l'application.

Définissez elixir_release_restart_method: systemd_flag, le processus de déploiement touche un fichier /srv/foo/flags/restart.flag sur le disque après avoir déployé le code. Systemd le remarque et le redémarre avec le nouveau code.

Voir mix-deploy-example pour un exemple complet.

Exemple de Playbook

Un playbook minimal, pour une application appelée foo :

- hosts: '*'
  become: true
  vars:
    elixir_release_app_name: foo
  roles:
    - cogini.elixir-release

Mettez ceci dans ansible/playbooks/deploy-app.yml.

Tout d'abord, configurez la machine cible, par exemple en installant des paquets et en créant des répertoires. Exécutez ceci depuis votre machine de développement, en spécifiant un utilisateur avec des permissions sudo :

ansible-playbook -u $USER -v -l web_servers playbooks/deploy-app.yml --skip-tags deploy -D

Ensuite, déployez le code. Exécutez ceci depuis le serveur de construction, à partir d'un compte utilisateur ayant un accès ssh au compte de déploiement sur la machine cible :

ansible-playbook -u deploy -v -l web_servers playbooks/deploy-app.yml --tags deploy --extra-vars ansible_become=false -D

Un playbook plus personnalisé :

- hosts: '*'
  become: true
  vars:
    elixir_release_app_name: foo
    elixir_release_app_user: bar
    elixir_release_deploy_user: deploy
    elixir_release_mix_env: frontend
    # elixir_release_release_name: "{{ elixir_release_mix_env }}"
    # elixir_release_release_system: distillery
    # elixir_release_start_command: foreground
    elixir_release_systemd_source: mix_systemd
    elixir_release_base_dir: /opt/bar
    elixir_release_app_dirs:
      - configuration
      - runtime
      - logs
      - tmp
      - state
      - cache
    elixir_release_tmp_directory_base: /var/tmp/bar
    elixir_release_state_directory_base: /var/bar
    elixir_release_http_listen_port: 8080
    elixir_release_cache_directory_mode: 0700
    elixir_release_configuration_directory_mode: 0755
    elixir_release_logs_directory_mode: 0755
    elixir_release_state_directory_mode: 0755
    elixir_release_tmp_directory_mode: 0755
    elixir_release_sudoers_file: "{{ elixir_release_app_user }}-{{ elixir_release_service_name }}"
    # Emplacement de l'application source, en supposant que les scripts de déploiement sont dans un dépôt séparé dans un répertoire parallèle
    elixir_release_src_dir: "{{ playbook_dir }}/../../../foo"
  roles:
    - cogini.elixir-release

Variables du rôle

Système utilisé pour construire des versions, soit "mix" soit "distillery".

elixir_release_release_system: "mix"

Emplacement de l'application pour obtenir les fichiers de version. Par défaut, il suppose que vous avez un répertoire ansible dans votre source d'application.

elixir_release_app_dir: "{{ role_path }}/../../.."

Nom Erlang de l'application, utilisé par Distillery pour nommer les répertoires et les scripts.

elixir_release_app_name: my_app

Nom de la version, par défaut app_name, mais souvent MIX_ENV.

elixir_release_release_name: "{{ elixir_release_app_name }}"

Nom externe de l'application, utilisé pour nommer le service systemd et les répertoires. Par défaut, il convertit les underscores en tirets :

elixir_release_service_name: "{{ elixir_release_app_name | replace('_', '-') }}"

Nom de l'application Elixir. Par défaut, c'est la version CamelCase du nom de l'application :

elixir_release_app_module: "{{ elixir_release_service_name.title().replace('_', '') }}"

Version de l'application à publier. Si non spécifié, il lira à partir du fichier start_erl.data dans le répertoire de version.

elixir_release_version: "0.1.0"

Pour la sécurité, nous utilisons des comptes séparés pour déployer l'application et pour l'exécuter. Le compte de déploiement possède le code et les fichiers de configuration, et a le droit de redémarrer l'application. Nous utilisons normalement un compte séparé appelé deploy. L'application s'exécute sous un compte séparé avec les permissions minimales dont elle a besoin. Nous créons normalement un nom correspondant à l'application, par exemple foo, ou utilisons un nom générique comme app.

Les fichiers de version sont la propriété de deploy:app avec le mode 0644 afin que l'application puisse les lire.

Compte OS qui déploie et possède les fichiers de version :

elixir_release_deploy_user: deploy

Groupe OS qui déploie et possède les fichiers de version :

elixir_release_deploy_group: "{{ elixir_release_deploy_user }}"

Compte OS sous lequel l'application s'exécute :

elixir_release_app_user: "{{ elixir_release_service_name }}"

Groupe OS sous lequel l'application s'exécute :

elixir_release_app_group: "{{ elixir_release_app_user }}"

Environnement de version de l'application, c'est-à-dire le paramètre de MIX_ENV, utilisé pour trouver le fichier de version sous le répertoire _build :

elixir_release_mix_env: prod

Préfixe du répertoire pour les fichiers de version :

elixir_release_base_dir: /srv

Répertoire de base pour les fichiers de déploiement :

elixir_release_deploy_dir: "{{ elixir_release_base_dir }}/{{ elixir_release_service_name }}"

Répertoires sous le répertoire de déploiement.

Emplacement où les archives de version sont décompressées :

elixir_release_releases_dir: "{{ elixir_release_deploy_dir }}/releases"

Version actuellement en cours d'exécution (lien symbolique) :

elixir_release_current_dir: "{{ elixir_release_deploy_dir }}/current"

Emplacement des scripts de déploiement :

elixir_release_scripts_dir: "{{ elixir_release_deploy_dir }}/bin"

Répertoire du fichier de signalisation, utilisé pour signaler un redémarrage :

elixir_release_flags_dir: "{{ elixir_release_deploy_dir }}/flags"

Répertoires où l'application conserve ses fichiers, suivant systemd.

elixir_release_app_dirs:
  - configuration
  - runtime
  # - logs
  # - tmp
  # - state
  # - cache

Utiliser conform :

elixir_release_conform: false
elixir_release_conform_conf_path: "{{ elixir_release_configuration_dir }}/config.conform"

Comment redémarrer l'application :

elixir_release_restart_method: systemctl
# elixir_release_restart_method: systemd_flag
# elixir_release_restart_method: touch

Les options sont :

  • systemctl, qui exécute systemctl restart foo
  • systemd_flag, qui touche le fichier {{ elixir_release_shutdown_flags_dir }}/restart.flag
  • touch, qui touche le fichier {{ elixir_release_shutdown_flags_dir }}/restart.flag. Les permissions du répertoire sont de 0770, permettant au processus géré de redémarrer lui-même.

Quels utilisateurs sont autorisés à redémarrer l'application en utilisant sudo /bin/systemctl restart lorsque la méthode == systemctl.

elixir_release_restart_users:
    - "{{ elixir_release_deploy_user }}"

Définissez sur [] et personne ne pourra redémarrer, ou ajoutez d'autres noms, par exemple - "{{ elixir_release_app_user }}".

systemd et scripts

Par défaut, ce rôle suppose que vous utilisez mix_systemd pour générer le fichier unitaire systemd et mix_deploy pour générer les scripts de cycle de vie.

elixir_release_systemd_source contrôle la source du fichier unitaire systemd.

elixir_release_systemd_source: mix_systemd

Avec la valeur par défaut de mix_systemd, le rôle copie les fichiers unitaires systemd du répertoire _build/{{ elixir_release_mix_env }}/systemd. Réglez-le sur self, et ce rôle générera un fichier unitaire systemd à partir d'un modèle.

elixir_release_scripts_source contrôle la source des scripts.

elixir_release_scripts_source: bin

Avec la valeur par défaut de bin, le rôle copie des scripts du répertoire bin du projet vers /srv/foo/bin sur le système cible. Réglez-le sur mix_deploy si vous avez défini output_dir_per_env: true dans la configuration mix_deploy, stockant les scripts générés sous _build.

Les variables suivantes sont utilisées lors de la génération du fichier unitaire systemd :

Port sur lequel l'application écoute les connexions HTTP :

elixir_release_http_listen_port: 4000

Port sur lequel l'application écoute les connexions HTTPS :

elixir_release_https_listen_port: 4001

Limite de fichiers ouverts :

elixir_release_limit_nofile: 65536

Secondes à attendre entre les redémarrages :

elixir_release_systemd_restart_sec: 5

Variable d'environnement LANG :

elixir_release_lang: "en_US.UTF-8"

umask :

elixir_release_umask: "0027"

Version cible de systemd, utilisée pour activer des fonctionnalités plus avancées :

elixir_release_systemd_version: 219

Type de service systemd : simple | exec | notify | forking Voir systemd Type

Commande de version à exécuter pour démarrer l'application. mix utilise start pour simple, daemon pour forking. distillery utilise foreground pour simple, start pour forking.

elixir_release_start_command: start

Fichier PID lors de l'utilisation du type de service forking :

elixir_release_pid_file: "{{ elixir_release_runtime_dir }}/{{ elixir_release_app_name}}.pid"

Liste des scripts ExecStartPre dans le fichier unitaire systemd :

elixir_release_exec_start_pre: []

Liste des variables d'environnement à définir dans le fichier unitaire systemd :

elixir_release_env_vars: []

Dépendances

Aucune

Exigences

Aucune

Licence

MIT

Informations sur l'auteur

Jake Morrison jake@cogini.com

À propos du projet

Deploy an Elixir app

Installer
ansible-galaxy install cogini.elixir-release
Licence
mit
Téléchargements
108
Propriétaire
Product development services for ambitious innovators