CI/CD, le divorce serait-il prononcé ?

Nos deux tourtereaux

L’origine

cicd cicd.code

CI

Continuous Build

cicd cicd.build

Objectif : Construire l’applicatif

Continuous Integration

cicd cicd.integration

Objectif : Valider le code et les métriques

Bref…​

geek evolution

CD

Delivery

cicd cicd.delivery

Objectif : Mettre un livrable à disposition

Deployment

cicd cicd.deployment

Objectif : Deployer l’application

Development

cicd cicd.development

Objectif : S’assurer que le service fonctionne

Bref…​

geek evolution

La rencontre…​

cicd cicd split

Un avenir tout tracé !

cicd cicd

Yann

intervenants yann

Nicolas

intervenants nicolas

Découvrons la suite de leur histoire

Les petits pipelines

La définition d’un pipeline

cicd pipeline

C’est un dessin…​

Dessin

…​ Et des personnes

Personnes

Dis, comment on fait des pipelines ?

dis comment

step 1
step 1
step 1

Event storming

event storming

step 1
step 1
step 1

periodic[1]

step 1

Et voilà !

step 1

Petit pipeline deviendra grand …​

…​de manière itérative

agile loop

Ce que l’on conçoit bien s’énonce clairement, et les mots pour le dire arrivent aisément![1]

1. Nicolas Boileau

Une révolution arrive ?

L’élément perturbateur

Tous l’admiraient

red carpet

Gestion des sources

.angular
.idea
conf
dist
aws
build
docker
docs
node_modules
proxy-backend
src
.browserslistrc
.dockerignore
.editorconfig
.eslintrc.json
.gitignore
.prettierrc
angular.json
CHANGELOG.md
Dockerfile
docker-compose.yml
karma.conf.js
package.json
package-lock.json
README.md
tsconfig.app.json
tsconfig.json
tsconfig.spec.json
Jenkinsfile
launch.bat
site.yml

C’est le bordel

sacdenoeuds

C’est le bordel

.idea
api
docs
ihm
 | .angular
 | conf
 | src
 | .browserslistrc
 | .dockerignore
 | .editorconfig
 | .eslintrc.json
 | .prettierrc
 | angular.json
 | Dockerfile
 | karma.conf.js
 | package.json
 | package-lock.json
 | tsconfig.app.json
 | tsconfig.json
 | tsconfig.spec.json
infra
.gitattributes
.gitignore
.gitlab-ci.yml
docker-compose.yml
README.md

Fusionner les deux process

fusion

Comment aider notre petite famille ?

La thérapie de couple

DRY…​

Don’t Repeat Yourself

Exemple

deliver_npm_package:
  script:
    - ./is_it_friday.sh
    - npm publish # Livraison NPM
    - ./alert_ops_team.sh
    - ./send_an_email_to_PO.sh

deliver_app:
  script:
    - ./is_it_friday.sh
    - ftp -u myapp.tar.gz # Livraison FTP
    - ./alert_ops_team.sh
    - ./send_an_email_to_PO.sh
.deliver:
  before_script:
    - ./is_it_friday.sh
  after_script:
    - ./alert_ops_team.sh
    - ./send_an_email_to_PO.sh

deliver_npm_package:
  extends: .deliver
  script:
    - npm publish  # Livraison NPM

deliver_app:
  extends: .deliver
  script:
    - ftp -u myapp.tar.gz # Livraison FTP

Exemple

top-jobs.yaml
.deliver:
  variables:
    DELIVER_TASK: ''
  script:
    - ./is_it_friday.sh
    - $DELIVER_TASK
    - ./alert_ops_team.sh
    - ./send_an_email_to_PO.sh
gitlab-ci.yml
include:
  - project: 'devops-team/tools'
    file: 'top-jobs.yaml'

deliver_npm_package:
  extends: .deliver
  script:
    - npm publish

deliver_app:
  extends: .deliver
  script:
    - ftp -u myapp.tar.gz

…​mais pas trop !

Un couple SOLID ?

guylookingatgirl

Une responsabilité unique

SOLID (Single responsibility)

Exemple

package:
  image: node
  before_script:
    - # install my tools :-D
  script:
    - npm run build
    - sonar-scanner ...
    - docker build

single respo 1 bad

build:
  image: node
  script:
    - npm ...

