Exécuter Django dans l'environnement Cloud Run

Le déploiement d'applications avec état sur Cloud Run comme Django implique l'intégration de services pour interagir entre eux afin de former un projet cohérent.

Dans ce tutoriel, nous partons du principe que vous connaissez bien le développement Web avec Django. Si vous débutez dans le développement avec Django, nous vous recommandons d'écrire votre première application Django avant de continuer.

Bien que ce tutoriel illustre spécifiquement Django, vous pouvez utiliser ce processus de déploiement avec d'autres frameworks basés sur Django, tels que Wagtail et Django CMS.

Ce tutoriel utilise Django 3, qui nécessite au moins Python 3.7.

Objectifs

Au cours de ce tutoriel, vous allez :

  • Créez et connectez une base de données Cloud SQL.
  • Créer et utiliser des valeurs de secrets Secret Manager
  • Déployer une application Django dans Cloud Run

  • Hébergez des fichiers statiques sur Cloud Storage.

  • Utilisez Cloud Build pour automatiser le déploiement.

Coûts

Ce tutoriel utilise les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

  4. Activer les API Cloud Run, Cloud SQL, Cloud Build, Secret Manager, and Compute Engine .

    Activer les API

  5. Installez et initialisez le SDK Cloud.
  6. Assurez-vous que le compte utilisé pour ce tutoriel dispose des autorisations suffisantes.

Préparer votre environnement

Cloner une application exemple

Le code de l'exemple d'application Django se trouve dans le dépôt GoogleCloudPlatform/python-docs-samples sur GitHub.

  1. Vous pouvez soit télécharger l'exemple sous forme de fichier ZIP et l'extraire, soit cloner le dépôt sur votre ordinateur local à l'aide de la commande suivante :

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
    
  2. Accédez au répertoire qui contient l'exemple de code :

    Linux/macOS

    cd python-docs-samples/run/django
    

    Windows

    cd python-docs-samples\run\django
    

Confirmer la configuration de Python

Ce tutoriel s'appuie sur Python pour exécuter l'exemple d'application sur votre ordinateur. L'exemple de code nécessite également l'installation des dépendances

Pour en savoir plus, consultez le guide de l'environnement de développement Python.

  1. Vérifiez que votre version de Python est au moins la version 3.7.

     python -V
    

    Le message Python 3.7.3 ou une version ultérieure doit s'afficher.

  2. Créez un environnement virtuel Python et installez des dépendances:

    Linux/macOS

    python -m venv venv
    source venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

    Windows

    python -m venv env
    venv\scripts\activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

Téléchargez le proxy d'authentification Cloud SQL pour vous connecter à Cloud SQL depuis votre ordinateur local

Une fois déployée, votre application utilise le proxy d'authentification Cloud SQL intégré à l'environnement Cloud Run pour communiquer avec votre instance Cloud SQL. Notez toutefois que pour tester votre application en local, vous devez installer et utiliser une copie locale du proxy dans votre environnement de développement. Pour en savoir plus, consultez le guide de proxy d'authentification Cloud SQL.

