Montée en compétence, autonomie : vive l'infogérance collaborative

L'infogérance collaborative permet de concilier vélocité, transparence, autonomie pour le client avec rigueur, contrôle et traçabilité pour l’infogéreur.

Pourquoi ?
L’infogérance classique s’articule autour d’une relation « donneur d’ordre vs exécutant » où le prestataire en charge du SLA, opère tout changement en production en raison, des impératifs de résultats qui lui incombent (SLA, sécurité de la plateforme, etc). A différents égards, ce mode de fonctionnement s’apparente à un anti pattern DevOps.

Dans ce schéma, quand un éditeur de logiciel en SaaS signe un nouveau client, il est amené à formuler plusieurs demandes d’évolutions de sa plateforme de production à son prestataire d’infogérance via une interface de ticketing (création d’un vHost, installation d’un certificat, création d’un volume NFS, création d’un User MySQL et d’une base de données client, ouverture de flux, modification des playbooks de deploiement etc).

Ce mode opératoire crée une frustration auprès des interlocuteurs techniques côté client qui depuis quelques années sont montés en compétence sur les sujets DevOps et infrastructure.
Le client se trouve tributaire du temps de traitement du prestataire pour une demande qu’il aurait pu réaliser lui-même (ex : ajout d’un vHost, modification d’un paramètre de configuration simple, lancement d’une sauvegarde avant un déploiement, resizing d’une instance ou d’un disque etc.).

C'est pourquoi, Claranet propose aujourd’hui des modes de co-infogérance fortement inspirés des concepts de pair programming et de peer review, autrement appelés infogérance collaborative. Les équipes Claranet travaillent ainsi étroitement avec les équipes techniques de nos clients Software Platforms & Providers et appliquent une méthodologie de co-construction, de partage de connaissance et d’apprentissage.

1. Infogérance Collaborative : Vault, Gitlab et Terraform

Guidelines et Bonnes pratiques

Nous avons de plus en plus de demandes de clients voulant partager l'infogérance de leur plateforme (surtout en heures ouvrées), que ce soit au niveau de l'infrastructure avec Terraform, ou au niveau middleware avec Ansible ou Chef. Nous avons donc mis en place des bonnes pratiques et standards pour aborder ce mode de collaboration afin d'éviter les dérives et de garantir une co-gestion efficace de la plateforme en phase de Run.

DevOps, montée en compétences et autonomie des équipes techniques : lire le témoigange de Kizeo

Cas client
Un de nos clients nous demande de partager avec lui le code Terraform, et veut proposer des modifications (ajout/modification/suppression de ressources) sur sa plateforme AWS.

Le mode d’infogérance standard, dans lequel nous utilisons Terraform en interne, impose quelques contraintes :

  • Les dépôts Gitlab du client : aucun client n'a accès à notre Gitlab interne pour des raisons de sécurité et de gestion de droits complexes.
  • Les modules Terraform sont hébergés sur notre Gitlab, inaccessible pour les clients. Difficile donc pour eux de proposer des modifications puisqu’ils ne possèdent ni la doc interne ni la logique à disposition. Des considérations relatives à la réversibilité nous imposeraient également de leur fournir les modules Terraform d'une manière ou d'une autre.
  • Vault : nous utilisons AWS STS et Vault afin de générer des Token temporaires à chaque Run Il faut réussir à garder ce même système. Également, tous les crédentials client sont maintenant dans Vault et sont récupérés par le provider Terraform (mot de passe AWS RDS par exemple).
  • L'image Docker utilisée par Gitlab CI est actuellement sur notre registry AWS privé et le code de cette image n'est pas public.

L'idée est donc de reprendre la manière dont nous utilisons Terraform et Gitlab CI en interne mais de la mettre à disposition du client.

