Contact salesFree trial
Blog

Comment assainir les données de l'environnement de prévisualisation

gdprdonnéesscripts d'activitél'automatisation
Partager

Être conforme au GDPR dans tous vos projets est un défi quotidien - en particulier si vous gérez des données utilisateur sensibles sur vos projets. Upsun adopte une approcheGDPR everywhere avec des niveaux élevés de sécurité et de conformité intégrés en standard - mais il existe des moyens de sécuriser davantage vos données sur notre PaaS lorsqu'il s'agit d'environnements de prévisualisation.

Chaque fois que vous créez une nouvelle branche Git sur un projet sur Upsun, l'environnement correspondant hérite des données (actifs et base de données) de son parent. Cela signifie que des données potentiellement sensibles de votre site web de production peuvent être exposées à l'environnement de prévisualisation.

Alors, comment s'y retrouver et s'assurer que votre application reste conforme ? Deux mots : assainissement des données. Il s'agit de l'effacement délibéré et permanent de données sensibles d'un dispositif de stockage, ce qui rend les données irrécupérables. Dans cet article, je partagerai les méthodes d'assainissement des données que vous pouvez mettre en œuvre pour les environnements de prévisualisation afin de garantir que vos données restent en sécurité à chaque étape du développement.

Quelques ressources nécessaires avant de commencer

Nous avons quelques prérequis pour nous assurer que vous pouvez suivre les solutions et les étapes détaillées dans cet article - veuillez vous assurer que vous avez installé les éléments suivants :

Méthodes d'assainissement des données de l'application

Pour les besoins de cet article, nous allons nous concentrer sur l'assainissement des données de l'environnement de prévisualisation sur Symfony, cependant, les méthodes détaillées s'appliquent à tous les frameworks.

Si vous voulez plus de détails sur la façon de mettre en place des applications Symfony Demo sur Upsun, jetez un coup d'oeil à notre guide Up(sun) and running with Symfony Demo.

Tout au long de l'article, nous allons passer en revue les différentes méthodes disponibles pour assainir les données de l'environnement Symfony sur Upsun - 5 méthodes pour être exact - que vous pouvez évaluer et choisir la meilleure pour vous. Cependant, assurez-vous que vous avez terminé l'étape de création d'une commande avant de procéder à une méthode.

Si vous connaissez déjà la méthode que vous préférez utiliser, cliquez sur le titre correspondant ci-dessous et nous vous y emmènerons directement :

Tout d'abord, créez une commande pour assainir vos données

Remarque: si vous hébergez une pile autre que Symfony, veuillez adapter la commande pour assainir votre base de données dans votre pile et la pousser vers votre branche de production. C'est la seule étape spécifique à Symfony dans cet article.

Pour exécuter l'une des cinq méthodes d'assainissement des données listées ci-dessus, nous avons besoin d'un appelable pour assainir nos environnements. Il y a deux façons possibles de le faire :

  1. Utiliser un script SQL pour mettre à jour ou falsifier toutes les données sensibles.
  2. En utilisant une commande Symfony pour le faire, peut-être en utilisant le bundle fakerPHP.

Puisque nous utilisons une application Symfony Demo, nous utiliserons la seconde option. Faites ce qui suit, à partir de la branche principale de Git :

symfony composer require --dev fakerphp/faker git add composer.json composer.lock && git commit -m "composer require --dev fakerphp bundle" 

Ensuite, ouvrez votre code dans votre IDE préféré et créez une nouvelle commande Symfony, dans un fichier SRC/command/SanitizeDataCommand.php, avec ce qui suit :

