Comment automatiser la configuration du serveur avec Ansible sur Ubuntu 18.04

introduction

Lorsque vous créez un nouveau serveur Ubuntu 18.04 pour la première fois, vous devez suivre quelques étapes de configuration lors de la configuration de base. Cela augmentera la sécurité et la convivialité de votre serveur, en travaillant comme une base solide pour les actions ultérieures.

Bien que vous puissiez exécuter ces étapes manuellement, l’automatisation du processus vous fera gagner du temps et réduira les erreurs humaines. Avec la vulgarisation des applications conteneurisées et des microservices, l’automatisation des serveurs joue désormais un rôle essentiel dans l’administration des systèmes. C'est également un moyen d'établir des procédures standard pour les nouveaux serveurs.

Ce guide explique comment utiliserAnsible pour automatiser les étapes contenues dans nosInitial Server Setup Guide. Ansible est un outil de gestion de configuration moderne qui peut être utilisé pour automatiser le provisioning et la configuration de systèmes distants.

Vérification pré-vol

Pour exécuter la configuration automatisée fournie par le livre de jeu dont nous traitons dans ce guide, vous aurez besoin des éléments suivants:

  • Ansible installé sur votre machine locale ou sur un serveur distant que vous avez configuré en tant queAnsible Control Node. Vous pouvez suivre l'étape 1 du didacticielHow to Install and Configure Ansible on Ubuntu 18.04 pour obtenir cette configuration.

  • Accès racine à un ou plusieurs serveurs Ubuntu 18.04 qui seront gérés par Ansible.

Avant d'exécuter un playbook, il est important de s'assurer qu'Ansible est capable de se connecter à vos serveurs via SSH et d'exécuterAnsible modules à l'aide de Python. Les deux sections suivantes expliquent comment configurer votre inventaire Ansible afin d'inclure vos serveurs et comment exécuter des commandes Ansible ad-hoc pour tester la connectivité et des informations d'identification valides.

Fichier d'inventaire

Leinventory file contient des informations sur les hôtes que vous gérerez avec Ansible. Vous pouvez inclure de un à plusieurs centaines de serveurs dans votre fichier d'inventaire, et les hôtes peuvent être organisés en groupes et sous-groupes. Le fichier d'inventaire est également souvent utilisé pour définir des variables qui ne seront valides que pour certains hôtes et groupes, afin de pouvoir être utilisées dans des playbooks et des modèles. Certaines variables peuvent également affecter la façon dont un playbook est exécuté, comme la variableansible_python_interpreter que nous verrons dans un instant.

Pour inspecter le contenu de votre inventaire Ansible par défaut, ouvrez le fichier/etc/ansible/hosts à l'aide de l'éditeur de ligne de commande de votre choix, sur votre machine locale ou sur un nœud de contrôle Ansible:

sudo nano /etc/ansible/hosts

[.note] #Note: certaines installations Ansible ne créent pas de fichier d'inventaire par défaut. Si le fichier n’existe pas dans votre système, vous pouvez créer un nouveau fichier à/etc/ansible/hosts ou fournir un chemin d’inventaire personnalisé à l’aide du paramètre-i lors de l’exécution de commandes et de playbooks.
#

Le fichier d'inventaire par défaut fourni par l'installation Ansible contient un certain nombre d'exemples que vous pouvez utiliser comme références pour configurer votre inventaire. L'exemple suivant définit un groupe nomméservers avec trois serveurs différents, chacun identifié par un alias personnalisé:server1,server2 etserver3:

/etc/ansible/hosts

[servers]
server1 ansible_host=203.0.113.111
server2 ansible_host=203.0.113.112
server3 ansible_host=203.0.113.113

[servers:vars]
ansible_python_interpreter=/usr/bin/python3

Le sous-groupeserver:vars définit le paramètre d'hôteansible_python_interpreter qui sera valide pour tous les hôtes inclus dans le groupeservers. Ce paramètre garantit que le serveur distant utilise l'exécutable Python 3 de/usr/bin/python3 au lieu de/usr/bin/python (Python 2.7), qui n'est pas présent sur les versions récentes d'Ubuntu.

Pour terminer la configuration de votre fichier d'inventaire, remplacez les adresses IP en surbrillance par les adresses IP de vos serveurs. Lorsque vous avez terminé, enregistrez et fermez le fichier en appuyant surCTRL+X puis sury pour confirmer les modifications, puis surENTER.

Maintenant que votre fichier d’inventaire est prêt, il est temps de tester la connectivité de vos nœuds.

Test de connectivité

Après avoir configuré le fichier d’inventaire pour inclure vos serveurs, il est temps de vérifier si Ansible est capable de se connecter à ces serveurs et d’exécuter des commandes via SSH. Pour ce guide, nous utiliserons le compte Ubunturoot car c'est généralement le seul compte disponible par défaut sur les serveurs nouvellement créés. Ce playbook créera un nouvel utilisateur non root avec les privilègessudo que vous devrez utiliser lors d'interactions ultérieures avec le serveur distant.

