Comment utiliser l’API v2 DigitalOcean avec Ansible 2.0 sur Ubuntu 16.04

[.Attention]##

Status: obsolète

Cet article est obsolète et n'est plus maintenu.

Raison

Cet article s'appuie sur un projet,dopy, qui n'est plus maintenu.

Voir plutôt

Cet article peut toujours être utile comme référence, mais peut ne pas fonctionner ou suivre les meilleures pratiques. Nous vous recommandons fortement d'utiliser un article récent écrit pour le système d'exploitation que vous utilisez.

introduction

Ansible 2.0 prend en chargeversion 2 of the DigitalOcean API, ce qui signifie que vous pouvez utiliser Ansible non seulement pour provisionner vos applications Web, mais également pour provisionner et gérer automatiquement vos Droplets.

Alors que DigitalOcean fournit une interface Web simple pour la configuration de clés SSH et la création de Droplets, il s’agit d’un processus manuel que vous devez suivre chaque fois que vous souhaitez configurer un nouveau serveur. Lorsque votre application se développe pour inclure un plus grand nombre de serveurs et nécessite une capacité de croissance et de réduction à la demande, vous ne devez plus vous préoccuper de la création et de la configuration manuelles des scripts de déploiement d'applications pour chaque serveur.

L’utilisation d’un outil de provisioning tel que Ansible présente l’avantage de permettre l’automatisation complète de ce processus. Son lancement est aussi simple qu’une seule commande. Ce tutoriel montrera par exemple comment utiliser la prise en charge de DigitalOcean API v2 par Ansible.

En particulier, ce didacticiel couvrira le processus de configuration d’une nouvelle clé SSH sur un compte DO et la configuration de deux gouttelettes différentes afin qu’elles soient prêtes à être utilisées pour le déploiement de vos applications Web. Après avoir suivi ce didacticiel, vous pourrez modifier et intégrer ces tâches dans vos scripts de déploiement d’applications existants.

Conditions préalables

Ce tutoriel s'appuie sur les connaissances de base d'Ansible, donc si vous êtes nouveau sur Ansible, vous pouvez d'abord lirethis section of the Ansible installation tutorial.

Pour suivre ce tutoriel, vous aurez besoin de:

[[step-1 -—- configuring-ansible]] == Étape 1 - Configuration d'Ansible

Dans cette étape, nous allons configurer Ansible pour communiquer avec l'API DigitalOcean.

En règle générale, Ansible utilise simplement SSH pour se connecter à différents serveurs et exécuter des commandes. Cela signifie que la configuration nécessaire pour commencer à utiliser Ansible est généralement la norme pour tous les modules. Cependant, étant donné que la communication avec l’API DigitalOcean n’est pas simplement une commande de shell SSH, nous devons procéder à une petite configuration supplémentaire. Le module Pythondopy (DigitalOcean API Python Wrapper) est ce qui permettra à Ansible de communiquer avec l'API.

Pour installerdopy, installez d'abord le gestionnaire de packages Pythonpip.

sudo apt-get install python-pip

Ensuite, installezdopy en utilisantpip.

sudo pip install dopy

Ensuite, nous allons créer un nouveau répertoire dans lequel travailler et garder les choses en ordre, et nous allons configurer un fichier de configuration de base Ansible.

Par défaut, Ansible utilise un fichier d'hôtes situé à/etc/ansible/hosts, qui contient tous les serveurs qu'il gère. Bien que ce fichier convient à certains cas d’utilisation, il est global. Il s’agit d’une configuration globale, ce qui convient dans certains cas, mais nous utiliserons un fichier hosts local dans ce tutoriel. De cette manière, nous ne casserons pas accidentellement les configurations existantes que vous pourriez avoir lors de l’apprentissage et du test de la prise en charge de l’API DO de Ansible.

Créez et déplacez-vous dans un nouveau répertoire, que nous utiliserons pour la suite de ce tutoriel.

mkdir ~/ansible-do-api
cd ~/ansible-do-api/

Lorsque vous exécutez Ansible, il recherche un fichieransible.cfg dans le répertoire où il est exécuté et s’il en trouve un, il appliquera ces paramètres de configuration. Cela signifie que nous pouvons facilement remplacer des options, telles que l'optionhostfile, pour chaque cas d'utilisation individuel.

Créez un nouveau fichier appeléansible.cfg et ouvrez-le pour le modifier à l'aide denano ou de votre éditeur de texte préféré.

nano ansible.cfg

Collez ce qui suit dansansible.cfg, puis enregistrez et fermez le fichier.