analyse:
  image : sonar-scanner
  script:
    - sonar-scanner ...

publish:
  image: gcr.io/kaniko-project/executor:debug
  script:
    - /kaniko/executor ...

single respo 1 good

Exemple

deploy:
  script:
    - deploy-db.sh
    - deploy-app.sh
    - deploy-doc.sh

single respo bad

deploy_doc:
  ...

deploy_app:
  ...

deploy_db:
  ...

single respo good

Rester ouvert…​

SOLID (Open/Closed principle)

Exemple

.bad-sonar:
  variables:
    PROJECT_KEY: ''
  script:
    - |
        sonar-scanner -Dsonar.projectKey=$PROJECT_KEY
        -Dsonar.sources=./src
        -Dsonar.tests=tests/

open closed bad

.good-sonar:
  variables:
    PROJECT_KEY: ''
    SONAR_EXTRA_PARAMETERS: ''
  script:
    - sonar-scanner -Dsonar.projectKey=$PROJECT_KEY \
      -Dproject.settings=./sonar-project.properties \
      $SONAR_EXTRA_PARAMETERS

open closed good

Liskov à la rescousse…​

SOLID (Liskov substitution) …​ou pas !

Barbara Liskov[1]

1. Barbara Liskov

Ségrégation d’interface

SOLID (Interface segregation)

Exemple

template.yaml
build:            #Assemble le Jar
  stage: build
analyse-code:     #Faire les analyses qualité
  stage: test
analyse-package:  #Faire les analyses qualité
  stage: test
package:          #Construire l'image Docker
  stage: package
can-i-deploy:     #Faire les analyses qualité
  stage: test
deploy:           #Déploie dans l'infra
  stage: deploy

interface segragation bad

maven-template.yaml
build:            #Assemble le Jar
    ...
analyse-build:    #Faire les analyses qualité
    ...
docker-template.yaml
analyse-package:  #Faire les analyses qualité
    ...
package:          #Construire l'image Docker
    ...
terrform-template.yaml
can-i-deploy:     #Faire les analyses qualité
    ...
deploy:           #Déploie dans l'infra
    ...

interface segragation good

Une inversion de dépendance ?

SOLID (Dependency inversion)

Exemple

deliver-on-artifactory:
  script: ./push_artefact_to_repo.sh

deploy: # Attend que l'étape de livraison soit ok
  needs: [deliver-on-artifactory]
  script: ./deploy.sh

dependency inversion bad

# Doit déposer l'artefact au bon endroit
deliver:
  script: ./push_artefact_to_repo.sh

# Vérifie que l'artefact soit bien présent
check_artefact_readiness:
  script: ./check_artefact.sh

# Déploie si l'artefact est au bon endroit
# (contrat respecté)
deploy:
  needs: [check_artefact_readiness]
  script: ./deploy.sh

dependency inversion good

Un peu de lacher prise ?

Le risque du "tout automatique"

Exemple

Jenkinsfile.build
{
  ...,
  stage ('deliver') {
    build '../proj-deliver/master'
  }
}
Jenkinsfile.deliver
{
  stage('check requirements') {}
  stage('Deploy approval') {
    input "Deploy to prod ?"
  }
  stage ('deploy') {
    build '../proj-deliver/master'
  }
}
Jenkinsfile.deploy
{
  stage('check requirements') {}
  ...,
}
debrayable

Pouvoir debrayer !

Ou l’art de faire des pauses

Points d’inférence

decouplage

Oups …​

complexite

Le monde des Bisounours

bisounours

KISS : Keep It Simple Stupid

Qui est ce thérapeute ?

Un plan à trois

L’arrivée…​

devops arrival

La boucle est bouclée

devops

L’émergence

pipeline people devops

Des accompagnateurs

matrice maturite

Une question de communication

communication

Bref…​

geek evolution

Faisons le point

C’est l’heure du choix

ci ci cd

Séparation des responsabilités

  • ci Construction

  • ci Assemblage

  • ci Mise en service

  • ci Règles

ci ci cd

ci ci cd

cd

Et pourquoi pas…​

Proposer sans imposer, critiquer sans discréditer

Vecteur de la culture DevOps

cd

CI/CD, le divorce est-il prononcé ?

A vous de jouer !

@nicgiro / @YannSchepens

Références