Depuis votre machine locale ou votre nœud de contrôle Ansible, exécutez:

ansible -m ping all -u root

Cette commande utilisera lespingAnsible module intégrés pour exécuter un test de connectivité sur tous les nœuds de votre inventaire par défaut, en se connectant en tant queroot. Le moduleping testera:
si les hôtes sont accessibles;
si vous avez des informations d'identification SSH valides;
si les hôtes sont capables d'exécuter des modules Ansible en utilisant Python.

Si, au lieu de l'authentification par clé, vous utilisezpassword-based authentication pour vous connecter à des serveurs distants, vous devez fournir le paramètre supplémentaire-k à la commande Ansible, afin qu'elle vous demande le mot de passe de la connexion utilisateur.

ansible -m ping all -u root -k

[.note] #Note: Gardez à l'esprit que certains serveurs peuvent avoir des mesures de sécurité supplémentaires contre l'authentification par mot de passe en tant qu'utilisateurroot, et dans certains cas, vous devrez peut-être vous connecter manuellement au serveur pour changer le mot de passe root initial.
#

Vous devriez obtenir une sortie semblable à ceci:

Outputserver1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
server2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
server3 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Si vous vous connectez à ces serveurs pour la première fois via SSH, il vous sera demandé de confirmer l’authenticité des hôtes auxquels vous vous connectez via Ansible. Lorsque vous y êtes invité, tapezyes, puis appuyez surEnter pour confirmer.

Une fois que vous recevez une réponse "pong" d'un hôte, cela signifie que vous êtes prêt à exécuter des commandes et des livres de lecture Ansible sur ce serveur.

Que fait ce Playbook?

Ce playbook Ansible offre une alternative à l'exécution manuelle de la procédure décrite dans lesUbuntu 18.04 initial server setup guide et le guide sur lessetting up SSH keys on Ubuntu 18.04.

L'exécution de ce livre de jeu entraînera l'exécution des actions suivantes:

  1. Le groupe administratifwheels est créé puis configuré pourpasswordless sudo.

  2. Un nouvel utilisateur administratif est créé au sein de ce groupe, en utilisant le nom spécifié par la variablecreate_user.

  3. Une clé SSH publique est copiée à partir de l'emplacement défini par la variablecopy_local_key, et ajoutée au fichierauthorized_keys pour l'utilisateur créé à l'étape précédente.

  4. L'authentification par mot de passe est désactivée pour l'utilisateurroot.

  5. L'index du package localapt est mis à jour et les packages de base définis par la variablesys_packages sont installés.

  6. Le pare-feu UFW est configuré pour autoriser uniquement les connexions SSH et refuser toute autre demande.

Pour plus d'informations sur chacune des étapes incluses dans ce manuel, veuillez consulter nosUbuntu 18.04 initial server setup guide.

Une fois le playbook terminé, vous pourrez vous connecter au serveur en utilisant le comptesudo nouvellement créé.

Comment utiliser ce livre de jeu

Pour commencer, nous allons télécharger le contenu desplaybook sur votre nœud de contrôle Ansible. Il peut s’agir de votre ordinateur local ou d’un serveur distant sur lequel vous avez installé Ansible et configuré votre inventaire.

[.note] #Pour votre commodité, le contenu du playbook est également inclus dans unfurther section of this guide.
#

Pour télécharger ce playbook à partir de la ligne de commande, vous pouvez utilisercurl:

curl -L https://raw.githubusercontent.com/do-community/ansible-playbooks/master/initial_server_setup/ubuntu1804.yml -o initial_server_setup.yml

Cela téléchargera le contenu du playbook dans un fichier nomméinitial_server_setup.yml sur votre chemin local actuel. Vous pouvez examiner le contenu du playbook en ouvrant le fichier à l'aide de l'éditeur de ligne de commande de votre choix:

nano initial_server_setup.yml

Une fois que vous avez ouvert le fichier du playbook, vous devriez remarquer une section nomméevars avec trois variables distinctes qui nécessitent votre attention:

  • create_user: le nom du compte d'utilisateur non root auquel créer et accorder des privilèges sudo. Notre exemple utilisesammy, mais vous pouvez utiliser le nom d’utilisateur de votre choix.

  • copy_local_key: chemin local vers une clé publique SSH valide à configurer comme clé autorisée pour le nouveau comptesudo non root. La valeur par défaut pointe vers la clé publique de l'utilisateur local actuel située à~/.ssh/id_rsa.pub.

  • sys_packages: une liste des packages système de base qui seront installés à l'aide de l'outil de gestion de packagesapt.

Une fois que vous avez terminé de mettre à jour les variables dansinitial_server_setup.yml, enregistrez et fermez le fichier.