Nous avons aussi posé quelques prérequis :

  • Que le code soit toujours accessible facilement par n'importe quelle personne faisant du run (idéalement avec son compte Active Directory)
  • Que la gestion des secrets se fasse toujours via notre Vault ou solution équivalente (AWS Secret Manager, Azure Key Vault etc…)
  • Que toute modification opérée en production se fassent via l’execution d’un job GitlabCI (zéro exception !)
  • Reprendre le même workflow que nous avons actuellement :
  • Infogerancecollab_Schema1_V1.png

    Le client n'aura dans un premier temps pas accès en écriture à la branche master et nous fera des merge requests. Il est tout à fait possible de lui donner les accès à la branche master après une certaine période ou de le lui retirer si des abus sont constatés…

    Plateforme de services
    Nous sommes donc partis sur la solution suivante :

  • Créer une plateforme que nous appellerons "plateforme de services" avec un VPC dédié et une connexion VPN (pas toujours nécessaire). Ce code ne sera pas partagé avec le client. Certains clients ont déjà̀ cette stack sous un autre nom : support, tools etc.
  • Mettre en place un Gitlab dédié́ par client voulant faire de l'infogérance collaborative avec son runner dédié́ sur lequel nous transférons les dépôts Terraform que nous avons actuellement en interne. Ce Gitlab servira également si le client souhaite ensuite faire de l'infogérance collaborative avec Ansible.
  • Voici un schéma pour résumer sur AWS :

  • 1 VPC dédié
  • 1 instance Gitlab avec un runner
  • L'accès à Vault via le public
  • Infogerancecollab_Schema2_V1.png

    Ou encore sur Google Cloud :

  • 1 projet dédié
  • 1 instance Gitlab avec un runner
  • L'accès à Vault via le public
  • Infogerancecollab_Schema3_V1.png

    Afin de faciliter le déploiement de cette stack, deux nouveaux modules Terraform ont été créés :

    • Un pour Google Cloud Platform
    • Un pour AWS
    • Ceux-ci permettent en (quasiment) un seul run Terraform de créer l'ensemble de la stack.

    variable "client" { default = "ClientsuperDEVOPS"
    }
    variable "region" { default = "eu-west-1"
    }
    module "tools" {
      source = "git::ssh://XXXX.git-01.adm/terraform
    /aws-tools-project.git"
      client          = "${var.client}"
      region          = "${var.region}"
      vpc_cidr_block  = "10.134.164.0/22"
      private_subnets = ["10.134.164.0/24"]
      public_subnets  = ["10.134.165.0/24"]
      azs             = ["eu-west-1a"]
      peer_vpc_id_svc     = "vpc-xxxxxx"
      customer_gateway_ip = "X.X.X.X"
      gitlab_allowed_ip = ["X.X.X.X/32", "X.X.X.X/32"]
      gitlab_zone = "eu-west-1a"
      gitlab_create_bucket = false
      public_key = "${data.vault_generic_secret.sshkey.data["p
    ub"]}"
    }
    data "vault_generic_secret" "sshkey" {
      path = "secret/clients_shared_pwd/${var.client}/ssh/compte_admin"
    }

    Ce module va créer une instance EC2 Gitlab à partir de l'AMI Debian officielle. La clé publique du client (utilisée par les bastions) doit avoir été renseignée dans Vault afin que l'on puisse se connecter avec l'utilisateur admin une fois l'instance UP.

    2. Gitlab et Ansible

    Installation
    Pour faciliter et accélérer le déploiement de Gitlab et du runner avec Docker, nous avons décidé de créer quelques rôles Ansible :

    • Un pour installer Gitlab
    • Un pour installer Docker
    • Un pour installer Gitlab Runner

    Configuration de l'authentification SAML
    Un des pré-requis est de pouvoir accéder facilement aux dépôts mis à disposition du client par n'importe quelle personne de la production, comme c'est le cas actuellement avec notre Gitlab. L'idée étant de ne pas avoir à créer un compte par personne sur chacun des Gitlab de nos clients.
    Nous avons d’abord choisi une authentification LDAP mais après discussion en interne, la mise en place de l'authentification via SAML et notre portail semble bien meilleure :

    • Pas besoin d'un accès à un répliqua Active Directory via une connexion VPN
    • Pas d'accès spécifique à créer pour chaque Gitlab sur Active Directory
    • Pas de double authentification si on est déjà connecté sur le portail

    La mise en place de l'authentification SAML sur Gitlab est en fait assez simple, avec l'utilisation du role Ansible.

    3. Vault et AppRole

    Vault est utilisé en interne pour la génération de token AWS STS valable 1h (via le backend Vault STS). Cela permet d’assurer que nous n’avons aucune clé AWS qui se balade dans la nature. Afin d'avoir accès à Vault lors des déploiements avec Gitlab CI, il est nécessaire de créer un AppRole avec une policy dédiée au client. Il est désormais possible de faire directement des MR sur le projet Vault.

    Une fois l'AppRole et la policy créée, nous avons besoin de deux choses pour créer des token Vault :

  • D'un role_id: créé une fois et que ne change pas
  • D'un secret_id: qui sera à renouveler chaque jour
  • Le role_id sera positionné directement en variable d'environnement sur le runner Gitlab, le secret_id est ajouté chaque jour en tant que protected variable au niveau de chaque projet Gitlab utilisant Terraform.

    Infogerancecollab_Schema4_V1.pngVoir la documentation officielle pour plus d’informations sur l’utilisation et le fonctionnement des AppRole.

    4. Pipeline et Image Docker

    Une fois que vous avez votre Gitlab avec l'authentification SAML, votre projet configuré avec le secret_id l'IP du Gitlab et autorisé sur le Vault Claranet, vous pouvez enfin configurer votre pipeline !
    Comme l'image Docker que nous utilisons n'est pas publique, en voici un exemple de pipeline:

     
    
    
    stages:
      - plan
      - apply

    image:
      name: hashicorp/terraform:0.11.13
      entrypoint: [""]

    variables:
      ACCOUNT_ID: "<account_id>"
      AWS_DEFAULT_REGION: "eu-west-1"
      VAULT_VERSION: "0.11.3"
      TMPFILE: vault_tmp

    .plan: &plan
      stage: plan
      tags:
        - docker
      before_script:
        - wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip && unzip vault_${VAULT_VERSION}_linux_amd64.zip
        - export VAULT_TOKEN=$(./vault write -field=token auth/approle/login role_id=$VAULT_ROLE_ID secret_id=$VAULT_SECRET_ID)
        - ./vault read aws/sts/manage-${ACCOUNT_ID} > ${TMPFILE}
        - export AWS_ACCESS_KEY_ID=$(grep access_key ${TMPFILE} | tr -s ' ' |cut -d ' ' -f2)
        - export AWS_SECRET_ACCESS_KEY=$(grep secret_key ${TMPFILE} | tr -s ' ' |cut -d ' ' -f2)
        - export AWS_SESSION_TOKEN=$(grep security_token ${TMPFILE} | tr -s ' ' |cut -d ' ' -f2)
        - cd terraform/${AWS_DEFAULT_REGION}
      script:
        - terraform init -input=false
        - terraform get -update
        - terraform plan -out=terraform.plan -input=false
      artifacts:
        paths:
          - terraform/${AWS_DEFAULT_REGION}/terraform.plan
          - terraform/${AWS_DEFAULT_REGION}/.terraform
          - vault_tmp
        expire_in: 1h

    Terraform Plan:
      <<: *plan

    .apply: &apply
      stage: apply
      tags:
        - docker
      before_script:
        - export AWS_ACCESS_KEY_ID=$(grep access_key ${TMPFILE} | tr -s ' ' |cut -d ' ' -f2)
        - export AWS_SECRET_ACCESS_KEY=$(grep secret_key ${TMPFILE} | tr -s ' ' |cut -d ' ' -f2)
        - export AWS_SESSION_TOKEN=$(grep security_token ${TMPFILE} | tr -s ' ' |cut -d ' ' -f2)
        - cd terraform/${AWS_DEFAULT_REGION}
      script:
        - terraform get -update
        - terraform apply -input=false terraform.plan
      after_script:
        - rm ${CI_PROJECT_DIR}/${TMPFILE}
      when: manual
      only:
        - master

    Terraform Apply:
      <<: *apply

    Conclusion

    L’implémentation technique ci-dessus et le mode opératoire de co-gestion de la codebase d’infrastructure en mode CI/CD permet de répondre aux attentes de toute les parties : vitesse, transparence et autonomie pour le client ainsi que rigueur, contrôle et traçabilité pour l’infogéreur. Ce mode opératoire remporte un franc succès avec nos clients les plus matures techniquement et permet de créer des relations d’infogérance Win-Win.

    Pour le client :

    • Réduction de 50 à 70% du nombre de demandes formulées via tickets
    • Meilleure utilisation des forfaits temps souscrits auprès de Claranet (temps passé sur du conseil vs temps passé sur des changements mineurs)
    • Visibilité et transparence sur la codebase de production
    • Augmentation de 25% à 50% du nombre de déploiement et du time to market
    • Montée en compétence des équipes du client. Elles peuvent s’approprier les sujets infra et DevOps de manière sereine car elles disposent d’un filet de sécurité grâce à la Peer Review

    Pour nos équipes de production :

    • Augmentation de l’attrait intellectuel des activités de Run. Plutôt que de clôturer des tickets bas niveaux (ajout ressources, redimensionnement disques, etc), l’activité de Run vise plutôt à retravailler les pipelines de CI afin d'automatiser les demandes récurrentes du client.
    • Réduction de la pression et des relances clients qui se trouvent bloqués dans l’attente du traitement du ticket
    • Conseils quotidiens à nos clients lors d’échanges autour des Merges Request (maintien dans le temps, lisibilité du code, bonnes pratiques de structuration des répertoires etc)

    Antares, une offre qui s'adapte à la maturité technique de vos équipes