JDB - Migration hébergement 2021

De PedroWiki

Introduction

Objectif de la migration:

  • on reste sur le même provider Cloud.
  • on monte 2 nouveaux serveurs en Debian 10.
  • on contrôle les déploiements par Terraform.
  • on contrôle la gestion fine des serveurs par Ansible.

NB: cette migration a été faite depuis un poste Windows, mais toutes les commandes dans WSL (git, terraform, ansible) sont également valables si on travaille depuis un poste ou un serveur Linux.

Versions

  • OS: Debian 10.9
  • Git: 2.20.1
  • Terraform: v1.0.5
  • Ansible: 2.7.7
  • Python (poste de contrôle): 3.7.3
  • Python (node distant): 2.7.16

Liens utiles

Journal de bord de la migration

Préparation du poste

WSL

La migration s'opère depuis un poste Windows 10.

On maximise l'utilisation de WSL pour plus de confort.

Cf la documentation officielle de Microsoft.

Les packages ou applications à installer:

  • Windows Terminal.
  • WSL Debian.

En complément, mais non essentiel pour le projet, activation de WSL2.

VSCode

Pour plus de confort, on installe et on utilisera Visual Studio Code.

Git

Dans la distribution WSL Debian:

sudo apt-get install git

Initialisation de Git en suivant ce super tuto Renater:

cd /mnt/d/Jules/Tech/Git/
git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto
git config --global user.email "jules@pedrono.fr"
git config --global user.name "jules"
cd scaleway
git init

NB: je n'utilise pour l'instant que le repository local, on ne push pas vers un serveur Gitlab distant ou sur Github.

Exclusions de fichier par gitignore:

git config --global core.excludesfile ./.gitignore

=> à priori sans effet car valeur par défaut contrairement au wiki ci dessus.

vi .gitignore (ignorer /tmp)
git status

Contenu du gitignore (.git/info/exclude):

# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
/tmp
/old
vi .git/info/exclude
rm .gitignore
git status

Terraform

Installation

Cf la documentation Terraform

Dans la distribution WSL Debian:

sudo apt-get update
sudo apt-get install curl
sudo apt-get install gnupg1
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-get install lsb-release

Cf cette doc pour le troubleshooting lors de l'ajout du repository.

sudo apt-get install software-properties-common
sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt install terraform

Cf ce tuto pour l'ajout du provider Scaleway.

Configuration

jules@DESKTOP-QQG9015:/mnt/d/Jules/Tech/Git/scaleway/terraform$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding latest version of scaleway/scaleway...
- Installing scaleway/scaleway v2.1.0...
- Installed scaleway/scaleway v2.1.0 (signed by a HashiCorp partner, key ID F5BF26CADF6F9614)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Ansible

Cf la documentation officielle Ansible.

sudo apt-get update
sudo apt-cache search ansible
sudo apt-get install ansible

Configuration Scaleway

Suppression des clés RSA dans les "Identifiants" du compte Scaleway, et re création avec le contenu de ma clé publique utilisée par défaut.

NB: cette clé sera automatiquement placée par Scaleway dans le authorized_keys du user root au moment du déploiement de l'instance.

Vérification de la fingerprint de ma clé publique:

jules@DESKTOP-QQG9015:~$ ssh-keygen -l -E md5 -f ./id_rsa_jules.pub
2048 MD5:bc:c2:f5:6f:a9:03:97:fb:fc:65:3f:f0:de:d1:31:24 jules@DESKTOP-QQG9015 (RSA)

Suppression des anciennes clés d'API et re création d'une paire clé/clé secrète.

Configurations Terraform

Choix de départ: on colle tout le code Terraform dans un seul main.tf.

Etapes:

  • Câblage du provider Scaleway:
terraform {
  required_providers {
    scaleway = {
      source = "scaleway/scaleway"
    }
  }
  required_version = ">= 0.13"
}
  • Déclaration du provider:
provider "scaleway" {
  access_key      = "<clé API Scaleway>"
  secret_key      = "<clé secrète de la clé d'API>"
  project_id      = "<utiliser l'ID de l'organisation Scaleway>"
  zone            = "fr-par-1"
  region          = "fr-par"
}
  • Réservation d'une IP publique:
resource "scaleway_instance_ip" "public_ip" {}
  • Configuration du Security Group:
resource "scaleway_instance_security_group" "test-sg" {
  inbound_default_policy  = "drop"
  outbound_default_policy = "accept"
  name = "tf-test-sg"

  inbound_rule {
    action = "accept"
    port   = "22"
    ip     = "<IP publique du poste ou serveur d'administration>"
  }

  inbound_rule {
    action = "accept"
    port   = "80"
  }

  inbound_rule {
    action = "accept"
    port   = "443"
  }
}
  • Déclaration de l'instance serveur:
resource "scaleway_instance_server" "test-srv" {
  type  = "DEV1-S"
  image = "debian_buster"
  name = "tf-test-srv"
  state = "started"

  tags = [ "test", "web" ]

  ip_id = scaleway_instance_ip.public_ip.id

  security_group_id = scaleway_instance_security_group.test-sg.id
}

NB:

  • A confirmer, mais les types d'instance DEV n'ont pas l'air de supporter un disque additionnel, donc on retire ce bout de code de l'exemple fourni par Scaleway et on se contente du disque local de base (20Go pour DEV1-S).
  • la proposition de la doc Scaleway d'utiliser une clé organization_id n'est plus valable dans cette version de Terraform, cf ce tuto Terraform. A partir de là, on remplace organization_id par project_id, et on fixe par défaut la valeur à l'ID de notre organisation Scaleway.

Configurations Ansible

Premiers pas:

NB: Dans notre cas, les appels ansible échouaient avec une erreur du type:

"/bin/sh: 1: /usr/bin/python: not found\r\n",

Sur le node contrôlé par Ansible, on constate en effet que ce fichier n'existe pas, on contourne brutalement la situation via la commande suivante:

ln -s /usr/bin/python3.7 /usr/bin/python

Constitution de la liste d'hôtes

Cf la documentation officielle Ansible sur la gestion de l'inventaire de parc.

Il y a de nombreuses façons de désigner les machines de l'inventaire:

  • via une option de la ligne de commande ansible-playbook.
  • via un fichier d'inventaire local au projet.
  • via un fichier d'inventaire global dans /etc/ansible/hosts.

Dans un premier temps on applique une configuration simpliste dans le fichier global, on fera mieux ensuite:

sudo vi /etc/ansible/hosts
...
[testservers]
<ip_publique_serveur>

Application des configurations Terraform

Planifier les modifications:

terraform plan

Appliquer les modifications:

terraform apply

Cf cette documentation Terraform sur le CLI et les états: Si un objet a été modifié "dans la vraie vie" et que son état n'est plus cohérent avec les états connus de terraform, il est possible d'importer l'état "de la vraie vie" pour rendre cohérents les états terraform. Cela permet de rattraper les écarts, par exemple, quand on n'a pas été rigoureux et qu'on a géré les objets par d'autres biais que terraform (ex: console Scaleway):

terraform import <nom_ressource_terraform> <region>/<id_de_l_objet_instancié>

Vous pouvez lister les objets connus de terraform:

terraform state list

Ex:

jules@DESKTOP-QQG9015:/mnt/d/Jules/Tech/Git/scaleway/terraform$ terraform state list
scaleway_instance_ip.public_ip
scaleway_instance_security_group.test-sg
scaleway_instance_server.test-srv

Vous pouvez également lister l'état connu d'un objet par terraform:

terraform state show <nom_ressource_terraform>

Ex:

jules@DESKTOP-QQG9015:/mnt/d/Jules/Tech/Git/scaleway/terraform$ terraform state show scaleway_instance_server.test-srv
# scaleway_instance_server.test-srv:
resource "scaleway_instance_server" "test-srv" {
    additional_volume_ids = []
    boot_type             = "local"
    bootscript_id         = "<id_bootscript>"
    enable_dynamic_ip     = false
    enable_ipv6           = false
    id                    = "fr-par-1/<id_instance>"
    image                 = "debian_buster"
    ip_id                 = "fr-par-1/<id_ip>"
    ipv6_prefix_length    = 0
    name                  = "tf-test-srv"
    organization_id       = "<id_organization>"
    private_ip            = "<ip_privee>"
    project_id            = "<id_projet>"
    public_ip             = "<ip_publique>"
    security_group_id     = "fr-par-1/<id_sg>"
    state                 = "started"
    tags                  = [
        "test",
        "web",
    ]
    type                  = "DEV1-S"
    zone                  = "fr-par-1"

    root_volume {
        delete_on_termination = true
        size_in_gb            = 20
        volume_id             = "fr-par-1/<id_volume>"
    }
}

Application des configurations Ansible

Jouer un playbook:

ansible-playbook <nom_du_playbook>.yml

Possibilités de surcharges:

  • -vvv: augmenter le niveau de verbosité (débug).
  • -u: forcer l'usage d'un utilisateur spécifique (autre que celui de la session linux en cours).
  • --private-key <path_to_priv_key>: forcer l'usage d'une paire de clé RSA spécifique.

Reste à faire

  • Stockage des états terraform pour permettre le partage avec un autre admin (ex: bucket S3).
  • Crédentiels Terraform à passer en variable d'environnement pour ne plus les écrire explicitement dans le code Terraform.
  • Evaluer l'utilité des datas sources ssh key.