Blog

3x en 3 ans : faire évoluer une organisation d'ingénierie

par Shekhtmeyster romain 27 juillet 2017 | 13 min de lecture

Il y a trois ans, j'ai rejoint une jeune entreprise en plein essor appelée PagerDuty en tant que responsable de l'ingénierie. Après avoir reçu un financement de série A en 2013, l'entreprise était en phase d'hyper-croissance et recrutait massivement dans tous les domaines. L'équipe d'ingénierie comptait moins de 30 personnes à l'époque, et l'un de mes principaux atouts était (et est toujours) d'apprendre à connaître les défis structurels auxquels est confrontée une organisation en croissance rapide. Alors que nous approchons des 100 Dutoniens en ingénierie, il semble approprié de revenir en arrière et de réfléchir aux changements intervenus jusqu'à présent.

L’évolution des structures organisationnelles est un processus fascinant, plein d’erreurs, d’impasses, de réinventions et, espérons-le, de leçons apprises. Il existe de nombreux ouvrages sur les organisations d’ingénierie, dont la plupart se résument à des listes abstraites d’avantages et d’inconvénients ou à des billets de blog qui vantent le processus que l’entreprise a adopté au moment de la rédaction. Je souhaite adopter une approche différente et examiner les raisons historiques qui ont poussé notre équipe d’ingénierie à expérimenter et à faire évoluer en permanence notre structure, avec tous les faux pas et les apprentissages qui en découlent.

Remarque : certains événements et détails ont été simplifiés pour les besoins du récit. La plupart d’entre eux méritent d’être publiés dans un article à part entière. Ajoutez ce blog à vos favoris pour rester à l’affût des nouveaux contenus.

L'organisation cloisonnée

PagerDuty début 2014 ressemblait à ceci :

  • L’organisation d’ingénierie a été divisée entre les bureaux de San Francisco et de Toronto.
  • L'équipe Opérations était responsable de l'automatisation de l'infrastructure, de la sécurité et de la persistance (SF uniquement).
  • L'équipe d'applications Web était responsable des aspects clients de PagerDuty (SF uniquement) et développée principalement avec Ruby on Rails et MySQL.
  • Le groupe de services back-end était responsable de l'ingestion fiable des données et de la diffusion des notifications (divisé en équipes colocalisées à SF et à Toronto) et développé principalement avec Scala et Cassandra.
  • Il n'y avait qu'une adhésion partielle à DevOps : l'équipe des opérations était de garde pour les alertes de surveillance de l'infrastructure, d'autres équipes sur appel pour le code qu'ils ont déployé .

Alors que l'ingénierie est passée d'une petite poignée de personnes à plusieurs équipes dispersées en très peu de temps, le processus de développement de produits est resté plutôt immature. Malgré les signes superficiels d'agilité avec les stand-ups et les sprints, nous utilisions essentiellement les Modèle de cascade . La direction a défini les projets sur lesquels travailler, a affecté les ingénieurs à ces projets et a fixé les dates de livraison cibles. Comme on pouvait s'y attendre, les dates étaient rarement respectées et les feuilles de calcul de suivi des projets étaient dans un état de désuétude perpétuel, et finalement tombées en désuétude.

Sur le terrain, les choses ne se présentaient pas mieux. Les chefs de produit ont lancé les nouveaux projets en rédigeant de longues spécifications de conception fonctionnelle, en faisant de leur mieux pour anticiper les éventuelles questions qui pourraient survenir, une conséquence du fait que les équipes Produit et Ingénierie n'interagissaient pas beaucoup pendant le développement ! Les spécifications ont été présentées aux équipes Web Application et Backend Services, qui ont ensuite travaillé sur les aspects utilisateur et backend de manière indépendante. Les nouvelles demandes d'infrastructure devaient être adressées à l'équipe Opérations des semaines à l'avance.

Intégrer tous ces efforts distincts dans une version cohérente des fonctionnalités a été un cauchemar. Nous avions une infrastructure manquante ou incomplète, des bugs brûlants, des lacunes fonctionnelles (chaque équipe pense que l'autre s'en occupe), un manque d'appropriation ou d'autonomie pour les ingénieurs et les responsables produits, des dates manquées et des silos organisationnels. Le désir de respecter les dates nous a amenés à prendre moins de risques et nous sommes devenus plus conservateurs dans nos implémentations ainsi que réticents à ajuster les spécifications du produit.

