Créer un Openstack Object Storage OVH avec Terraform pour backup Nextcloud

Bonjour à tous, cela fait un long moment que je n’ai pas eu l’opportunité d’écrire un article. Il y a quelques jours, j’ai eu besoin de relier un object storage OpenStack à un Nextcloud. J’ai décidé ensuite de l’automatiser avec terraform et l’inclure dans un module. Pour ceux qui ne connaissent pas les pratiques Objects Storage, je renvoie au site OpenStack. Comme d’hab, comme je suis chauvin, je vais utiliser un service cloud français : OVH. Bientôt et si le temps me le permet, j’utiliserai ma propre infra OpenStack sur plusieurs nodes : pour ça, j’ai enfin reçu mes cartes mères bi-xeon supermicro, mais tout est à construire, même le hardware donc à suivre…

L’authentification

Pour permettre à Terraform de dialoguer avec OpenStack, il faut sourcer un fichier RC avec les différentes variables d’environnement. Toutes ces valeurs sont disponibles dans l’interface d’administration d’OVHCloud. Ensuite il faut renseigner des blocs providers dans le code terraform.

#!/usr/bin/env bash
# To use an OpenStack cloud you need to authenticate against the Identity
# service named keystone, which returns a **Token** and **Service Catalog**.
# The catalog contains the endpoints for all services the user/tenant has
# access to - such as Compute, Image Service, Identity, Object Storage, Block
# Storage, and Networking (code-named nova, glance, keystone, swift,
# cinder, and neutron).
#
# *NOTE*: Using the 3 *Identity API* does not necessarily mean any other
# OpenStack API is version 3. For example, your cloud provider may implement
# Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
# only for the Identity API served through keystone.
export OS_AUTH_URL=https://auth.cloud.ovh.net/v3
# With the addition of Keystone we have standardized on the term **project**
# as the entity that owns the resources.