<?php /* src/Command/SanitizeDataCommand.php */ namespace App\Command ; use App\Entity\User ; use App\Repository\UserRepository ; use Doctrine\ORM\EntityManagerInterface ; use Faker ; use Symfony\Component\Console\Attribute\AsCommand ;
use Symfony\Component\Console\Command\Command ; use Symfony\Component\Console\Input\InputInterface ; use Symfony\Component\Console\Output\OutputInterface ; use Symfony\Component\Console\Style\SymfonyStyle ; #[AsCommand( name : 'app:sanitize-data', description : 'Assainissement des données utilisateur (nom d'utilisateur et email).', aliases : ['app:sanitize'] )] class SanitizeDataCommand extends Command { private SymfonyStyle $io ; public function __construct(private UserRepository $userRepository, private EntityManagerInterface $entityManager) { parent::__construct() ; } protected function configure() { $this ->setDescription('Cette commande permet d'assainir les données des utilisateurs (nom d'utilisateur et email).') ; } protected function initialize(InputInterface $input, OutputInterface $output) : void { $this->io = new SymfonyStyle($input, $output) ; } protected function execute(InputInterface $input, OutputInterface $output) : int { $users = $this->userRepository->findAll() ; $this->io->progressStart(count($users)) ; $this->entityManager->getConnection()->beginTransaction() ; // suspend l'auto-commit try { /** @var User $user */ foreach ($users as $user) { $this->io->progressAdvance() ; // initialise le faker $faker = Faker\Factory ::create() ; $this->io->text('faking user '.$user->getUsername()) ; // fausse info utilisateur $user->setUsername(uniqid($faker->userName())) ; $user->setEmail($faker->email()) ; // veuillez adapter à vos besoins }   

           $this->entityManager->flush() ; $this->entityManager->getConnection()->commit() ; $this->io->progressFinish() ; } catch (\Exception $e) { $this->entityManager->getConnection()->rollBack() ; throw $e ; } return Command::SUCCESS ; } }

Cette commande app:sanitize-data utilise le UserRepository et falsifie le nom d'utilisateur et l'email de l'entité par défaut User Symfony. Veuillez l'adapter à vos besoins. Ensuite, ajoutez votre code à la branche principale:

git add src/Command/SanitizeDataCommand.php && git commit -m "sanitize data command" 
déploiement de symfony

1) Assainir manuellement vos données

Maintenant que votre code source contient une commande Symfony pour assainir vos données, nous allons l'utiliser manuellement dans un nouvel environnement de prévisualisation. En commençant par créer une nouvelle branche staging et en attendant que le processus se termine, comme suit :

symfony branch staging --type=staging

Ensuite, exécutez votre commande Symfony nouvellement créée sur votre environnement Upsun staging, comme indiqué ci-dessous :

symfony ssh php bin/console -e dev app:sanitize-data

Et voilà, les données de votre environnement de prévisualisation sont assainies !

2) Utiliser l'héritage d'environnement

Dans cette section, nous allons créer un environnement de prévisualisation, assainir ses données, et ensuite faire en sorte que tous les nouveaux environnements héritent de cet environnement de prévisualisation.

Comme mentionné au début de cet article, chaque fois que vous créez une nouvelle branche Git sur Upsun, l'environnement créé héritera des données de l'environnement parent. Cependant, il est possible de modifier l'héritage des données par défaut et de le configurer plus tard pour synchroniser les données d'un nouveau parent - l'environnement de prévisualisation que nous allons créer.

Le CLI Symfony offre la possibilité de créer une branche sans parent, en utilisant l'option --no-clone-parent, puis en définissant le parent à staging (a.k.a preview), ce qui garantit que les nouvelles branches héritent des données de l'environnement de prévisualisation. Suivez les instructions de l'étape 1 pour plus de détails sur la façon d'assainir manuellement les données de l'environnement de prévisualisation afin de garantir que toutes les branches futures héritent de données assainies et conformes au GDPR.

symfony checkout main symfony branch dev --no-clone-parent symfony env:info -e dev parent staging symfony sync -e dev data

Et voilà, votre nouvel environnement dedéveloppement est maintenant créé avec les données nettoyées de votre environnement de prévisualisation.