Cette combinaison de structure départementale et de processus de développement a propulsé le sujet du cloisonnement au premier plan de toutes les autres discussions au sein de l'ingénierie cette année-là. Et bon sang, nous avions des cloisonnements :

  • Applications Web et services back-end. La tension était palpable entre les deux groupes. Aucun des deux ne comprenait vraiment sur quoi travaillait l'autre groupe et tous deux étaient frustrés.
  • Ruby contre Scala. Des lignes de conflit similaires à celles décrites ci-dessus, avec beaucoup de démantèlement du vélo et de construction identitaire autour de langues spécifiques.
  • Équipes d'exploitation et de développement. Les deux parties étaient frustrées par le fait que l'équipe d'exploitation constituait un goulot d'étranglement pour l'approvisionnement de tous les serveurs. Les opérations subissaient également une forte pression en raison des délais imminents.
  • San Francisco contre Toronto. Avec toutes les équipes situées au même endroit, une ambiance « eux contre nous » distincte s’est développée entre les ingénieurs des deux sites. Les deux parties ont trouvé matière à grogner.

Les responsabilités strictement définies ne laissaient pas beaucoup de place aux équipes pour une collaboration interfonctionnelle. Nous avons expérimenté brièvement le concept de « groupes de travail » : de petites équipes temporaires et diversifiées, composées de membres des équipes existantes, dans le but de travailler sur des projets transversaux, limités dans le temps et à portée limitée. Ces groupes ont fini par introduire davantage de chaos en déstabilisant les équipes principales, et l’expérience a donc été abandonnée.

Il était néanmoins primordial de collaborer et de fournir des résultats plus cohérents et plus prévisibles. Tout le monde en avait assez du cloisonnement, il fallait donc y mettre un terme. Nous avions du pain sur la planche.

L'organisation de la matrice

Début 2015, l'insatisfaction face à la situation actuelle et l'intérêt croissant pour les méthodologies Agile ont atteint une masse critique et ont entraîné un remaniement départemental. Plusieurs nouvelles équipes ont été formées autour d'orientations produit spécifiques. Elles ont suivi le processus Scrum et étaient composées d'ingénieurs des équipes d'applications Web et de services back-end, ainsi que de propriétaires de produits, de Scrum Masters et de concepteurs UX.

Compte tenu du rythme de progression moins qu’idéal du produit au cours de l’année précédente, les nouvelles équipes ont été optimisées pour la livraison du produit. Pour s’assurer qu’elles puissent consacrer 100 % de leur temps à la création de nouvelles fonctionnalités, les tâches de maintenance ont été déléguées aux équipes des services back-end. Celles-ci sont devenues connues sous le nom d’« équipes de base » à mesure qu’elles adoptaient Méthodologie Kanban et a pris en charge la propriété de tous les services de production, y compris tous les produits responsabilités de garde . De plus, les équipes de base alimentaient les équipes de produits : les ingénieurs migraient de l’une à l’autre à mesure que le travail sur les produits augmentait.

Il s'agissait évidemment de changements importants. Dans un effort pour minimiser l'impact du remaniement des équipes sur les ingénieurs individuels (et pour retarder la gestion des rapports à distance), les relations hiérarchiques n'ont pas été modifiées. Cela a bien sûr énormément compliqué la vie de tout le monde, car nous avions désormais une double structure hiérarchique, également appelée organisation matricielle ! De nombreux ingénieurs se sont retrouvés dans des équipes qui n’étaient pas rattachées à leur supérieur hiérarchique direct et les managers jouaient désormais le rôle de « gestionnaire de personnes » (responsables de personnes dont certaines étaient dans d’autres équipes) et de « gestionnaire fonctionnel » (responsable d’équipes dont certains ingénieurs étaient rattachés à d’autres équipes).

La bonne nouvelle est que les anciens silos ont été en grande partie détruits et ne seront plus jamais revus. Les ingénieurs d'applications Web travaillant en étroite collaboration avec les ingénieurs des services back-end ont pu voir au-delà des différences de chacun et progresser vers des objectifs communs. La plupart des équipes étaient désormais également dispersées géographiquement, ce qui a fait des merveilles pour rapprocher les deux bureaux.

La mauvaise nouvelle est qu’une série de nouveaux problèmes ont été introduits :

  • Il était très difficile de fédérer une équipe autour de la maintenance technique. Les équipes de base ont eu du mal à établir des feuilles de route à long terme et à accepter la propriété opérationnelle de tous les services de production.
  • Le modèle de recrutement a eu un impact très réel sur la cohésion de l’équipe Il s’avère que changer sans cesse la composition de l’équipe n’est pas très bon pour le moral.
  • La structure de reporting double a créé de nombreuses inefficacités. Il y avait un manque de visibilité sur les activités quotidiennes d’un subordonné direct, des frais de communication supplémentaires entre les responsables du personnel et les responsables fonctionnels, et une confusion générale autour des responsabilités.
  • Nous avons adopté des processus Agile, plutôt que l'agilité . Scrum a certainement aidé à la surspécification, à l'intégration et à l'implication des propriétaires de produits. Cependant, notre approche de la livraison de logiciels n'a pas changé : les versions de fonctionnalités étaient toujours des affaires de grande envergure qui apportaient une valeur douteuse.
  • Plus d'équipes signifiait plus de charge pour le personnel des opérations. Avec des demandes d’infrastructure fréquentes et des responsabilités d’astreinte supplémentaires pour chaque nouveau service, il est clair que cette approche n’était pas évolutive.