Le proxy d'authentification Cloud SQL utilise l'API Cloud SQL pour interagir avec votre instance SQL. Pour ce faire, il nécessite l'authentification de l'application via gcloud.

  1. Authentifiez-vous et procurez-vous des identifiants pour l'API:

    gcloud auth application-default login
    
  2. Téléchargez et installez le proxy d'authentification Cloud SQL sur votre ordinateur local.

    Linux 64 bits

    1. Téléchargez le proxy d'authentification Cloud SQL :
      wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
      
    2. Rendez le proxy d'authentification Cloud SQL exécutable :
      chmod +x cloud_sql_proxy
      

    Linux 32 bits

    1. Téléchargez le proxy d'authentification Cloud SQL :
      wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.386 -O cloud_sql_proxy
      
    2. Si la commande wget est introuvable, exécutez sudo apt-get install wget puis répétez la commande de téléchargement.
    3. Rendez le proxy d'authentification Cloud SQL exécutable :
      chmod +x cloud_sql_proxy
      

    macOS 64 bits

    1. Téléchargez le proxy d'authentification Cloud SQL :
      curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
      
    2. Rendez le proxy d'authentification Cloud SQL exécutable :
      chmod +x cloud_sql_proxy
      

    macOS 32 bits

    1. Téléchargez le proxy d'authentification Cloud SQL :
      curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.386
      
    2. Rendez le proxy d'authentification Cloud SQL exécutable :
      chmod +x cloud_sql_proxy
      

    Windows 64 bits

    Pour télécharger le proxy d'authentification Cloud SQL, effectuez un clic droit sur le lien https://dl.google.com/cloudsql/cloud_sql_proxy_x64.exe, puis sélectionnez Enregistrer le lien sous. Renommez le fichier en cloud_sql_proxy.exe.

    Windows 32 bits

    Pour télécharger le proxy d'authentification Cloud SQL, effectuez un clic droit sur le lien https://dl.google.com/cloudsql/cloud_sql_proxy_x86.exe, puis sélectionnez Enregistrer le lien sous. Renommez le fichier en cloud_sql_proxy.exe.

    Image Docker du proxy d'authentification Cloud SQL

    Pour plus de commodité, plusieurs images de conteneur contenant le proxy d'authentification Cloud SQL sont disponibles sur GitHub dans le dépôt du proxy d'authentification Cloud SQL. Vous pouvez extraire la dernière image sur votre ordinateur local en utilisant Docker avec la commande suivante :
    docker pull gcr.io/cloudsql-docker/gce-proxy:1.19.1
    

    Autres systèmes d'exploitation

    Pour les autres systèmes d'exploitation non inclus ici, vous pouvez compiler le proxy d'authentification Cloud SQL à partir de la source.

    Vous pouvez choisir de placer le téléchargement à un emplacement courant, par exemple à un emplacement de votre PATH ou dans votre répertoire d'accueil. Si vous choisissez de le faire, lorsque vous démarrerez le proxy d'authentification Cloud SQL plus tard dans le tutoriel, n'oubliez pas de faire référence à l'emplacement choisi lorsque vous utilisez les commandes cloud_sql_proxy.

Préparer les services externes

Ce tutoriel utilise un certain nombre de services Google Cloud pour fournir la base de données, l'espace de stockage multimédia et de stockage de secrets, compatibles avec le projet Django déployé. Ces services sont déployés dans une région spécifique. Pour assurer l'efficacité entre les services, il est préférable que tous les services soient déployés dans la même région. Pour plus d'informations sur la région la plus proche de vous, consultez la section Produits disponibles par région.

Configurer une instance Cloud SQL pour PostgreSQL

Django est compatible avec plusieurs bases de données relationnelles, mais offre la plus grande compatibilité avec PostgreSQL, l'un des types de bases de données proposés dans Cloud SQL.

Les sections suivantes décrivent la création d'une instance PostgreSQL, d'une base de données et d'un utilisateur de base de données pour l'application "polls".

Créer une instance PostgreSQL

Console

  1. Dans Cloud Console, accédez à la page Instances Cloud SQL :

    Accéder à la page Instances Cloud SQL

  2. Cliquez sur Create Instance (Créer une instance).

  3. Cliquez sur PostgreSQL.

  4. Dans le champ ID de l'instance, saisissez un nom pour l'instance (INSTANCE_NAME).

  5. Indiquez le mot de passe de l'utilisateur postgres.

  6. Utilisez les valeurs par défaut dans les autres champs.

  7. Cliquez sur Create (Créer).

gcloud

  1. Créez l'instance PostgreSQL :

    gcloud sql instances create INSTANCE_NAME \
        --project PROJECT_ID \
        --database-version POSTGRES_12 \
        --tier db-f1-micro \
        --region REGION
    

    Remplacez l'élément suivant :

    • INSTANCE_NAME : nom de l'instance Cloud SQL
    • PROJECT_ID : ID de projet Google Cloud
    • REGION : région Google Cloud

    La création de l'instance et sa préparation peuvent prendre quelques minutes.

  2. Définissez un mot de passe pour l'utilisateur postgres.

    gcloud sql users set-password postgres \
        --instance INSTANCE_NAME --prompt-for-password
    

Créer une base de données

Console

  1. Dans Cloud Console, accédez à la page Instances Cloud SQL.

    Accéder à la page Instances Cloud SQL

  2. Sélectionnez l'instance INSTANCE_NAME.

  3. Accédez à l'onglet Bases de données.

  4. Cliquez sur Create database.

  5. Dans la boîte de dialogue Nom de la base de données, saisissez DATABASE_NAME.

  6. Cliquez sur Create (Créer).