3) Utiliser un crochet

Plutôt que de s'appuyer sur l'héritage, il peut être souhaitable d'assainir certaines données à chaque déploiement. Dans ce cas, nous pouvons déplacer notre appel de script dans la section " hooks" de la configuration.

Le type de crochet que vous choisissez est libre- crochets de déploiement ou crochetspost_déploiement - mais voici quelques points à garder à l'esprit :

  • Les scripts à longue durée d'exécution dans le crochet de déploiement devront prolonger le temps de déploiement d'une application.
  • Un script de longue durée dans le hook post_deploy pourrait rendre momentanément publiques des données non conformes/critiques pendant que l'assainissement est en cours.
  • Redéploiements ; si l'assainissement est quelque chose que vous aimeriez pouvoir déclencher manuellement avec un redéploiement, l'assainissement aura lieu à chaque redéploiement seulement s'il est placé dans le hook post_deploy.

Pour exécuter une commande Symfony pendant le hook post_deploy, ajoutez ce qui suit dans votre .upsun/config.yaml:

applications : app : hooks : build : ... deploy : ... post_deploy : | if [ "$PLATFORM_ENVIRONMENT_TYPE" != production ] ; then # L'assainissement de la base de données devrait avoir lieu ici (puisque c'est de la non-production) php bin/console -e dev app:sanitize-data fi

Poussez ensuite votre code sur la branche principale:

git checkout main && git add .upsun/config.yaml && git commit -m "add sanitize data command to post_deploy hook" 
symfony deploy

4) Utiliser des opérations d'exécution et des scripts d'activité

Il y a une autre option qui vous permet de créer un déclencheur personnalisé qui est exécuté en réponse à certaines activités qui ont lieu sur le projet. Par exemple, lors de la synchronisation d'un environnement avec son parent, nous pourrions synchroniser les données non anonymisées du parent (par exemple, si la synchronisation se fait à partir de l'environnement de production).

Les deux composants qui permettront de réaliser cette opération sont les suivants :

  • Une opération d'exécution: elle vous permettra de déclencher des commandes ou des scripts uniques sur votre projet. Similaires aux crons, ils s'exécutent dans le conteneur d'application mais pas selon un calendrier spécifique.
  • Un script d'activité: un morceau de code JavaScript qui sera exécuté en réponse à certaines activités se déroulant au niveau du projet, de l'environnement ou même de l'organisation.

