DevOpsFacile
AccueilParcours de formationCertificationsModulesCheat SheetÀ Propos
DevOpsFacile

Une plateforme d'apprentissage complète pour maîtriser les pratiques DevOps modernes, du débutant à l'expert.

contact@devopsfacile.fr

Formation

  • Parcours de formation
  • Modules

Informations

  • À Propos
  • Conditions d'utilisation
  • Confidentialité
  • Mentions légales

© 2026 DevOps Facile. Tous droits réservés.

Fait avec pour la communauté DevOps

ModulesGCP - Intermédiaire : VPC, Cloud SQL, Cloud Run et Cloud Build07 - Pipeline CI/CD avec Cloud Build

Détails

  • 40 minutes
  • Intermédiaire

Objectifs

  • Créer un pipeline Cloud Build déclenché par un push Git
  • Builder une image Docker et la pousser dans Artifact Registry
  • Déployer automatiquement sur Cloud Run après un build réussi
  • Interpréter les logs et les résultats d'un build Cloud Build
Module GCP - Intermédiaire : VPC, Cloud SQL, Cloud Run et Cloud Build

Exercice 07 : Pipeline CI/CD avec Cloud Build

🎯 Objectifs

À la fin de cet exercice, vous serez capable de :

  • ✅ Écrire un fichier cloudbuild.yaml avec plusieurs étapes
  • ✅ Déclencher un build Cloud Build depuis la CLI ou un push GitHub
  • ✅ Builder une image Docker et la stocker dans Artifact Registry
  • ✅ Déployer l'image sur Cloud Run automatiquement

Durée estimée : 40 minutes

Difficulté : ⭐⭐⭐☆☆ (Intermédiaire)

Prérequis : Docker installé localement, notions Dockerfile, compte GitHub optionnel


📖 Contexte

Cloud Build est le service CI/CD serverless de GCP. Vous ne gérez pas de serveurs d'intégration continue (pas de Jenkins, pas de GitLab Runner à maintenir). Cloud Build exécute chaque étape dans un conteneur Docker isolé, ce qui garantit la reproductibilité. Il s'intègre nativement avec GitHub, GitLab et Cloud Source Repositories.


📋 Énoncé

Construisez un pipeline qui teste, build et déploie une application web.


🧭 Déroulement de l'exercice

Tâche 1 : Créer l'application et le Dockerfile

bash
# Activer les APIs
gcloud services enable cloudbuild.googleapis.com \
  artifactregistry.googleapis.com \
  run.googleapis.com

PROJECT_ID=$(gcloud config get-value project)
REGION=europe-west9

# Créer le projet applicatif
mkdir -p monapp && cd monapp

# Application web minimaliste (Python/Flask)
cat > app.py << 'EOF'
from flask import Flask, jsonify
import os

app = Flask(__name__)

@app.route('/')
def index():
    return jsonify({
        'message': 'Déployé avec Cloud Build !',
        'version': os.environ.get('APP_VERSION', '1.0.0'),
        'environnement': os.environ.get('ENV', 'production')
    })

@app.route('/health')
def health():
    return jsonify({'status': 'ok'})

if __name__ == '__main__':
    port = int(os.environ.get('PORT', 8080))
    app.run(host='0.0.0.0', port=port)
EOF

# Requirements
cat > requirements.txt << 'EOF'
flask==3.0.0
gunicorn==21.2.0
EOF

# Dockerfile
cat > Dockerfile << 'EOF'
FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

ENV PORT=8080
EXPOSE 8080

CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--workers", "2", "app:app"]
EOF

# Tests simples
cat > test_app.py << 'EOF'
import pytest
from app import app

@pytest.fixture
def client():
    app.config['TESTING'] = True
    with app.test_client() as client:
        yield client

def test_index(client):
    response = client.get('/')
    assert response.status_code == 200
    data = response.get_json()
    assert 'message' in data

def test_health(client):
    response = client.get('/health')
    assert response.status_code == 200
    assert response.get_json()['status'] == 'ok'
EOF

Tâche 2 : Créer l'Artifact Registry et le fichier cloudbuild.yaml

bash
# Créer un repository Docker dans Artifact Registry
gcloud artifacts repositories create monapp-repo \
  --repository-format=docker \
  --location=$REGION \
  --description="Repository pour l'exercice Cloud Build"