Vous êtes maintenant prêt à exécuter ce livre sur un ou plusieurs serveurs. La plupart des playbooks sont configurés pour être exécutés sur les serveursall de votre inventaire, par défaut. Nous pouvons utiliser l'indicateur-l pour nous assurer que seul un sous-ensemble de serveurs, ou un seul serveur, est affecté par le playbook. Pour exécuter le playbook uniquement surserver1, vous pouvez utiliser la commande suivante:

ansible-playbook initial_server_setup.yml  -l server1

Vous obtiendrez une sortie similaire à celle-ci:

Output
PLAY [all] ***************************************************************************************************************************************

TASK [Make sure we have a 'wheel' group] *********************************************************************************************************
changed: [server1]

TASK [Allow 'wheel' group to have passwordless sudo] *********************************************************************************************
changed: [server1]

TASK [Create a new regular user with sudo privileges] ********************************************************************************************
changed: [server1]

TASK [Set authorized key for remote user] ********************************************************************************************************
changed: [server1]

TASK [Disable password authentication for root] **************************************************************************************************
changed: [server1]

TASK [Update apt] ********************************************************************************************************************************
changed: [server1]

TASK [Install required system packages] **********************************************************************************************************
ok: [server1]

TASK [UFW - Allow SSH connections] ***************************************************************************************************************
changed: [server1]

TASK [UFW - Deny all other incoming traffic by default] ******************************************************************************************
changed: [server1]

PLAY RECAP ***************************************************************************************************************************************
server1                    : ok=9    changed=8    unreachable=0    failed=0

Une fois l’exécution du Playbook terminée, vous pourrez vous connecter au serveur avec:

ssh sammy@server_domain_or_IP

N'oubliez pas de remplacersammy par l'utilisateur défini par la variablecreate_user etserver_domain_or_IP par le nom d'hôte ou l'adresse IP de votre serveur.

Si vous avez défini une clé publique personnalisée avec la variablecopy_local_key, vous devrez fournir un paramètre supplémentaire spécifiant l'emplacement de son homologue de clé privée:

ssh sammy@server_domain_or_IP -i ~/.ssh/ansible_controller_key

Une fois connecté au serveur, vous pouvez vérifier les règles actives du pare-feu UFW pour vous assurer qu’il est correctement configuré:

sudo ufw status

Vous devriez obtenir une sortie semblable à ceci:

OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

Cela signifie que le pare-feu UFW a été activé avec succès. S'agissant de la dernière tâche du livre de lecture, cela confirme que celui-ci a été entièrement exécuté sur ce serveur.

Le contenu du livret

Vous pouvez trouver le playbook de configuration initiale du serveur dans lesansible-playbooks repository du DigitalOceanCommunity GitHub organization. Pour copier ou télécharger directement le contenu du script, cliquez sur le boutonRaw vers le haut du script, ou surclick here to view the raw contents directly.

Le contenu complet est également inclus ici pour plus de commodité:

initial_server_setup.yml

---
- hosts: all
  remote_user: root
  gather_facts: false
  vars:
    create_user: sammy
    copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
    sys_packages: [ 'curl', 'vim', 'git', 'ufw' ]

  tasks:
    - name: Make sure we have a 'wheel' group
      group:
        name: wheel
        state: present

    - name: Allow 'wheel' group to have passwordless sudo
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%wheel'
        line: '%wheel ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s'

    - name: Create a new regular user with sudo privileges
      user:
        name: "{{ create_user }}"
        state: present
        groups: wheel
        append: true
        create_home: true
        shell: /bin/bash

    - name: Set authorized key for remote user
      authorized_key:
        user: "{{ create_user }}"
        state: present
        key: "{{ copy_local_key }}"

    - name: Disable password authentication for root
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'

    - name: Update apt
      apt: update_cache=yes

    - name: Install required system packages
      apt: name={{ sys_packages }} state=latest

    - name: UFW - Allow SSH connections
      ufw:
        rule: allow
        name: OpenSSH

    - name: UFW - Deny all other incoming traffic by default
      ufw:
        state: enabled
        policy: deny
        direction: incoming

N'hésitez pas à modifier ce manuel ou à inclure de nouvelles tâches pour répondre au mieux à vos besoins individuels dans votre propre flux de travail.

Conclusion

L'automatisation de la configuration initiale du serveur peut vous faire gagner du temps, tout en veillant à ce que vos serveurs suivent une configuration standard qui peut être améliorée et personnalisée en fonction de vos besoins. Avec la nature distribuée des applications modernes et le besoin d'une plus grande cohérence entre les différents environnements de transfert, une telle automatisation devient une nécessité.

Dans ce guide, nous avons montré comment utiliser Ansible pour automatiser les tâches initiales devant être exécutées sur un nouveau serveur, telles que la création d’un utilisateur non root avec un accès sudo, l’activation de UFW et la désactivation de la connexion root à distance.

Si vous souhaitez inclure de nouvelles tâches dans ce guide pour personnaliser davantage la configuration initiale de votre serveur, veuillez consulter notre guide d'introduction AnsibleConfiguration Management 101: Writing Ansible Playbooks.