Mise à jour ansible.cfg

[defaults]
hostfile = hosts

La définition de l'optionhostfile dans le groupe[defaults] indique à Ansible d'utiliser un fichier d'hôtes particulier au lieu du fichier global. Ceansible.cfg indique à Ansible de rechercher un fichier hôte appeléhosts dans le même répertoire.

Ensuite, nous allons créer le fichierhosts.

nano hosts

Comme nous ne traiterons que de l'API DigitalOcean dans ce didacticiel, nous pouvons dire à Ansible de s'exécuter surlocalhost, ce qui simplifie les choses et supprime le besoin de se connecter à un hôte distant. Cela peut être fait en disant à Ansible d'utiliserlocalhost et en spécifiant lesansible_connection commelocal. Collez le code ci-dessous danshosts, puis enregistrez et fermez le fichier.

Fichier d'hôtes mis à jour

[digitalocean]
localhost ansible_connection=local

Enfin, nous utiliserons le jeton d'API créé dans les conditions préalables pour permettre à Ansible de communiquer avec l'API DigitalOcean. Il y a trois façons de dire à Ansible à propos du jeton de l'API:

  1. Fournissez-le directement sur chaque tâche DigitalOcean, en utilisant le paramètreapi_token.

  2. Définissez-la comme variable dans le playbook ou le fichier hosts, et utilisez cette variable pour le paramètreapi_token.

  3. Exportez-le en tant que variable d'environnement, en tant queDO_API_TOKEN ouDO_API_KEY.

L'option 1 est l'approche la plus directe et peut sembler intéressante si vous ne souhaitez pas créer de variables. Cependant, cela signifie que le jeton de l'API devra être copié dans chaque tâche pour laquelle il est utilisé. Plus important encore, cela signifie que si cela change jamais, vous devez en trouver toutes les instances et les remplacer.

L'option 2 nous permet de définir le jeton de l'API directement dans notre playbook, comme l'option 1. Contrairement à l'option 1, nous le définissons à un seul endroit en utilisant une variable, ce qui est plus pratique et plus facile à mettre à jour. Nous allons utiliser l'option 2 pour ce tutoriel car c'est l'approche la plus simple.

Toutefois, l’option 3 est la meilleure méthode de protection de votre jeton d’API, car il est beaucoup plus difficile de le valider par inadvertance dans un référentiel (qui peut être partagé avec qui que ce soit). Cela permet de configurer le jeton au niveau du système et de travailler sur différents playbooks sans avoir à inclure le jeton dans chacun d'eux.

Créez un playbook de base appelédigitalocean.yml.

nano digitalocean.yml

Collez le code suivant dans le fichier, en veillant à le remplacer dans votre jeton d'API.

Digitalocean.yml mis à jour

---
- hosts: digitalocean

  vars:
    do_token: your_API_token

  tasks:

Vous pouvez laisser ce fichier ouvert dans votre éditeur, car nous continuerons de l’utiliser à l’étape suivante.

[[step-2 -—- setting-up-an-ssh-key]] == Étape 2 - Configuration d'une clé SSH

Dans cette étape, nous allons créer une nouvelle clé SSH sur votre serveur et l'ajouter à votre compte DigitalOcean à l'aide de Ansible.

La première chose à faire est de s’assurer que l’utilisateur dispose d’une paire de clés SSH, que nous pouvons transmettre à DigitalOcean afin qu’elle puisse être installée par défaut sur vos nouvelles Droplets. Bien que cela soit facile à faire via la ligne de commande, nous pouvons le faire tout aussi facilement avec le moduleusers dans Ansible. L'utilisation d'Ansible permet également de s'assurer que la clé existe avant de l'utiliser, ce qui peut éviter des problèmes lors de l'exécution du livre de lecture sur différents hôtes.

Dans votre playbook, ajoutez la tâcheuser ci-dessous, que nous pouvons utiliser pour nous assurer qu'une clé SSH existe, puis enregistrez et fermez le fichier.

Digitalocean.yml mis à jour

---
- hosts: digitalocean

  vars:
    do_token: your_API_token

  tasks:

  - name: ensure ssh key exists
    user: >
      name={{ ansible_user_id }}
      generate_ssh_key=yes
      ssh_key_file=.ssh/id_rsa

[.note] #Vous pouvez changer le nom de la clé si vous souhaitez utiliser autre chose que~/.ssh/id_rsa.
#

Lancez votre playbook.

ansible-playbook digitalocean.yml

Le résultat devrait ressembler à ceci:

Sortie

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [ensure ssh key exists] ***************************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0