Nous allons donc ajouter une intégration (script d'activité) qui répond à certains événements pour exécuter une opération d'exécution afin d'assainir les données à la volée, voir l'ajout d'une intégration d' un script d'activité ci-dessous.

Remarque: si vous avez défini un hook post_deploy à l'étape précédente, veuillez le commenter car il ne sera plus nécessaire après l'utilisation de cette opération d'exécution.

Comment créer une opération d'exécution

Pour configurer une opération d'exécution, nous devons ajouter une nouvelle clé YAML de premier niveau dans notre fichier.upsun/config.yaml avec ce qui suit :

applications : app : 
    operations : sanitize : role : admin commands : start : | if [ "$PLATFORM_ENVIRONMENT_TYPE" != production ] ; then # L'assainissement de la base de données devrait avoir lieu ici (puisqu'il s'agit d'une non-production) php bin/console -e dev app:sanitize-data fi

Poussez ensuite votre fichier vers la branche principale et déployez-le.

git checkout main git add .upsun/config.yaml && git commit -m "add runtime operation to sanitize data" symfony deploy

Et si vous voulez tester cette opération d'exécution manuellement, vous pouvez utiliser ce qui suit :

symfony operation:run sanitize --app=app

Comment créer un script d'activité

Upsun supporte les scripts personnalisés qui peuvent être déclenchés en réponse à n'importe quelle activité. Ce script est exécuté en dehors du contexte de l'environnement et nous devons donc recréer ce contexte pour que le script d'activité soit exécuté avec les droits nécessaires. Pour ce faire, créez un nouveau fichier src/runtime/sanitize.js avec ce qui suit :

// src/runtime/sanitize.js let app_container = "app" ; let runtime_operation_name = "sanitize" ; if (!variables.api_token) { console.log("Variable API Token is not defined !") ; console.log("Veuillez définir une variable d'environnement avec votre jeton API à l'aide de la commande : ") ; console.log("upsun project:curl /integrations/<INTEGRATION_ID>/variables -X POST -d '{\"name\" : \N- "api_token\N", \N- "value\N" : \"<API_TOKEN>", "is_sensitive" : true, "is_json" : false}' ") ; } else { console.log("OAuth2 API Token defined") ; let resp = fetch('https://auth.api.platform.sh/oauth2/token', { method : 'POST', headers : { 'Content-Type' : 'application/x-www-form-urlencoded' }, body : "client_id=platform-api-user&grant_type=api_token&api_token=" + variables.api_token }) ; if (!resp.ok) { console.log("Failed to get an OAuth2 token, status code was " + resp.status) ; } else { console.log("OAuth2 API TOKEN ok") ; } let access_token = resp.json().access_token ; // get current branch from activity object let branch ; switch (activity.type) { case 'environment.synchronize' : branch = activity.parameters.into ; break ; case 'environment.branch' : case 'environment.activate' : branch = activity.parameters.environment ; break ; } // exécuter l'opération runtime runtime_operation_name sur l'environnement actuel/ciblé resp = fetch("https://api.upsun.com/api/projects/" + activity.project + "/environments/" + branch + "/deployments/current/operations", { headers : { "Authorization" : "Bearer " + access_token }, method : "POST", body : JSON.stringify({"service" : app_container, "operation" : runtime_operation_name}), }) ; if (!resp.ok) { console.log("Failed to invoke the runtime operation, status code was " + resp.status) ; } else { console.log(runtime_operation_name + " launched") ; } }

Ce script d'activité utilise un jeton API, en tant que variable d'environnement, pour se connecter à l'environnement actuel et exécuter l'opération d'exécution définie précédemment à l'aide de l'API Upsun. Nous devons définir cette variable d'environnement pour l'intégration de notre script d'activité, et ajouter plus tard une variable d'environnement API Token.

Ensuite, poussez votre fichier sur la branche principale et déployez-le, comme suit :

symfony checkout main git add src/runtime/sanitize.js git commit -m "add activity script" symfony deploy

Ajouter une intégration d'un script d'activité

Trois événements Upsun doivent déclencher cette opération d'exécution :

  • Lors de la création d'une nouvelle branche (environment.branch),
  • Lors de la synchronisation des données entre les environnements (environment.synchronize),
  • Lors de l'activation d'un environnement de prévisualisation (environment.activate) .

Pour mettre en place ces déclencheurs, utilisez cette commande dans votre terminal pour ajouter une intégration de script d'activité.

symfony integration:add --type script --file ./src/runtime/sanitize.js --events environment.branch,environment.synchronize,environment.activate --states complete --environments \*

Remarque: une liste complète des événements possibles est disponible dans la définition du type de script d'activité. N'importe lequel de ces types de scripts d'activité peut être ajouté en tant que liste d'événements dans l'option --events=event1,event2,....

Ajouter une variable d'environnement API Token

Tout d'abord, obtenez l'ID de l'intégration précédente en utilisant la commande suivante :

symfony integration:list

Ensuite, créez un nouveau Token API depuis la Console, gardez la valeur en main, et remplacez-la dans cette commande du terminal :

symfony project:curl /integrations/<INTEGRATION_ID>/variables -X POST -d '{"name" : "api_token", "value" : "<API_TOKEN>", "is_sensitive" : true, "is_json" : false}'

Remarque: remplacez <INTEGRATION_ID> et <API_TOKEN> par les valeurs correspondantes créées précédemment.

Vous pouvez vérifier que la variable a été créée avec cette commande :

symfony project:curl /integrations/<INTEGRATION_ID>/variables

Il est temps de tester

Pour tester si tout a fonctionné, dans la Console ou avec le CLI, déclenchez la création d'une nouvelle branche à partir de main, déclenchez une synchronisation, désactivez et réactivez votre environnement de prévisualisation, et vous devriez alors voir deux activités :

  • Activité déclenchée
  • Une activité d'opération en cours d'exécution

Vous rencontrez un problème ? Déboguez-le

Si vous rencontrez un problème et que vous souhaitez déboguer l'intégration du script d'activité, vous devez utiliser la commande suivante :

symfony integration:activity:log <INTEGRATION_ID>

Lorsque vous ajoutez l'intégration de votre script d'activité, le script correspondant est ajouté en mémoire du côté d'Upsun. Cela signifie qu'à chaque fois que vous mettez à jour votre script, vous devez mettre à jour la version en cache du fichier, en utilisant la commande suivante : symfony integration:update <INTEGRATION_ID> :

symfony integration:update <INTEGRATION_ID> --file ./src/runtime/sanitize.js

Remarque: bien entendu, pour maintenir votre code source à jour, vous devez livrer ce fichier :

git add src/runtime/sanitize.js git commit -m "add activity script" symfony deploy # optional

5) Comment utiliser des scripts shell pour assainir les environnements de développement