gcloud

  • Créez la base de données dans l'instance récemment créée :

    gcloud sql databases create DATABASE_NAME \
        --instance INSTANCE_NAME
    

    Remplacez DATABASE_NAME par le nom de la base de données dans l'instance.

Créer un compte utilisateur

Console

  1. Dans Cloud Console, activez Cloud Shell.

    Activer Cloud Shell

  2. Dans Cloud Shell, utilisez le client gcloud intégré pour vous connecter à votre instance INSTANCE_NAME :

    gcloud sql connect INSTANCE_NAME --user postgres
    
  3. Saisissez le mot de passe utilisateur postgres.

    Vous utilisez à présent psql. L'invite postgres=> doit s'afficher.

  4. Créez un compte utilisateur :

    CREATE USER 'django' WITH PASSWORD 'PASSWORD';
    

    Remplacez PASSWORD par un mot de passe suffisamment secret.

  5. Accordez tous les droits sur la nouvelle base de données au nouvel utilisateur :

    GRANT ALL PRIVILEGES ON DATABASE 'DATABASE_NAME' TO 'django';
    
  6. Quittez psql :

    \q
    

gcloud

  1. Démarrez une connexion à l'instance SQL :

    gcloud sql connect INSTANCE_NAME --user postgres
    

    Remplacez INSTANCE_NAME par l'instance Cloud SQL créée.

  2. Saisissez le mot de passe utilisateur postgres.

    Vous utilisez à présent psql. L'invite postgres=> doit s'afficher.

  3. Créez un compte utilisateur :

    CREATE USER 'django' WITH PASSWORD 'PASSWORD';
    
  4. Accordez tous les droits sur la nouvelle base de données au nouvel utilisateur :

    GRANT ALL PRIVILEGES ON DATABASE 'DATABASE_NAME' TO 'django';
    
  5. Quittez psql :

    \q
    

Configurer un bucket Cloud Storage

Cloud Storage vous permet de stocker les éléments statiques inclus de Django, ainsi que les médias importés par l'utilisateur, dans un espace de stockage d'objets hautement disponible. Le package django-storages[google] gère l'interaction de Django avec ce backend de stockage.

Console

  1. Dans Cloud Console, accédez à la page du navigateur Cloud Storage.

    Accéder à la page du navigateur

  2. Cliquez sur Créer un bucket.
  3. Sur la page Créer un bucket, saisissez les informations concernant votre bucket. Pour passer à l'étape suivante, cliquez sur Continuer.
    • Pour nommer votre bucket, saisissez un nom qui répond aux exigences de dénomination des buckets.
    • Pour Emplacement, sélectionnez l'option suivante : PROJECT_ID-media
    • Pour Choisir une classe de stockage par défaut pour vos données, sélectionnez les éléments suivants : Standard.
    • Pour le champ Choisir comment contrôler l'accès aux objets, sélectionnez une option de Contrôle des accès.
    • Sous Paramètres avancés (facultatif), choisissez une méthode de chiffrement, une règle de conservation ou des libellés de bucket.
  4. Cliquez sur Create (Créer).

gcloud

L'outil de ligne de commande gsutil a été installé dans le cadre de l'installation du SDK Cloud.

  • Créez un bucket Cloud Storage :

    gsutil mb -l REGION gs://PROJECT_ID-media
    

Stocker les valeurs du secret dans Secret Manager

Maintenant que les services externes sont configurés, Django a besoin d'informations sur ces services. Au lieu de placer ces valeurs directement dans le code source de Django, ce tutoriel utilise Secret Manager pour stocker ces informations en toute sécurité.

Cloud Run et Cloud Build interagissent avec les secrets en utilisant leurs comptes de service respectifs, identifiés par une adresse e-mail contenant le numéro du projet.

Créer un fichier d'environnement Django en tant que secret Secret Manager

Vous stockez les paramètres requis pour démarrer Django dans un fichier .env sécurisé. L'exemple de code utilise l'API Secret Manager pour récupérer la valeur du secret, ainsi que le package django-environ pour charger les valeurs dans l'environnement Django. Le secret est configuré pour être accessible à la fois par Cloud Build et Cloud Run, car ces deux services exécutent Django.

  1. Créez un fichier appelé .env, en définissant la chaîne de connexion à la base de données, le nom du bucket multimédia et une nouvelle valeur SECRET_KEY :

    DATABASE_URL=postgres://django:PASSWORD@//cloudsql/PROJECT_ID:REGION:INSTANCE_NAME/DATABASE_NAME
    GS_BUCKET_NAME=PROJECT_ID-media
    SECRET_KEY=(a random string, length 50)
    
  2. Stockez le secret dans le gestionnaire de secrets :