Lorsque cela est terminé, vous pouvez vérifier manuellement que la clé existe en lançant:

ls -la ~/.ssh/id_rsa*

Il listera tous les fichiers qui correspondent àid_rsa*. Vous devriez voirid_rsa etid_rsa.pub répertoriés, indiquant que votre clé SSH existe.

Ensuite, nous allons insérer la clé dans votre compte DigitalOcean. Ouvrez donc votre Playbook pour le modifier.

nano digitalocean.yml

Nous utiliserons le module Ansibledigital_ocean pour télécharger votre clé SSH. Nous enregistrerons également la sortie de la tâche en tant que variablemy_ssh_key car nous en aurons besoin pour une étape ultérieure.

Ajoutez la tâche au bas du fichier, puis enregistrez et fermez le fichier.

Digitalocean.yml mis à jour

---
. . .
  - name: ensure ssh key exists
    user: >
      name={{ ansible_user_id }}
      generate_ssh_key=yes
      ssh_key_file=.ssh/id_rsa

  - name: ensure key exists at DigitalOcean
    digital_ocean: >
      state=present
      command=ssh
      name=my_ssh_key
      ssh_pub_key={{ lookup('file', '~/.ssh/id_rsa.pub') }}
      api_token={{ do_token }}
    register: my_ssh_key

[.note] #Si vous avez nommé votre clé autre queid_rsa, assurez-vous de mettre à jour le nom dans la lignessh_pub_key dans cette tâche.
#

Nous utilisons ici un certain nombre d'options différentes du moduledigital_ocean:

  • state - Cela peut être présent, actif, absent ou supprimé. Dans ce cas, nous voulonspresent, car nous voulons que la clé SSH soit présente dans le compte.

  • command - Il s'agit de la gouttelette ou de ssh. Nous voulonsssh, ce qui nous permet de gérer l'état des clés SSH au sein du compte.

  • name - Ceci est le nom sous lequel enregistrer la clé SSH, il doit être unique et sera utilisé pour identifier votre clé via l'API et l'interface Web.

  • ssh_pub_key - Ceci est votre clé publique SSH, qui sera la clé dont nous avons assuré l'existence en utilisant le module utilisateur.

  • api_token - Ceci est votre jeton API DigitalOcean, que nous avons accessible en tant que variable (do_token, défini dans la sectionvars).

Maintenant, lancez votre playbook.

ansible-playbook digitalocean.yml

Le résultat devrait ressembler à ceci:

Sortie

. . .

TASK [ensure key exists at digital ocean] **************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0

Lorsque cela est terminé, vous pouvez vérifier manuellement que votre clé SSH existe dans votre compte DigitalOcean en allant dans le panneau de configuration, en cliquant surSettings (depuis le menu engrenage), puis surSecurity (dans leUser) s dans la barre latérale gauche). Vous devriez voir votre nouvelle clé répertoriée sousSSH Keys.

[[step-3 -—- creating-a-new-droplet]] == Étape 3 - Création d'une nouvelle droplet

Dans cette étape, nous allons créer un nouveau Droplet.

Nous avons brièvement abordé le moduledigital_ocean à l'étape 2. Nous allons utiliser un ensemble d'options différent pour ce module à cette étape:

  • command - Nous avons utilisé cette option à l'étape précédente avec`+ssh+; cette fois, nous l'utiliserons avecdroplet pour gérer les Droplets via ce module.

  • state - Nous l'avons également utilisé à l'étape précédente; ici, il représente l'état du Droplet, que nous voulons êtrepresent.

  • image_id - Il s'agit de l'image à utiliser pour le nouveau Droplet, commeubuntu-16-04-x64.

  • name - Il s'agit du nom d'hôte à utiliser lors de la création du droplet.

  • region_id - C'est la région dans laquelle créer la gouttelette, commeNYC3.

  • size_id - Il s'agit de la taille de la goutte que nous voulons créer, comme512mb.

  • sshkeyids - Il s'agit de l'ID de clé SSH (ou ID) à définir sur le serveur lors de sa création.

Il existe de nombreuses autres options que celles décrites dans ce didacticiel (toutes disponibles à la page de documentation Ansible), mais en utilisant ces options comme guide, nous pouvons écrire votre nouvelle tâche.

Ouvrez votre livre de jeu pour le modifier.

nano digitalocean.yml

Mettez à jour votre Playbook avec la nouvelle tâche surlignée en rouge ci-dessous, puis enregistrez et fermez le fichier. Vous pouvez modifier des options telles que la taille, la région et l’image en fonction de votre application. Les options ci-dessous créeront un serveur Ubuntu 16.04 de 512 Mo nommédroplet-one à l'aide de la clé SSH que nous avons créée à l'étape précédente.