Il est possible d'utiliser un script shell pour automatiser l'assainissement des données de tous vos environnements, à l'exception de la production, pour tous vos projets au sein d'une organisation - apprenez-enplus sur les organisations ici. Pour utiliser ce script shell, veuillez vous assurer que toutes vos sources d'environnement de tous vos projets au sein de votre organisation contiennent la commande Symfony pour assainir les données, avant de suivre les étapes suivantes.

La première étape consiste à créer un fichier nommé fleet_sanitizer.sh avec le code suivant :

if [ -n "$ZSH_VERSION" ] ; then emulate -L ksh ; fi ###################################################### # script de démonstration de l'assainissement de la flotte, en utilisant l'interface de programmation.
# # Active le flux de travail suivant sur un projet donné et assainit les environnements de prévisualisation (environnement staging, new-feature et auto-updates) : # . # └── main # ├── staging # | └── new-feature # └── auto-updates # # Utilisation # 1. sourcez ce script : `. fleet_sanitizer.sh` ou `source fleet_sanitizer.sh` en fonction de votre machine locale # 2. define ORGANIZATION var : ORGANIZATION=<organizationIdentifier> # 3. exécuter `sanitize_organization_data $ORGANIZATION` ###################################################### # Fonctions utilitaires # list_org_projects : Affiche la liste des projets sur lesquels l'opération sera appliquée avant de commencer. # $1 : Organisation, telle qu'elle apparaît dans console.upsun.com. list_org_projects() { symfony project:list -o $1 --columns="ID, Title" } # get_org_projects : Récupère un tableau d'identifiants de projets pour une organisation donnée. # Note : Rend la variable PROJECTS disponible pour les scripts suivants. # $1 : Organisation, telle qu'elle apparaît dans console.upsun.com. get_org_projects() { PROJECTS_LIST=$(symfony project:list -o $1 --pipe) PROJECTS=($PROJECTS_LIST) } # get_project_envs : Récupère un tableau d'IDs d'envs pour un projet. # Note : Rend la variable ENVS disponible pour les scripts suivants. # $1 : ProjectId, tel qu'il apparaît dans console.upsun.com. get_project_envs() { ENV_LIST=$(symfony environment:list -p $1 --pipe) ENVS=($ENV_LIST) } # list_project_envs : Imprimer la liste des envs sur lesquels l'opération sera appliquée avant de démarrer. # $1 : ProjectId, tel qu'il apparaît dans console.upsun.com. list_project_envs() { symfony environment:list -p $1 } # add_env_var : Ajouter une variable d'environnement au niveau de l'environnement. # $1 : Nom de la variable. # $2 : Valeur de la variable. # $3 : ID du projet cible. # $4 : ID de l'environnement cible. add_env_var() { VAR_STATUS=$(symfony project:curl -p $3 /environments/$4/variables/env:$1 | jq '.status') if [ "$VAR_STATUS" != "null" ] ; then symfony variable:create --name $1 --value "$2" --prefix env : --project $3 --environment $4 --level environment --json false --sensitive false --visible-build true --visible-runtime true --enabled true --inheritable true -q else printf "\nVariable $1 existe déjà. Sauter." fi } # Fonctions principales. sanitize_organization_data() { list_org_projects $1 get_org_projects $1 for PROJECT in "${PROJECTS[@]}" ; do printf "\n#### Projet $PROJET."# obtenir la liste des environnements list_project_envs $PROJECT get_project_envs $PROJECT for ENVIRONMENT in "${ENVS[@]}" ; do unset -f ENV_CHECK ENV_CHECK=$(symfony project:curl -p $PROJECT /environments/$ENVIRONMENT | jq -r '.status') unset -f ENV_TYPE ENV_TYPE=$(symfony project:curl -p $PROJECT /environments/$ENVIRONMENT | jq -r '.type') if [ "$ENV_CHECK" = active -a "$ENV_TYPE" != production ] ; then unset -f DATA_SANITIZED DATA_SANITIZED=$(symfony variable:get -p $PROJECT -e $ENVIRONMENT env:DATA_SANITIZED --property=value) if [ "$DATA_SANITIZED" != true ] ; then printf "\nL'environnement $ENVIRONMENT existe et n'est pas encore assaini. Sanitizing data." printf "\n" # do sanitization here symfony ssh -p $PROJECT -e $ENVIRONMENT -- php bin/console app:sanitize-data printf "\nSanitizing data is finished, redeploying" add_env_var DATA_SANITIZED true $PROJECT $ENVIRONMENT else printf "\nEnvironment $ENVIRONMENT existe et n'a pas besoin d'être sanitizé. skipping." fi elif [ "$ENVIRONMENT" == main ] ; then printf "\nEnvironnement $ENVIRONMENT est en production, skipping." else printf "\nEnvironnement $ENVIRONMENT n'est pas actif $ENV_CHECK, skipping." fi done done }