Console

  1. Dans Cloud Console, accédez à la page Secret Manager.

    Accéder à la page Secret Manager

  2. Cliquez sur Créer un secret.

  3. Dans le champ Nom, saisissez django_settings.

  4. Dans la boîte de dialogue Importer un fichier, sélectionnez le fichier .env stocké localement.

  5. Cliquez sur Créer un secret.

  6. Dans la section Détails pour django_settings, notez le numéro du projet :

    projects/PROJECTNUM/secrets/django_settings
    
  7. Cliquez sur Ajouter un membre.

  8. Dans le champ Nouveaux membres, saisissez PROJECTNUM-compute@developer.gserviceaccount.com, puis appuyez sur Enter.

  9. Dans le champ Nouveaux membres, saisissez PROJECTNUM@cloudbuild.gserviceaccount.com, puis appuyez sur Enter.

  10. Dans le menu déroulant Rôle, sélectionnez Accesseur de secrets de Secret Manager.

  11. Cliquez sur Enregistrer.

gcloud

  1. Créez un secret, django_settings :

    gcloud secrets create django_settings --replication-policy automatic
    
  2. Ajoutez le fichier .env en tant que version du secret.

    gcloud secrets versions add django_settings --data-file .env
    
  3. Pour confirmer la création du secret, vérifiez-le :

    gcloud secrets describe django_settings
    

    Notez le numéro du projet :

    projects/PROJECTNUM/secrets/django_settings
    
  4. Accordez l'accès au secret au compte de service Cloud Run :

    gcloud secrets add-iam-policy-binding django_settings \
        --member serviceAccount:PROJECTNUM-compute@developer.gserviceaccount.com \
        --role roles/secretmanager.secretAccessor
    
  5. Accordez l'accès au secret au compte de service Cloud Build :

    gcloud secrets add-iam-policy-binding django_settings \
        --member serviceAccount:PROJECTNUM@cloudbuild.gserviceaccount.com \
        --role roles/secretmanager.secretAccessor
    

    Dans le résultat, vérifiez que bindings répertorie les deux comptes de service en tant que membres.

Créer un secret pour le mot de passe administrateur de Django

L'administrateur Django est normalement créé en exécutant la commande de gestion interactive createsuperuser.

Ce tutoriel utilise une migration de données pour créer l'administrateur, en récupérant le mot de passe mentionné à partir de Secret Manager.

Console

  1. Dans Cloud Console, accédez à la page Secret Manager.
  2. Cliquez sur Créer un secret.

  3. Dans le champ Nom, saisissez superuser_password.

  4. Dans le champ Valeur de secret, saisissez un mot de passe aléatoire.

  5. Cliquez sur Créer un secret.

  6. Dans la section Détails pour superuser_password, notez le numéro du projet (projects/PROJECTNUM/secrets/superuser_password).

  7. Cliquez sur Ajouter un membre.

  8. Dans le champ Nouveaux membres, saisissez PROJECTNUM@cloudbuild.gserviceaccount.com, puis appuyez sur Enter.

  9. Dans le menu déroulant Rôle, sélectionnez Accesseur de secrets de Secret Manager.

  10. Cliquez sur Enregistrer.

gcloud

  1. Créez un secret, superuser_password :

    gcloud secrets create superuser_password --replication-policy automatic
    
  2. Ajoutez un mot de passe généré de manière aléatoire en tant que version de ce secret :

    cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c30 > superuser_password
    
    gcloud secrets versions add superuser_password --data-file superuser_password
    
  3. Accordez l'accès au secret à Cloud Build :

    gcloud secrets add-iam-policy-binding superuser_password \
        --member serviceAccount:PROJECTNUM@cloudbuild.gserviceaccount.com \
        --role roles/secretmanager.secretAccessor
    

    Dans le résultat, confirmez que bindings ne répertorie que Cloud Build en tant que membre.

Autoriser Cloud Build à accéder à Cloud SQL

Pour que Cloud Build puisse appliquer les migrations de base de données, vous devez autoriser Cloud Build à accéder à Cloud SQL.