# L'adresse complète du repository
REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/monapp-repo"
echo "Repository : $REPO"
bash
# Créer le fichier de configuration Cloud Build
cat > cloudbuild.yaml << EOF
steps:
  # Étape 1 : Installer les dépendances et lancer les tests
  - name: 'python:3.12-slim'
    entrypoint: bash
    args:
      - -c
      - |
        pip install --no-cache-dir -r requirements.txt pytest &&
        python -m pytest test_app.py -v
    id: tests

  # Étape 2 : Builder l'image Docker
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - build
      - -t
      - '${REGION}-docker.pkg.dev/\$PROJECT_ID/monapp-repo/monapp:latest'
      - -t
      - '${REGION}-docker.pkg.dev/\$PROJECT_ID/monapp-repo/monapp:\$BUILD_ID'
      - .
    id: build
    waitFor: ['tests']

  # Étape 3 : Pousser l'image dans Artifact Registry
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - push
      - '--all-tags'
      - '${REGION}-docker.pkg.dev/\$PROJECT_ID/monapp-repo/monapp'
    id: push
    waitFor: ['build']

  # Étape 4 : Déployer sur Cloud Run
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: gcloud
    args:
      - run
      - deploy
      - monapp-service
      - '--image=${REGION}-docker.pkg.dev/\$PROJECT_ID/monapp-repo/monapp:\$BUILD_ID'
      - '--region=${REGION}'
      - '--platform=managed'
      - '--allow-unauthenticated'
      - '--set-env-vars=APP_VERSION=\$BUILD_ID,ENV=production'
    id: deploy
    waitFor: ['push']

# Images poussées dans Artifact Registry
images:
  - '${REGION}-docker.pkg.dev/\$PROJECT_ID/monapp-repo/monapp:latest'
  - '${REGION}-docker.pkg.dev/\$PROJECT_ID/monapp-repo/monapp:\$BUILD_ID'

options:
  logging: CLOUD_LOGGING_ONLY
  machineType: 'E2_HIGHCPU_8'  # Build plus rapide
EOF

echo "Fichier cloudbuild.yaml créé"

Tâche 3 : Lancer le build manuellement

bash
# Accorder les permissions Cloud Run au service account Cloud Build
CB_SA="${PROJECT_ID}@cloudbuild.gserviceaccount.com"
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$CB_SA" \
  --role="roles/run.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$CB_SA" \
  --role="roles/iam.serviceAccountUser"

# Lancer le build depuis le dossier courant
gcloud builds submit . --config=cloudbuild.yaml

# Suivre les logs en temps réel
BUILD_ID=$(gcloud builds list --limit=1 --format="value(id)")
gcloud builds log $BUILD_ID --stream

Tâche 4 : Vérifier le déploiement

bash
# Voir les builds passés
gcloud builds list --limit=5 \
  --format="table(id,status,createTime,duration)"

# Récupérer l'URL Cloud Run
SERVICE_URL=$(gcloud run services describe monapp-service \
  --region=$REGION \
  --format="value(status.url)")
echo "URL du service : $SERVICE_URL"

# Tester l'application déployée
curl $SERVICE_URL
curl $SERVICE_URL/health

# Voir les révisions Cloud Run (historique des déploiements)
gcloud run revisions list \
  --service=monapp-service \
  --region=$REGION \
  --format="table(name,deployTime,status.conditions[0].status)"

Tâche 5 : Nettoyer

bash
cd ..
gcloud run services delete monapp-service --region=$REGION --quiet
gcloud artifacts repositories delete monapp-repo --location=$REGION --quiet
rm -rf monapp/

✅ Vérification du résultat

  • gcloud builds list affiche le build en état SUCCESS
  • Les tests pytest passent dans les logs du build
  • L'image est visible dans Artifact Registry
  • curl $SERVICE_URL/health retourne {"status":"ok"}

💡 À retenir

Structure d'un cloudbuild.yaml :

yaml
steps:
  - name: 'image-docker'   # Image utilisée pour cette étape
    entrypoint: 'commande' # Optionnel (remplace ENTRYPOINT de l'image)
    args: ['arg1', 'arg2'] # Arguments passés à la commande
    id: 'mon-etape'        # Nom pour les dépendances
    waitFor: ['autre-etape'] # Attendre cette étape avant de démarrer

options:
  machineType: 'E2_HIGHCPU_8'  # Type de machine pour le build

Variables built-in Cloud Build :

VariableValeur
$PROJECT_IDID du projet GCP
$BUILD_IDID unique du build
$COMMIT_SHASHA du commit Git (si déclenché par Git)
$BRANCH_NAMENom de la branche

✨ Solution Complète

bash
# Lancer un build depuis le dossier courant
gcloud builds submit . --config=cloudbuild.yaml

# Lancer un build depuis GitHub (après avoir connecté le dépôt)
gcloud builds triggers run mon-trigger --branch=main
Retour au module

Sur cette page

  • 🎯 Objectifs
  • 📖 Contexte
  • 📋 Énoncé
  • 🧭 Déroulement de l'exercice
  • Tâche 1 : Créer l'application et le Dockerfile
  • Tâche 2 : Créer l'Artifact Registry et le fichier cloudbuild.yaml
  • Tâche 3 : Lancer le build manuellement
  • Tâche 4 : Vérifier le déploiement
  • Tâche 5 : Nettoyer
  • ✅ Vérification du résultat
  • 💡 À retenir
  • ✨ Solution Complète