Remarque: dans ce script, à chaque fois que nous assainissons un environnement, nous définissons la variable d'environnement DATA_SANITIZED afin de nous assurer que la prochaine fois que nous exécuterons ce script, il n'assainira pas l'environnement de manière répétée.

Ensuite, en fonction de la machine sur laquelle vous voulez exécuter ce script, veuillez adapter le code à vos besoins, mais il devrait ressembler à quelque chose comme ceci :

. fleet_sanitizer.sh # ou source fleet_sanitizer.sh ORGANIZATION=<organizationIdentifier> sanitize_organization_data $ORGANIZATION

Astuce: vous trouverez l'identifiant de l'organisation pour un projet spécifique en cliquant sur votre nom, puis sur paramètres dans le coin supérieur droit de l'écran.

Et juste comme ça, vos données sont assainies et vous êtes sur la bonne voie pour être en conformité avec le GDPR !

Si vous avez d'autres questions sur nos capacités en matière de sécurité et de conformité ou si vous rencontrez des problèmes avec les méthodes et/ou les étapes ci-dessus, contactez notre équipe d'assistance qui se fera un plaisir de vous aider.

Restez au courant des dernières nouvelles sur nos médias sociaux et nos canaux communautaires. Retrouvez-nous sur Dev.to, Reddit et Discord.

Votre meilleur travail
est à l'horizon

Essai gratuit
Discord
© 2025 Platform.sh. All rights reserved.