Digitalocean.yml mis à jour

. . .
      api_token={{ do_token }}
    register: my_ssh_key

  - name: ensure droplet one exists
    digital_ocean: >
      state=present
      command=droplet
      name=droplet-one
      size_id=512mb
      region_id=sgp1
      image_id=ubuntu-16-04-x64
      ssh_key_ids={{ my_ssh_key.ssh_key.id }}
      api_token={{ do_token }}
    register: droplet_one

  - debug: msg="IP is {{ droplet_one.droplet.ip_address }}"

Notez que nous utilisons{{ my_ssh_key.ssh_key.id }} pour récupérer l'ID de la clé SSH précédemment configurée et le transmettre à votre nouveau Droplet. Cela fonctionne si la clé SSH est nouvellement créée ou si elle existe déjà.

Maintenant, lancez votre playbook. L'exécution nécessitera un peu plus de temps qu'auparavant, car elle créerait un droplet.

ansible-playbook digitalocean.yml

Le résultat devrait ressembler à ceci:

. . .

TASK [ensure key exists at DigitalOcean] **************************************
ok: [localhost]

TASK [ensure droplet one exists] ******************************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "IP is 111.111.111.111"
}

PLAY RECAP *********************************************************************
localhost                  : ok=5    changed=1    unreachable=0    failed=0

Ansible nous a fourni l'adresse IP du nouveau Droplet dans le message de retour. Pour vérifier qu’il fonctionne, vous pouvez vous y connecter directement à l’aide de SSH.

Cela devrait vous connecter à votre nouveau serveur (à l'aide de la clé SSH que nous avons créée sur votre serveur Ansible à l'étape 2). Vous pouvez ensuite revenir à votre serveur Ansible en appuyant surCTRL+D.