export OS_PROJECT_ID="..."
export OS_PROJECT_NAME="..."
export OS_USER_DOMAIN_NAME="Default"
if [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi
export OS_PROJECT_DOMAIN_ID="default"
if [ -z "$OS_PROJECT_DOMAIN_ID" ]; then unset OS_PROJECT_DOMAIN_ID; fi

# unset v2.0 items in case set
unset OS_TENANT_ID
unset OS_TENANT_NAME

# In addition to the owning entity (tenant), OpenStack stores the entity
# performing the action as the **user**.
export OS_USERNAME="..."

# With Keystone you pass the keystone password.
# echo "Please enter your OpenStack Password for project $OS_PROJECT_NAME as user $OS_USERNAME: "
export OS_PASSWORD="..."

# If your configuration has multiple regions, we set that information here.
# OS_REGION_NAME is optional and only valid in certain environments.
export OS_REGION_NAME="UK1"
 # example

# Don't leave a blank variable, unset it if it was empty
if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
export OS_INTERFACE=public
export OS_IDENTITY_API_VERSION=3

# for Vrack
export OVH_ENDPOINT="ovh-eu"
export OVH_APPLICATION_KEY="..."
export OVH_APPLICATION_SECRET="..."
export OVH_VRACK="pn-2854..."
export OVH_PUBLIC_CLOUD="..."
export TF_ACC=1
export OVH_CONSUMER_KEY="..."
provider "openstack" {
 auth_url    = "https://auth.cloud.ovh.net/v3.0/" # c'est comme son nom l'indique l'url d'authentification
 domain_name = "default" # à "default" pour OVH
 tenant_name = "" # dans le fichier RC
 alias       = "ovh"
 user_name   = var.openstack_user # à ne pas stocker en clair dans le code...
 password    = var.openstack_password
}

provider "ovh" {
 endpoint = "ovh-eu" # point d'entrée du fournisseur
 alias    = "ovh"
}

Création du conteneur de stockage

Pour ce qui est de la suite du code, rien de bien compliqué, c’est la ressource openstack_objectstorage_container :

resource "openstack_objectstorage_container_v1" "nextcloud_container" {
  provider     = openstack.ovh
  region       = var.bucket_region
  name         = "nextcloud-container"
  metadata     = {
    test = true
  }
  content_type = "application/json"
}

Pour plus d’agilité, j’en ai fait un module que je peux donc réutiliser dans tous mes projets terraform par exemple pour mon projet Nextcloud :

[matt@hyp2 nextcloud_test6]$ tree
.
├── ansible
│   ├── hosts
│   └── hosts.tpl
├── cloud_init.tpl
├── connections.tf
├── graph.png
├── graph.svg
├── main.tf
├── modules
│   ├── gluster-module
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── loadbalancer-module
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── mariadb-module
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── nextcloud-module
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── ovh-object-storage
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   └── variables.tf
│   └── redis-module
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── network_config_dhcp.cfg
├── network.tf
├── nicmodel.xsl
├── outputs.tf
├── provisioner.tf
├── terraform.tfstate
├── terraform.tfstate.backup
└── variables.tf

8 directories, 33 files

Ce qui en un schéma rapide donne :

archi_Nextcloud_Project

Intégration dans Nextcloud avec Ansible

Une fois que terraform aura appliqué le code et créé l’infrastructure, il faut lors de l’installation de Nextcloud monter l’Object Storage. La CLI de nextcloud nous permet de faire cela :

sudo -u nginx php occ files_external:create -c bucket=nextcloud-container \
    -c service_name=swift \
    -c region=UK \
    -c user=... \
    -c password=... \
    -c tenant=... \
    -c domain=default \
    -c url=https://auth.cloud.ovh.net/v3/ \
    OpenStackObjectStorage swift openstack::openstackv3

J’utilise nginx donc mon utilisateur pour lancer la CLI occ de nextcloud est nginx… Les user/password sont définis dans l’interface d’admin Horizon ou ovhcloud, pour info ils peuvent également être créés en CLI. Attention confusion possible sur la variable tenant : c’est le nom du tenant (ou nom du projet); une série de chiffres souvent plus courte que l’ID du tenant. Concernant l’url d’authentification, il vaut mieux utiliser la v3 car la v2 ne sera ou n’est plus supportée chez OVH.

Mon bloc de code d’installation silencieuse via Ansible devient donc :

- name: Nextcloud Silent Installation
  shell: |
      sudo -u "{{ webserver.user | default(apache) }}" php occ maintenance:install --database="mysql" --database-name="{{ nextcloud_db }}" --database-host="{{ hostvars[groups['lan_db'][0]]['ansible_host'] }}" --database-user="{{ nextcloud_db_user }}" --database-pass="{{ nextcloud_db_password }}" --database-table-prefix="" --admin-user="{{ nextcloud_admin_user }}" --admin-pass="{{ nextcloud_admin_password }}" --data-dir "/var/nc_data"
      sudo -u "{{ webserver.user | default(apache) }}" php occ config:system:set trusted_domains 1 --value="{{ hostvars[groups['lan_nc'][0]]['ansible_host'] }}"
      sudo -u "{{ webserver.user | default(apache) }}" php occ config:system:set trusted_domains 2 --value="{{ hostvars[groups['lan_nc'][1]]['ansible_host'] }}"
      sudo -u "{{ webserver.user | default(apache) }}" php occ config:system:set trusted_domains 3 --value="{{ hostvars[groups['lan_lb'][0]]['ansible_host'] }}"
      sudo -u "{{ webserver.user | default(apache) }}" php occ config:system:set overwrite.cli.url --value=https://"{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}"
      sudo -u "{{ webserver.user | default(apache) }}" php occ background:cron
      sudo -u "{{ webserver.user | default(apache) }}" php occ app:disable firstrunwizard
      sudo -u "{{ webserver.user | default(apache) }}" php occ app:disable survey_client
      sudo -u "{{ webserver.user | default(apache) }}" php occ app:install files_external
      sudo -u "{{ webserver.user | default(apache) }}" php occ app:enable files_external
      sudo -u "{{ webserver.user | default(apache) }}" php occ files_external:create -c bucket="{{ bucket_name }}" -c service_name=swift -c region="{{ bucket_region }}" -c user="{{ storage_user }}" -c password="{{ storage_user_password }}" -c tenant="{{ tenant_name }}" -c domain=default -c url="{{ object_auth_url }}" OpenStackObjectStorage swift openstack::openstackv3
      systemctl stop "{{ webserver.name | default(httpd) }}"
      sudo -u "{{ webserver.user | default(apache) }}" php occ db:add-missing-indices
      systemctl start "{{ webserver.name | default(httpd) }}"
  args:
    chdir: /var/www/html/nextcloud/
  tags: install
  when: not nc_config_stat.stat.exists
  delegate_to: "{{ hostvars[groups['lan_nc'][0]]['ansible_host'] }}"
  run_once: true

Voilà à l’issue de l’installation le stockage externe monté dans l’interface admin de Nextcloud :

Openstack Object Storage dans Nextcloud

Monter un Openstack Object Storage sous Linux Fedora

Pour rendre plus pratique l’utilisation d’un objet de stockage Openstack, il peut être judicieux de le monter directement sur un serveur. Pour Fedora Server, il faut installer le package s3fs-fuse. Ensuite créer un fichier de configuration avec la clé d’accès et le mot de passe récupérés avec la CLI openstack. Voici les commandes :

[matt@hyp2 nextcloud_test6]$ sudo dnf install s3fs-fuse
[matt@hyp2 nextcloud_test6]$ sudo mkdir /mnt/cloudata
[matt@hyp2 nextcloud_test6]$ source ~/openstackrc.sh
[matt@hyp2 nextcloud_test6]$ openstack ec2 credentials  list
+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| Access                           | Secret                           | Project ID                       | User ID                          |
+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| ae4fzffefefzfefefezfzefzef59c9c2 | ef8efdfefefefzfzfzefefezfef1f5cc | ef8efdfefefefifoioid646zfef1f5cc | ff8efdfefefefifoioid646zfef1f5cc |
| 3dee2eb082frfrf554frfrfrffrrfrff | 86522ae2fzeffezezfzeffzfz19b6ffb | ef8efdfefefefifoioid646zfef1f5cc | ff8efdfefefefifoioid646zfef1f5cc |
+----------------------------------+----------------------------------+----------------------------------+----------------------------------+

[matt@hyp2 nextcloud_test6]$ echo <Access>:<Secret> > ~/.passwd-s3fs
[matt@hyp2 nextcloud_test6]$ chmod 0600 ~/.passwd-s3fs
[matt@hyp2 nextcloud_test6]$ sudo s3fs nextcloud-container /mnt/cloudata \
> -o passwd_file=~/.passwd-s3fs \
> -o url=https://storage.uk.cloud.ovh.net \
> -o use_path_request_style \
> -o umask=0002 \
> -o allow_other

Voire ajouter une ligne dans le fichier fstab. A noter qu’avec ec2, on ne passe plus par l’authentification openstack ovh mais directement sur le serveur de stockage de la région.

Bonnes sauvegardes sur le Cloud !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

32 − = 23

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.