Console

  1. Dans Cloud Console, accédez à la page Identity and Access Management.

    Accéder à la page "Identity and Access Management"

  2. Pour modifier l'entrée pour PROJECTNUM@cloudbuild.gserviceaccount.com, cliquez sur Modifier.

  3. Cliquez sur Ajouter un autre rôle.

  4. Dans la boîte de dialogue Select a role (Sélectionner un rôle), sélectionnez Cloud SQL Client.

  5. Cliquez sur Enregistrer.

gcloud

  1. Autorisez Cloud Build à accéder à Cloud SQL :

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:PROJECTNUM@cloudbuild.gserviceaccount.com \
        --role roles/cloudsql.client
    

Exécuter l'application sur votre ordinateur local

Avec les services de sauvegarde configurés, vous pouvez désormais exécuter l'application sur votre ordinateur. Cette configuration permet le développement local et l'application des migrations de base de données. Notez que les migrations de bases de données sont également appliquées dans Cloud Build, mais vous devez disposer de cette configuration locale pour makemigrations.

  1. Dans un terminal distinct, démarrez le proxy d'authentification Cloud SQL:

    Linux/macOS

    ./cloud_sql_proxy -instances="PROJECT_ID:REGION:INSTANCE_NAME"=tcp:5432
    

    Windows

    cloud_sql_proxy.exe -instances="PROJECT_ID:REGION:INSTANCE_NAME"=tcp:5432
    

    Cette étape permet d'établir une connexion depuis votre ordinateur local vers votre instance Cloud SQL à des fins de test en local. N'arrêtez pas le proxy d'authentification Cloud SQL pendant tout le test local de votre application. L'exécution de ce processus dans un terminal distinct vous permet de continuer à travailler pendant qu'il s'exécute. Assurez-vous que les étapes suivantes sont effectuées dans un terminal distinct

  2. Dans un nouveau terminal, définissez l'ID du projet localement :

    Linux/macOS

      export GOOGLE_CLOUD_PROJECT=PROJECT_ID
    

    Windows

      set GOOGLE_CLOUD_PROJECT=PROJECT_ID
    
  3. Définissez une variable d'environnement pour indiquer que vous utilisez le proxy d'authentification Cloud SQL (cette valeur est reconnue dans le code):

    Linux/macOS

      export USE_CLOUD_SQL_AUTH_PROXY=true
    

    Windows

      set USE_CLOUD_SQL_AUTH_PROXY=true
    
  4. Exécutez les migrations Django pour configurer vos modèles et éléments:

    python manage.py makemigrations
    python manage.py makemigrations polls
    python manage.py migrate
    python manage.py collectstatic
    
  5. Démarrez le serveur Web Django:

    python manage.py runserver
    
  6. Dans votre navigateur, accédez à http://localhost:8000.

    La page affiche le texte suivant : "Hello, world. You're at the polls index." Le serveur Web Django qui s'exécute sur votre ordinateur diffuse les pages de l'exemple d'application.

  7. Appuyez sur Control+C pour arrêter le serveur Web local.

Déployer l'application sur Cloud Run

Avec la configuration des services externes, vous pouvez maintenant déployer le service Cloud Run.

  1. À l'aide du fichier cloudmigrate.yaml fourni, utilisez Cloud Build pour créer l'image, exécutez les migrations de base de données et insérez les éléments statiques:

    gcloud builds submit --config cloudmigrate.yaml \
        --substitutions _INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION
    

    Cette première compilation prend quelques minutes.

  2. Une fois la compilation réussie, déployez le service Cloud Run pour la première fois en définissant la région du service, l'image de base et l'instance Cloud SQL connectée :

    gcloud run deploy polls-service \
        --platform managed \
        --region REGION \
        --image gcr.io/PROJECT_ID/polls-service \
        --add-cloudsql-instances PROJECT_ID:REGION:INSTANCE_NAME \
        --allow-unauthenticated
    

    Vous devriez obtenir un résultat indiquant que le déploiement a réussi, avec une URL de service :

    Service [polls-service] revision [polls-service-00001-tug] has been deployed
    and is serving 100 percent of traffic at https://polls-service-<hash>-uc.a.run.app
    
  3. Pour afficher le service déployé, accédez à l'URL du service.

  4. Pour vous connecter à l'administrateur Django, ajoutez /admin à l'URL, puis connectez-vous avec le nom d'utilisateur admin et le mot de passe défini précédemment.