Tout bien considéré, nous étions encore dans une bien meilleure forme qu’il y a un an. Mais il restait encore un long chemin à parcourir.

L'organisation agile

Après avoir vécu avec la nouvelle structure organisationnelle pendant un an, nous avons accumulé beaucoup d'apprentissages. Agile était bon (mais nous ne l'avons pas assez utilisé), DevOps était bon (mais nous ne l'avons pas assez utilisé), la gestion matricielle n'était pas si bonne (et nous en avions assez).

Début 2016, nous avons procédé à une nouvelle restructuration. Les équipes Scrum « verticales » étaient désormais responsables de certaines parties du produit. Les équipes « horizontales » étaient responsables des problèmes transversaux liés au produit ou à l’infrastructure, et étaient chargées de définir les meilleures pratiques et de permettre aux autres équipes d’avancer rapidement. Les équipes de livraison des produits étaient responsables de leur feuille de route, de la définition des exigences, de la mise en œuvre, du déploiement et de la maintenance de leur code et de leur infrastructure (!) en production. Nous avions adopté une véritable approche DevOps. vous le codez, vous en êtes propriétaire ' approche.

Comment cela a-t-il résolu nos préoccupations précédentes ?

  • Plus d'équipes de maintenance. Chaque équipe possédait une partie du produit ou de l’infrastructure et était habilitée à évoluer rapidement et à innover.
  • Plus d'équipes de relève. Le décompte a été ouvert pour des équipes spécifiques.
  • Fini les doubles déclarations ! En tant qu'entreprise, nous sommes devenus beaucoup plus à l'aise avec le recrutement et la gestion d'ingénieurs à distance. La distance physique n'étant plus un obstacle, nous avons pu affecter des responsables à des équipes sans aucune relation de travail en pointillé.
  • Nous nous concentrons sur l’accomplissement des tâches. Le mantra GSD (Get Sh*t Done) imprègne notre conscience collective, mettant au défi les équipes d'introspecter et de se débarrasser de l'héritage de surspécification et de sur-ingénierie afin de devenir des machines de livraison pragmatiques, productives et agiles.
  • Croissance facilitée par le libre-service. L'équipe des opérations a fait beaucoup de travail pour responsabiliser les équipes de livraison de produits, notamment en leur fournissant des Outils ChatOps pour répondre en autonomie à toutes sortes de besoins d'infrastructure. Cela a été essentiel pour adopter DevOps à tous les niveaux et déplacer les alertes d'infrastructure hors des opérations vers les équipes concernées possédant les hôtes réels (qui pouvaient de toute façon résoudre les problèmes plus rapidement).

Le sujet de la GSD mérite d'être approfondi un peu plus. Grâce à la pratique, nous sommes devenus de plus en plus à l'aise avec les idées d'autonomie de l'équipe, innovation plutôt qu'invention , et les entreprises apportent des problèmes à résoudre plutôt que des solutions à mettre en œuvre. Il n'est pas facile d'abandonner l'idée que nous savons ce qui est le mieux pour les clients. Une concentration laser sur la fourniture de la produit minimum viable , et rechercher un feedback immédiat et l’intégrer au cycle de développement a été essentiel. Cela nous a permis d’itérer rapidement, de maximiser la valeur, de minimiser la sur-réglementation et de raccourcir le délai de mise à disposition d’un prototype entre les mains du client, de plusieurs mois à quelques jours ou semaines. En d’autres termes, nous sommes passés d’une organisation qui « suit des processus agiles » à une véritable organisation agile.

À mesure que le nombre d’équipes de livraison de produits augmentait, un phénomène intéressant s’est développé : nous avons assisté à l’émergence de ce que l’on appelle les « tribus » (merci à Le modèle d'équipe de Spotify ); c'est-à-dire des groupes d'équipes liées les unes aux autres par une fonctionnalité commune ou une mission commune. Ces arrangements ont donné lieu à des avantages tels qu'une propriété partagée, des connaissances partagées, une feuille de route partagée (séparée des arriérés des équipes individuelles) et une vision partagée. L'organisation tribale est quelque chose que nous expérimentons encore - restez à l'écoute pour les mises à jour futures sur nos apprentissages avec les tribus.

Nous utilisons cette structure depuis 16 mois maintenant et elle fonctionne parfaitement. Il est certain que les équipes et les structures de propriété associées évolueront à mesure que l'entreprise continuera de croître à un rythme soutenu, et certains détails changeront à mesure que nous continuerons d'investir pour nous améliorer. En même temps, il est clair que nous avons fait suffisamment de mauvaises choses pour apprendre à quoi devrait ressembler la bonne chose.

Leçons apprises

En repensant à certaines des décisions prises au début et à certains des états intermédiaires difficiles que notre organisation a traversés, je suis tenté de me frapper la tête et de me demander pourquoi il ne nous est pas venu à l’idée de passer à l’état final manifestement supérieur. La réalité, bien sûr, n’est jamais aussi simple : ces décisions étaient fonction de notre état, de nos priorités, de nos collaborateurs et de nos défis. à l'époque Vous avez peut-être également reconnu certains de vos propres défis, auquel cas j'espère que vous pourrez tirer quelque chose de notre expérience.

Si je devais tout recommencer, voici les enseignements que j’emporterais avec moi :

  • Minimiser les dépendances entre les équipes Les dépendances entraînent des blocages, des bugs, des malentendus et des ressentiments. Donnez aux équipes les moyens de livrer sans attendre les autres et vous constaterez des améliorations majeures de productivité.
  • Minimiser les changements dans la composition de l’équipe . Les réalités du monde des affaires imposent parfois de déplacer des ressources d'un endroit à un autre. Réfléchissez bien avant de déplacer des personnes, car cela peut avoir de graves répercussions sur le moral et la productivité de l'équipe.
  • Ne prescrivez pas de manière excessive la propriété et les responsabilités de l'équipe . La flexibilité ici conduit à des gains à long terme. Encouragez les équipes à résoudre leurs propres problèmes et vous aurez moins de problèmes avec les deux points précédents.
  • N'ayez pas peur de l'apprentissage continu et de l'expérimentation . Cela s'applique à tout : code, processus, organisation. On ne s'améliore pas en faisant toujours les mêmes choses.
  • Les processus agiles sont bien, la culture agile est encore meilleure r. Les réunions debout et les revues de sprint n'apportent pas beaucoup de valeur en elles-mêmes. Se concentrer sur le produit minimum viable, les boucles de rétroaction rapides et la collaboration nécessite un changement culturel, mais maximise la valeur client fournie.
  • Opérationnel la propriété du code doit appartenir aux équipes C’est le meilleur moyen d’équilibrer la fiabilité du système, la qualité du code et l’évolutivité organisationnelle.
  • Les équipes polyvalentes et interfonctionnelles sont idéales pour la livraison de produits . Cela correspond tout à fait au point de minimisation des dépendances ci-dessus. Chaque équipe doit pouvoir passer de la collecte des exigences au déploiement sans avoir besoin de faire appel à des experts extérieurs ou de transférer des projets. Les équipes spécialisées ont leur place, mais davantage dans le domaine des équipes « horizontales » évoquées précédemment.
  • Embauchez des généralistes qui peut fonctionner dans n'importe quel environnement. Les membres de l’équipe ne doivent pas lier leur identité à des outils, cadres et piles spécifiques à mesure que les technologies et les orientations techniques évoluent. Les personnes les mieux placées pour prospérer dans un environnement à forte croissance sont celles qui se concentrent sur l’apprentissage et l’utilisation du bon outil pour leur travail. Par conséquent, soyez prêt à offrir ces opportunités d’apprentissage et de croissance.
  • Évitez la gestion matricielle si vous pouvez l’éviter . Examinez s’il existe d’autres moyens de résoudre les problèmes que la double déclaration semble résoudre.
  • Adoptez les équipes distribuées Construire des équipes soudées avec des membres distants n’est pas sans défis, mais les avantages sont nombreux. Martin Fowler souligné que, ' En créant une équipe à distance, vous pouvez élargir le nombre de personnes que vous pouvez intégrer à l'équipe. Une équipe à distance peut être moins productive que cette même équipe si elle était colocalisée, mais peut toujours être plus productive que la meilleure équipe colocalisée que vous puissiez former. « En d’autres termes, autoriser les membres à distance crée un bassin de recrutement beaucoup plus large, ce qui vous permet de constituer une équipe globale plus solide.

À mesure que les organisations grandissent et mûrissent, elles ont tendance à ralentir, à se calcifier et à devenir plus conservatrices. En pratiquant l'amélioration continue et en faisant évoluer nos pratiques, nous avons réussi à inverser la tendance et à devenir plus agiles, pragmatiques et productifs au fil du temps. Et vous pouvez faire de même.

Voici trois (et de nombreuses) années supplémentaires d’apprentissage !