Aller au contenu

Cloud Run : la gestion des conteneurs simplifiée

Ce guide pratique vous montre comment automatiser le déploiement d’une application Python conteneurisée via Terraform et Google Cloud Run, avec un exemple concret et des ressources pour aller plus loin.

Google Cloud Run

Si vous recherchez un service plus simple que Kubernetes pour déployer et gérer des conteneurs dans un environnement (même en production), Google Cloud propose un service clé en main et simple à utiliser : Cloud Run.

L'objectif de cet article est d'aller un peu plus loin que le guide de démarrage rapide, et de vous montrer comment déployer un conteneur Python simple, via Terraform.

Pré-requis pour la démo

Premièrement, vous aurez besoin de ces éléments :

Ensuite, créez le trigger Cloudbuild dans la console GCP :

  1. Allez à la page Cloud Build Triggers.
  2. Cliquez sur “Create Trigger”.
  3. Définissez ces options :
    • Name: your-github-trigger
    • Event: Push to a branch
    • Source: GitHub
    • Repository: Sélectionnez le dépôt que vous avez créé pour ce projet.
    • Branch: main
    • Build Configuration: Cloud Build configuration file (yaml or json)
  4. Cliquez sur Create pour terminer la configuration du trigger.

Note : Créez un compte de service nommé sa-cloudbuild et attribuez-lui les rôles Cloud Build Service Account et Storage Admin. Ce compte de service sera utilisé par Cloud Build pour déployer l'application sur Cloud Run.

Ressources Terraform

Pour créer un dépôt dans Artifact Registry :

resource "google_artifact_registry_repository" "repo" {
  location      = var.region
  repository_id = "flask-repo"
  description   = "Repository for Flask app"
  format        = "DOCKER"

  labels = {
    managed_by = "terraform"
  }
}

Créez l'application simple :

# main.py
import os

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    """Example Hello World route."""
    name = os.environ.get("NAME", "World")
    return f"Hello {name}!"

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

Avec ces requirements :

# requirements.txt
Flask==3.0.3
gunicorn==23.0.0
Werkzeug==3.0.3

Et ce Dockerfile :

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt main.py ./

RUN pip install --no-cache-dir -r requirements.txt

EXPOSE 8080

ENV NAME=World
ENV PORT=8080

CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:app"]

Voici le code Terraform pour créer et déployer le conteneur avec Cloud Build :

resource "null_resource" "build_image" {
  triggers = {
    dockerfile_hash   = filemd5("${path.root}/app/Dockerfile")
    main_py_hash      = filemd5("${path.root}/app/main.py")
    requirements_hash = filemd5("${path.root}/app/requirements.txt")
  }

  provisioner "local-exec" {
    command = <<-EOT
      gcloud builds submit ${path.root}/app \\
        --tag ${var.region}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.repo.repository_id}/flask-app:latest \\
        --project ${var.project_id}
    EOT
  }

  depends_on = [
    google_artifact_registry_repository.repo
  ]
}

Pour notre exemple, nous lancerons le code directement depuis Terraform, sans avoir besoin d'installer Docker ou Podman, juste Gcloud Cli.

Et enfin, le code Terraform pour créer le service Cloud Run :

# Cloud Run Service
##

resource "google_cloud_run_v2_service" "flask_service" {
  name     = var.service_name
  location = var.region

  labels = {
    managed_by = "terraform"
  }

  template {
    labels = {
      managed_by = "terraform"
    }

    containers {
      image = "${var.region}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.repo.repository_id}/flask-app:latest"

      ports {
        container_port = 8080
      }

      env {
        name  = "NAME"
        value = "Cloud Run"
      }

      resources {
        limits = {
          cpu    = "1000m"
          memory = "512Mi"
        }
      }
    }

    scaling {
      min_instance_count = 0
      max_instance_count = 3
    }
  }

  depends_on = [
    null_resource.build_image
  ]
}

# IAM policy to allow public access
##

resource "google_cloud_run_service_iam_member" "public_access" {
  service  = google_cloud_run_v2_service.flask_service.name
  location = google_cloud_run_v2_service.flask_service.location
  role     = "roles/run.invoker"
  member   = "allUsers"
}

Ces résultats vous fourniront les URL générées pour votre service, ainsi que le registre :

output "service_url" {
  description = "URL of the Cloud Run service"
  value       = google_cloud_run_v2_service.flask_service.uri
}

output "artifact_registry_url" {
  description = "Artifact Registry repository URL"
  value       = google_artifact_registry_repository.repo.name
}

Vous pouvez désormais lancer un plan et appliquer votre code ; vous disposez d'un conteneur sur lequel vous pouvez travailler et gérer un service administré par Google Cloud.

Tout le code est disponible dans ce dépôt github.

Il y a une page “Awesome CloudRun” où vous trouverez de nombreuses utilisations intéressantes de Cloud Run..

Google propose également des Codelabs où vous pouvez vous former et explorer des cas d'utilisation avancés avec Cloud Run.

Vous pouvez maintenant utiliser et améliorer votre configuration pour travailler avec vos conteneurs, amusez-vous bien !

Dernier