Mettre à jour l'application

Bien que les étapes initiales de provisionnement et de déploiement soient complexes, la mise à jour est plus simple:

  1. Exécutez le script de compilation et de migration Cloud Build :

    gcloud builds submit --config cloudmigrate.yaml \
        --substitutions _INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION
    
  2. Déployez le service en spécifiant uniquement la région et l'image :

    gcloud run deploy polls-service \
        --platform managed \
        --region REGION \
        --image gcr.io/PROJECT_ID/polls-service
    

Configurer pour la production

Votre déploiement Django est à présent opérationnel, mais vous pouvez suivre d'autres étapes pour vous assurer que votre application est prête pour la production.

Vérifier que le débogage est désactivé

Vérifiez que la variable DEBUG dans mysite/settings.py est définie sur False. Cette opération empêche les pages d'erreur détaillées d'être présentées à l'utilisateur, ce qui peut fuir des informations sur les configurations.

Limiter les droits de l'utilisateur de la base de données

Tous les utilisateurs créés à l'aide de Cloud SQL disposent des droits associés au rôle cloudsqlsuperuser : CREATEROLE, CREATEDB et LOGIN.

Pour empêcher l'utilisateur de la base de données Django de disposer de ces autorisations, créez-le manuellement dans PostgreSQL. Vous devez avoir installé le terminal interactif psql ou utiliser Cloud Shell sur lequel cet outil est préinstallé.

Console

  1. Dans Cloud Console, activez Cloud Shell.

    Activer Cloud Shell

  2. Dans Cloud Shell, utilisez le terminal intégré pour vous connecter à votre instance INSTANCE_NAME:

    gcloud sql connect INSTANCE_NAME --user postgres
    
  3. Saisissez le mot de passe utilisateur postgres.

    Vous utilisez à présent psql. L'invite postgres=> doit s'afficher.

  4. Créez un compte utilisateur :

    CREATE USER django WITH PASSWORD 'PASSWORD';
    

    Remplacez PASSWORD par un mot de passe aléatoire unique.

  5. Accordez tous les droits sur la nouvelle base de données au nouvel utilisateur :

    GRANT ALL PRIVILEGES ON DATABASE DATABASE_NAME TO django;
    
  6. Quittez psql :

    \q
    

gcloud

  1. Démarrez une connexion à l'instance SQL :

    gcloud sql connect INSTANCE_NAME --user postgres
    

    Remplacez INSTANCE_NAME par l'instance Cloud SQL créée.

  2. Saisissez le mot de passe utilisateur postgres.

    Vous utilisez à présent psql. L'invite postgres=> doit s'afficher.

  3. Créez un compte utilisateur :

    CREATE USER django WITH PASSWORD 'PASSWORD';
    
  4. Accordez tous les droits sur la nouvelle base de données au nouvel utilisateur :

    GRANT ALL PRIVILEGES ON DATABASE DATABASE_NAME TO django;
    
  5. Quittez psql :

    \q
    

Définir des autorisations minimales

Par défaut, ce service est déployé avec le compte de service de calcul par défaut. Toutefois, dans certains cas, l'utilisation du compte de service par défaut peut accorder un trop grand nombre d'autorisations. Si vous souhaitez être plus restrictif, vous devez créer votre propre compte de service et ne lui accorder que les autorisations requises par votre service. Les autorisations requises peuvent varier d'un service à l'autre, en fonction des ressources utilisées par un service particulier.

Voici les rôles minimaux de projet requis par ce service:

  • Demandeur Cloud Run
  • Client Cloud SQL
  • Administrateur Storage sur le bucket multimédia
  • Accesseur de secret Manager, sur la clé secrète des paramètres Django. L'accès au code secret de l'administrateur Django n'est pas requis par le service lui-même.