[[step-4 -—- assurant-qu'une-gouttelette-existe]] == Étape 4 - Vérification de l'existence d'une gouttelette

Au cours de cette étape, nous discuterons du concept d’idempotence et de la manière de mettre en service des gouttelettes avec Ansible.

Ansible vise à utiliser le concept d’idempotence. Cela signifie que vous pouvez exécuter les mêmes tâches plusieurs fois et que les modifications ne doivent être apportées que lorsqu'elles sont nécessaires, ce qui est généralement la première fois qu'elle est exécutée. Cette idée correspond bien au provisioning de serveurs, à l'installation de packages et à d'autres tâches d'administration du serveur.

Si vous exécutez à nouveau votre playbook (ne le faites pas encore!), Étant donné la configuration actuelle, il continuera et fournira un deuxième Droplet également appelédroplet-one. Exécutez-le à nouveau, et il fera un troisième Droplet. Cela est dû au fait que DigitalOcean autorise plusieurs gouttelettes portant le même nom. Pour éviter cela, nous pouvons utiliser le paramètreunique_name.

Le paramètreunique_name indique à Ansible et DigitalOcean que vous souhaitez des noms d'hôte uniques pour vos serveurs. Cela signifie que lorsque vous relancerez votre playbook, il respectera idempotence et considérera le droplet déjà configuré, et ne créera donc pas de second serveur du même nom.

Ouvrez votre livre de jeu pour le modifier:

nano digitalocean.yml

Ajoutez le paramètreunique_name:

Digitalocean.yml mis à jour

. . .
  - name: ensure droplet one exists
    digital_ocean: >
      state=present
      command=droplet
      name=droplet-one
      unique_name=yes
      size_id=512mb
. . .

Enregistrez et lancez votre playbook:

ansible-playbook digitalocean.yml

La sortie ne devrait entraîner aucune modification des tâches, mais vous remarquerez que la sortie de débogage avec l'adresse IP est toujours affichée. Si vous vérifiez votre compte DigitalOcean, vous remarquerez qu'un seul Dropletdroplet-one a été provisionné.

[[step-5 -—- creation-a-second-droplet]] == Étape 5 - Création d'une seconde droplet

Dans cette étape, nous allons répliquer notre configuration existante pour mettre en place un droplet séparé.

Pour approvisionner un Droplet distinct, il suffit de répliquer la tâche Ansible à partir de notre premier Droplet. Cependant, pour rendre notre livre de jeu un peu plus robuste, nous allons le convertir en utilisant une liste de droplets à approvisionner, ce qui nous permet d’agrandir facilement notre flotte si nécessaire.

Premièrement, nous devons définir notre liste de gouttelettes.

Ouvrez votre livre de jeu pour le modifier:

nano digitalocean.yml

Ajoutez une liste de noms de droplet à provisionner dans la sectionvars.

Digitalocean.yml mis à jour

---
- hosts: digitalocean

  vars:
    do_token: 
    droplets:
    - droplet-one
    - droplet-two

  tasks:
. . .

Ensuite, nous devons mettre à jour notre tâche pour parcourir la liste des droplets, vérifier s’ils existent, puis enregistrer les résultats dans une variable. Ensuite, nous devons également modifier nos tâchesdebug pour afficher les informations stockées dans la variable pour chaque élément.

Pour ce faire, mettez à jour la tâcheensure droplet one exists dans votre playbook comme ci-dessous:

Digitalocean.yml mis à jour

. . .
  - name: ensure droplets exist
    digital_ocean: >
      state=present
      command=droplet
      name={{ item }}
      unique_name=yes
      size_id=512mb
      region_id=sgp1
      image_id=ubuntu-16-04-x64
      ssh_key_ids={{ my_ssh_key.ssh_key.id }}
      api_token={{ do_token }}
    with_items: droplets
    register: droplet_details

  - debug: msg="IP is {{ item.droplet.ip_address }}"
    with_items: droplet_details.results

Enregistrez et lancez votre livre de jeu.

ansible-playbook digitalocean.yml

Les résultats devraient ressembler à ceci:

Sortie

. . .
TASK [ensure droplets exists] **************************************************
ok: [localhost] => (item=droplet-one)
changed: [localhost] => (item=droplet-two)

TASK [debug] *******************************************************************

. . .

"msg": "IP is 111.111.111.111"

. . .

"msg": "IP is 222.222.222.222"
}

PLAY RECAP *********************************************************************
localhost                  : ok=5    changed=1    unreachable=0    failed=0

Vous remarquerez peut-être que la sortiedebug contient beaucoup plus d'informations que la première fois. Ceci est dû au fait que le moduledebug imprime des informations supplémentaires pour aider au débogage; c'est un petit inconvénient de l'utilisation de variables enregistrées avec ce module.

En dehors de cela, vous verrez que notre deuxième Droplet a été provisionné, alors que notre premier était déjà en cours d'exécution. Vous avez maintenant configuré deux gouttelettes DigitalOcean en utilisant uniquement Ansible!

Supprimer vos gouttelettes est tout aussi simple. Le paramètre state de la tâche indique à Ansible dans quel état doit se trouver Droplet. Le définir surpresent garantit que le droplet existe, et il sera créé s'il n’existe pas déjà; le définir surabsent garantit que la gouttelette avec le nom spécifiénot existe, et elle supprimera toutes les gouttelettes correspondant au nom spécifié (tant queunique_name est défini).

Si vous souhaitez supprimer les deux exemples de droplets que vous avez créés dans ce didacticiel, changez simplement l'état de la tâche de création enabsent et relancez votre playbook.

Digitalocean.yml mis à jour

. . .
  - name: ensure droplets exist
    digital_ocean: >
      state=absent
      command=droplet
. . .

Vous pouvez également vouloir supprimer la ligne de débogage avant de réexécuter votre playbook. Sinon, vos gouttelettes seront toujours supprimées, mais vous verrez une erreur dans la commande debug (car il n’ya pas d’adresses IP à renvoyer).

ansible-playbook digitalocean.yml

Maintenant, vos deux exemples de gouttelettes seront supprimés.

Conclusion

Ansible est un outil de provisioning incroyablement puissant et très flexible. Vous avez constaté à quel point il est facile de mettre à disposition (et de supprimer) des droplets à l'aide de l'API DigitalOcean à l'aide des concepts Ansible standard et des modules intégrés.

Le paramètre state, qui a été défini surpresent, indique à Ansible dans quel état le Droplet doit être. Le définir surpresent garantit que le droplet existe, et il sera créé s'il n’existe pas déjà; le définir surabsent indique à Ansible de s'assurer que le droplet avec le nom spécifiénot existe, et il supprimera tous les droplets correspondant au nom spécifié (tant queunique_name est défini).

À mesure que votre nombre de gouttelettes que vous gérez augmente, la possibilité d'automatiser le processus vous fera gagner du temps pour la création, la configuration et la destruction de gouttelettes dans le cadre d'un processus automatisé. Vous pouvez adapter et développer les exemples de ce tutoriel pour améliorer vos scripts de provisioning personnalisés en fonction de votre configuration.

Related