1. Architecture
L'application et toutes ses dépendances sont compilées dans une image Docker.
Dès que le conteneur est déployé sur une instance GCP, il se connecte à une organisation Salesforce disposant du package Unify UI (installable directement via le AppExchange).
Ce document décrit une configuration possible pour gérer l'accès à l'instance déployée, par exemple via un LoadBalancer.
Diagramme de flux
Voici le diagramme décrivant tous les flux entrants/sortants ainsi que les IPs et ports demandés par l'application.
Mesures de sécurité
Nous ne pouvons pas fournir un exemple d'implémentation de la couche de sécurité qui s'intégrerait parfaitement à votre architecture. Cependant, nous pouvons fournir quelques recommandations pertinentes pour l'utilisation de l'application elle-même.
- Protocoles et ports : Tous les flux sortants/entrants de l'application passent par le protocole HTTPS (port 443). Il n'est pas nécessaire d'ouvrir un autre port sur votre VM. Les IPs DQE qui doivent être accessibles sont décrites dans le diagramme précédent.
- Filtrage IP : Le serveur d'application lui-même doit uniquement être accessible depuis les serveurs Salesforce. Il est donc recommandé de mettre en place un filtrage des IP entrantes.
Il existe cependant une exception, le serveur web CustomUI inclus dans le docker-compose. Il doit être accessible via un navigateur web. Une solution pourrait donc être d'autoriser un VPN spécifique à accéder au serveur. Voir ici la liste des IPs publiées par Salesforce. (N'oubliez pas les IPs Hyperforce)
- Protocole d'authentification : Salesforce offre nativement plusieurs protocoles pour sécuriser les requêtes entre ses serveurs et le serveur DQE One. Lors de la configuration de l'application connectée "DQE One Customer" dans votre organisation, vous pourrez sélectionner la méthode d'authentification "Basic Auth" et configurer votre pare-feu applicatif en conséquence.
Si la VM est directement exposée à internet, elle doit avoir une entrée DNS et un certificat SSL associé qui pointent vers elle.
Si la VM n'est pas directement exposée à internet, cela signifie généralement que le trafic est acheminé via un composant tel qu'une passerelle. Dans ce cas, le DNS et le certificat SSL doivent être installés sur cette passerelle, qui redirigera ensuite le trafic vers la VM interne.
Recommandation
Dans cette section, nous décrivons la liste des composants nécessaires pour installer l'instance Unify Server DQE sur GCP.
Note : Les estimations sont faites pour une base de 1 million d'enregistrements. Selon le volume des bases de données traitées, il peut être nécessaire d'augmenter la capacité mémoire des instances conteneurs afin d'optimiser les temps de traitement.
Déploiement avec des INSTANCES VM GCP
- Type de serveur : Unix, par exemple Ubuntu.
- Load Balancer : Non essentiel mais peut être utilisé s'il existe déjà.
Pour plus d'informations, consultez les ressources suivantes :
- Configuration VM :
https://cloud.google.com/compute/docs/instances?hl=fr
Composition et services
L'image docker est une application web qui expose les services et API sollicités depuis Salesforce via l'application Lightning DQE Unify UI.
Pour chaque service, nous décrivons ci-dessous les attributs et leurs fonctions.
APPLICATION WEB
Un conteneur backend contenant une application microservices. Cette application expose toutes les API appelées pour lancer des processus, gérer les files de traitement, instancier des workers de traitement. Elle dépend des services suivants pour fonctionner correctement. Ce worker doit être exposé sur le web comme décrit dans la configuration nginx présentée plus loin dans ce document.
Paramètres Docker Compose
-
image : Le nom de l'image utilisée par l'application web. Il est nécessaire de renommer l'image selon les noms des registres utilisés. Pour les images hébergées dans un registre de conteneurs Azure, le nom se construit comme suit :
<Nom du registre de conteneurs>.azurecr.io/<nom de l'image>
- container_name : Nom du conteneur
- depends_on : Noms des services précédant ce service
-
domainname : Le nom de domaine pour le FQDN. Résultat évalué Azure :
<nom de domaine>
- environment : Variables d'environnement du service
- command : Commande exécutée au lancement du conteneur
Worker
Un conteneur backend contenant une application microservices. Cette application expose toutes les API appelées pour lancer des processus, gérer les files de traitement, instancier des workers de traitement. Elle dépend des services suivants pour fonctionner correctement. Ce worker doit être exposé sur le web comme décrit dans la configuration nginx présentée plus loin dans ce document.
Paramètres à définir dans Docker Compose
- image : Le nom de cette image est identique à celui du service web
- container_name : Le nom du conteneur qui apparaît dans Azure
- depends_on : Noms des services qui précédent ce service
- environment : Variables d'environnement du service
- command : Commande exécutée au lancement du conteneur
CustomUI
Ce service est une application web exposant une interface front utilisée pour configurer les règles de déduplication. Comme le premier service, il doit donc également être exposé sur le web. Ce service consomme aussi certaines API du backend, par exemple pour récupérer les métadonnées du CRM.
Nom du registre : *
Nom de l'image : *
Versions disponibles : *
Redis
Ce service est une base de données clé/valeur utilisée par les différents services pour stocker des clés de fonctionnement internes telles que les configurations d'organisation Salesforce, les sessions, etc.
Il est possible d'utiliser les images officielles publiées par Redis comme "redis:alpine", mais par mesure de sécurité certains fournisseurs cloud bloquent la récupération d'images publiques et n'autorisent que les images provenant de registres privés. Pour contourner cette restriction, nous publions également sur le registre privé "dqeone" une version de redis parfaitement compatible avec nos applications.
Paramètres
- image : Image officielle de redis => redis:alpine
- container_name : Le nom du conteneur qui apparaît dans Azure
-
volumes : Le chemin du volume à utiliser pour sauvegarder les données Redis
<nom du volume défini dans ce docker compose>:/data
RabbitMQ
Ce service est un gestionnaire de files d'attente puissant permettant la réception et la planification des requêtes de traitement. Tant qu'un processus n'a pas été attribué à un worker et terminé, il reste en attente dans une file. Cela permet aussi une résilience aux pannes, si le serveur devait redémarrer, il reprendrait le dernier traitement en file d'attente là où il s'était arrêté.
Comme pour l'image du service Redis, vous avez la possibilité d'utiliser une version publique (rabbitmq:3-management-alpine) ou celle du registre privé dqeone.
Paramètres
- image : Image officielle de rabbitmq => rabbitmq:3-management-alpine
- container_name : Nom du conteneur qui apparaît dans aws
2. Installation
2 scénarios sont possibles :
-
Scénario 1 : Le client ne dispose pas encore d'un Load Balancer configuré sur sa VM
Suivez toutes les étapes - Scénario 2 : Le client utilisateur GCP dispose déjà d'une VM avec Load Balancer configuré
2.1. Prérequis
Lancez l'instance serveur dédiée et connectez-vous avec l'une des options de connexion :
Pour plus de détails sur l'accès aux instances via la console GCP, consultez la documentation officielle sur le site GCP.
Installation de NGINX
$ sudo apt update
$ sudo apt install nginx
Configuration :
- Si la VM est uniquement accessible via le load balancer (vnet privé par exemple)
server {
listen 80;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8001;
}
Location /api/ {
rewrite /api/(.*) /$1 break;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8000;
}- Si la VM est directement ouverte en https :
server {
listen 443 ssl;
server_name <e.g. exemple.com>;
ssl_certificate < emplacement du certificat .crt>
ssl_certificate_key < emplacement de la clé privée .key>
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH: !aNULL: ! MD5;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8001;
}
Location /api/ {
rewrite /api/(.*) /$1 break;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8000;
}
}
Installation de Docker
-
Mettre à jour le paquet existant
$ sudo apt-get update -
Installation des prérequis pour utiliser les paquets via HTTPS
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
-
Ajout de la clé GPG du dépôt officiel Docker
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
-
Ajout du dépôt Docker aux sources APT
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
-
Mise à jour des paquets
$ sudo apt-get update
-
Vérification de l'installation depuis le dépôt Docker
$ apt-cache policy docker-ce
-
Installation de Docker
$ sudo apt install docker-ce
Installation de Docker-compose
-
Téléchargez la version désirée (Numéro de version à modifier dans l'URL)
$ sudo curl -L "https://github.com/docker/compose/releases/download/<NUMEROS_DE_VERSION>/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose -
Définir les permissions
$ sudo chmod +x /usr/local/bin/docker-compose
Installation de Azure-cli
$ sudo curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
2.2. Serveur Unify GCP
version: '3.8'
services:
rabbitmq:
image: rabbitmq:3-management-alpine
container_name: rabbitmq
hostname: rabbitmq
logging:
driver: none
depends_on:
- redis
environment:
RABBITMQ_DEFAULT_PASS: guest
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_VHOST: admin
volumes:
- rabbitmq_data:/var/lib/rabbitmq/
- rabbitmq_log:/var/log/rabbitmq/
ports:
- "15672:15672"
redis:
container_name: redis
image: "redis:alpine"
hostname: redis
logging:
driver: none
ports:
- "6379:6379"
unify:
container_name: one-server
image: <imageURL>
expose:
- "8000"
ports:
- "8000:8000"
depends_on:
- redis
- rabbitmq
environment:
- SFAPIVERSION=v57.0
- WAIT_HOSTS= redis:6379
- WAIT_HOSTS_TIMEOUT=300
- WAIT_SLEEP_INTERVAL=5
- WAIT_HOST_CONNECT_TIMEOUT=30
- REDIS_URL=redis://redis
- CLOUDAMQP_URL=amqp://guest:guest@rabbitmq/admin
command:
- "bash"
- "./entrypoint.sh"
custom:
container_name: custom
image: <imageURL>
command: npm start
environment:
- PORT=8001
expose:
- "8001"
ports:
- "8001:8001"
worker:
container_name: queue-worker
image: <imageURL>
restart: always
depends_on:
- unify
- redis
- rabbitmq
environment:
- SFAPIVERSION=v57.0
- WORKDIRPATH=/app/unify
- REDIS_URL=redis://redis
- CLOUDAMQP_URL=amqp://guest:guest@rabbitmq/admin
command: python -u ./unify/queue_worker.py
volumes:
rabbitmq_data:
rabbitmq_log:
redis_data:
nginx.conf:
3. Lancement
3.1. Connexion de l'image DQE One au Hub Azure
Connectez Docker à l'image ONE Server DQE sur Azure :
$ sudo docker login **************
Nom d'utilisateur : <Identifiant fourni par DQE>
Mot de passe : <Mot de passe fourni par DQE>
3.2. Lancement de docker-compose.yml
Allez dans le dossier contenant le docker-compose.yml et lancez la commande.
$ sudo docker-compose up
Associé à