Pour créer un compte de service avec les autorisations requises et l'attribuer au service, exécutez la commande suivante:

  1. Dans l'outil gcloud, créez un compte de service avec les rôles requis:

    gcloud iam service-accounts create polls-service-account
    SERVICE_ACCOUNT=polls-service-account@PROJECT_ID.iam.gserviceaccount.com
    
    # Cloud Run Invoker
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:${SERVICE_ACCOUNT} \
        --role roles/run.invoker
    
    # Cloud SQL Client
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:${SERVICE_ACCOUNT} \
        --role roles/cloudsql.client
    
    # Storage Admin, on the media bucket
    gsutil iam ch \
        serviceAccount:${SERVICE_ACCOUNT}:roles/storage.objectAdmin \
        gs://PROJECT_ID-media
    
    # Secret Accessor, on the Django settings secret.
    gcloud secrets add-iam-policy-binding django_settings \
        --member serviceAccount:${SERVICE_ACCOUNT} \
        --role roles/secretmanager.secretAccessor
    
  2. Déployez le service et associez-le au nouveau compte de service:

    gcloud run services update polls-service \
        --platform managed \
        --region REGION \
        --service-account ${SERVICE_ACCOUNT}
    

Comprendre le code

Exemple d'application

L'exemple d'application Django a été créé à l'aide des outils Django standards. Les commandes suivantes créent le projet et l'application de sondages:

django-admin startproject mysite
python manage.py startapp polls

Les vues de base, les modèles et les configurations de routage ont été copiés à partir du tutoriel Écrire votre première application Django (Partie 1 et Partie 2).

Secrets de Secret Manager

Le fichier settings.py contient du code qui utilise l'API Python Secret Manager pour récupérer la dernière version du secret nommé et l'extraire dans l'environnement (à l'aide de django-environ) :

env = environ.Env(DEBUG=(bool, False))
env_file = os.path.join(BASE_DIR, ".env")

# Attempt to load the Project ID into the environment, safely failing on error.
try:
    _, os.environ["GOOGLE_CLOUD_PROJECT"] = google.auth.default()
except google.auth.exceptions.DefaultCredentialsError:
    pass

if os.path.isfile(env_file):
    # Use a local secret file, if provided

    env.read_env(env_file)
# ...
elif os.environ.get("GOOGLE_CLOUD_PROJECT", None):
    # Pull secrets from Secret Manager
    project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")

    client = secretmanager.SecretManagerServiceClient()
    settings_name = os.environ.get("SETTINGS_NAME", "django_settings")
    name = f"projects/{project_id}/secrets/{settings_name}/versions/latest"
    payload = client.access_secret_version(name=name).payload.data.decode("UTF-8")

    env.read_env(io.StringIO(payload))
else:
    raise Exception("No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.")

Le secret permet de stocker plusieurs valeurs de secrets afin de réduire le nombre de secrets à configurer. Bien que la superuser_password puisse avoir été créée directement à partir de la ligne de commande, la méthode basée sur les fichiers a été utilisée à la place. Si le paramètre a été généré depuis la ligne de commande, head -c a permis de déterminer la longueur de la chaîne générée de manière aléatoire, tout en veillant à ce qu'il n'y ait pas de saut de ligne à la fin du fichier, ce qui aurait entraîné des problèmes lors de la saisie du mot de passe dans l'administrateur Django.

Remplacements de secrets locaux

Si un fichier .env se trouve dans le système de fichiers local, il est utilisé à la place de la valeur de Secret Manager. La création d'un fichier .env en local peut faciliter les tests en local (par exemple, le développement local sur une base de données SQLite ou d'autres paramètres locaux).

Connexion à une base de données

Le fichier settings.py contient la configuration de la base de données SQL. Si vous définissez USE_CLOUD_SQL_AUTH_PROXY, le paramètre DATABASES est modifié pour déduire l'utilisation du proxy d'authentification Cloud SQL.

# Use django-environ to parse the connection string
DATABASES = {"default": env.db()}

# If the flag as been set, configure to use proxy
if os.getenv("USE_CLOUD_SQL_AUTH_PROXY", None):
    DATABASES["default"]["HOST"] = "127.0.0.1"
    DATABASES["default"]["PORT"] = 5432

Contenu statique stocké dans le cloud

Le fichier settings.py utilise également django-storages pour intégrer le bucket multimédia Cloud Storage directement au projet :

# Define static storage via django-storages[google]
GS_BUCKET_NAME = env("GS_BUCKET_NAME")
STATIC_URL = "/static/"
DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
STATICFILES_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
GS_DEFAULT_ACL = "publicRead"

Automatisation avec Cloud Build

Le fichier cloudmigrate.yaml exécute non seulement les étapes de compilation d'images classiques (création d'une image de conteneur et transfert de celle-ci vers le registre de conteneurs), mais aussi les commandes Django migrate et collectstatic. Ceux-ci nécessitent un accès à la base de données, effectué à l'aide de laapp-engine-exec-wrapper , un outil d'aide pourProxy d'authentification Cloud SQL:

steps:
  - id: "build image"
    name: "gcr.io/cloud-builders/docker"
    args: ["build", "-t", "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}", "."]

  - id: "push image"
    name: "gcr.io/cloud-builders/docker"
    args: ["push", "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"]

  - id: "apply migrations"
    name: "gcr.io/google-appengine/exec-wrapper"
    args:
      [
        "-i",
        "gcr.io/$PROJECT_ID/${_SERVICE_NAME}",
        "-s",
        "${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}",
        "-e",
        "SETTINGS_NAME=${_SECRET_SETTINGS_NAME}",
        "--",
        "python",
        "manage.py",
        "migrate",
      ]

  - id: "collect static"
    name: "gcr.io/google-appengine/exec-wrapper"
    args:
      [
        "-i",
        "gcr.io/$PROJECT_ID/${_SERVICE_NAME}",
        "-s",
        "${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}",
        "-e",
        "SETTINGS_NAME=${_SECRET_SETTINGS_NAME}",
        "--",
        "python",
        "manage.py",
        "collectstatic",
        "--verbosity",
        "2",
        "--no-input",
      ]

substitutions:
  _INSTANCE_NAME: django-instance
  _REGION: us-central1
  _SERVICE_NAME: polls-service
  _SECRET_SETTINGS_NAME: django_settings

images:
  - "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"

Les variables de substitution sont utilisées dans cette configuration. Si vous modifiez les valeurs directement dans le fichier, l'option --substitutions peut être supprimée au moment de la migration.

K_SERVICE est l'une des variables d'environnement par défaut déclarées dans le contrat concernant le conteneur de Cloud Run. Elle est définie lors des étapes de migration, car il s'agit de la variable utilisée dans settings.py pour détecter si l'application s'exécute localement et utilise le proxy d'authentification Cloud SQL.

Dans cette configuration, seules les migrations existantes sont appliquées. Les migrations doivent être créées localement à l'aide de la méthode de proxy d'authentification Cloud SQL définie dans la section Exécuter l'application en local.

Pour étendre la configuration Cloud Build de façon à inclure le déploiement dans la configuration sans avoir à exécuter deux commandes, consultez la section Déploiement continu à partir de git à l'aide de Cloud Build. Cela nécessite des modifications IAM, comme décrit.

Création de super-utilisateurs avec des migrations de données

La commande de gestion Django createsuperuser peut uniquement être exécutée de manière interactive, c'est-à-dire lorsque l'utilisateur peut saisir des informations en réponse aux invites. Bien que vous puissiez utiliser cette commande avec le proxy Cloud SQL et l'exécution de commandes dans une configuration Docker locale, une autre méthode consiste à créer le super-utilisateur en tant que migration de données:

import os

from django.contrib.auth.models import User
from django.db import migrations
from django.db.backends.postgresql.schema import DatabaseSchemaEditor
from django.db.migrations.state import StateApps

import google.auth
from google.cloud import secretmanager

def createsuperuser(apps: StateApps, schema_editor: DatabaseSchemaEditor) -> None:
    """
    Dynamically create an admin user as part of a migration
    Password is pulled from Secret Manger (previously created as part of tutorial)
    """
    if os.getenv("TRAMPOLINE_CI", None):
        # We are in CI, so just create a placeholder user for unit testing.
        admin_password = "test"
    else:
        client = secretmanager.SecretManagerServiceClient()

        # Get project value for identifying current context
        _, project = google.auth.default()

        # Retrieve the previously stored admin password
        PASSWORD_NAME = os.environ.get("PASSWORD_NAME", "superuser_password")
        name = f"projects/{project}/secrets/{PASSWORD_NAME}/versions/latest"
        admin_password = client.access_secret_version(name=name).payload.data.decode(
            "UTF-8"
        )

    # Create a new user using acquired password, stripping any accidentally stored newline characters
    User.objects.create_superuser("admin", password=admin_password.strip())

class Migration(migrations.Migration):

    initial = True
    dependencies = []
    operations = [migrations.RunPython(createsuperuser)]

Nettoyer

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et les ressources individuelles.

Supprimer le projet

  1. Dans Cloud Console, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Étape suivante