Configurer des notifications pour les services tiers

Lorsque l'état de vos compilations Cloud Build change, vous pouvez envoyer des notifications concernant ces modifications via des services de messagerie tiers ou par e-mail.

Des services tels que Slack proposent des webhooks entrants, un moyen simple de publier des messages depuis des applications vers Slack. Cloud Functions est une solution de calcul légère permettant de créer des fonctions autonomes à usage unique qui répondent aux événements cloud, tels que des compilations, sans avoir à gérer de serveur, ni d'environnement d'exécution. Lorsqu'un événement cloud se produit, un déclencheur répond en exécutant une action, par exemple l'envoi d'un message Cloud Pub/Sub.

Il existe de nombreux services tiers intégrés à des fonctionnalités de messagerie interapplication tels que SendGrid et IFTTT. Vous pouvez utiliser ce tutoriel comme modèle pour vous connecter à des services de ce type.

Ce tutoriel explique comment utiliser Cloud Functions et Cloud Pub/Sub pour envoyer des notifications sur Cloud Build via Slack et Mailgun.

Objectifs

  • Déployer une application Slack pour recevoir des notifications externes de Cloud Build
  • Écrire une fonction Cloud Functions pour envoyer des notifications Pub/Sub à Slack
  • Configurer Mailgun pour recevoir des notifications externes de Cloud Build
  • Écrire une fonction Cloud Functions pour envoyer des notifications Pub/Sub à Mailgun

Coûts

Ce tutoriel fait appel à des composants facturables de Cloud Platform, en particulier :

  • Cloud Functions
  • Cloud Pub/Sub
  • Cloud Build

Utilisez le simulateur de coût pour générer une estimation des coûts en fonction de votre utilisation prévue.

Les nouveaux utilisateurs de Cloud Platform peuvent bénéficier d'un essai gratuit.

Avant de commencer

  1. Connectez-vous à votre compte Google.

    Si vous n'en possédez pas déjà un, vous devez en créer un.

  2. Dans Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Cloud.

    Accéder à la page de sélection du projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

  4. Activez les Cloud Functions and Cloud Pub/Sub API.

    Activer les API

  5. Installez et initialisez le SDK Cloud.
  6. Mettez à jour et installez les composants gcloud :
    gcloud components update &&
    gcloud components install alpha beta

Notifications Slack

Les sections suivantes vous expliquent comment configurer des notifications Slack.

Préparer l'application Slack

  1. Téléchargez Slack sur votre ordinateur. Vous devez également rejoindre un espace de travail Slack en vous inscrivant avec votre adresse e-mail ou en utilisant une invitation envoyée par un administrateur de l'espace de travail.

  2. Connectez-vous à Slack à l'aide du nom de votre espace de travail et des identifiants de votre compte Slack.

  3. Pour créer une application Slack, procédez comme suit :

    1. Choisissez le nom de l'application et votre espace de travail Slack. Cliquez sur Create App (Créer l'application).
    2. Sous Features (Fonctionnalités), cliquez sur Incoming Webhooks (Webhooks entrants).
    3. Activez Activate Incoming Webhooks (Activer Webhooks entrants).
    4. Cliquez sur Add New Webhook to Workspace (Ajouter un nouveau webhook à l'espace de travail). Une page d'autorisation s'affiche.
    5. Dans le menu déroulant, sélectionnez le canal auquel vous souhaitez que les notifications soient envoyées.
    6. Cliquez sur Install (Installer).
    7. Un webhook a été créé pour votre application Slack. Copiez l'URL du webhook (Webhook URL) et enregistrez-le pour une utilisation ultérieure.

Écrire la fonction Cloud Functions

Créez un répertoire nommé gcb_slack et modifiez les sous-répertoires comme suit :

mkdir ~/gcb_slack
cd ~/gcb_slack

Créez ensuite les fichiers index.js et package.json dans le répertoire gcb_slack :

index.js

const { IncomingWebhook } = require('@slack/webhook');
const url = process.env.SLACK_WEBHOOK_URL;

const webhook = new IncomingWebhook(url);

// subscribeSlack is the main function called by Cloud Functions.
module.exports.subscribeSlack = (pubSubEvent, context) => {
  const build = eventToBuild(pubSubEvent.data);

  // Skip if the current status is not in the status list.
  // Add additional statuses to list if you'd like:
  // QUEUED, WORKING, SUCCESS, FAILURE,
  // INTERNAL_ERROR, TIMEOUT, CANCELLED
  const status = ['SUCCESS', 'FAILURE', 'INTERNAL_ERROR', 'TIMEOUT'];
  if (status.indexOf(build.status) === -1) {
    return;
  }

  // Send message to Slack.
  const message = createSlackMessage(build);
  webhook.send(message);
};

// eventToBuild transforms pubsub event message to a build object.
const eventToBuild = (data) => {
  return JSON.parse(Buffer.from(data, 'base64').toString());
}

// createSlackMessage creates a message from a build object.
const createSlackMessage = (build) => {
  const message = {
    text: `Build \`${build.id}\``,
    mrkdwn: true,
    attachments: [
      {
        title: 'Build logs',
        title_link: build.logUrl,
        fields: [{
          title: 'Status',
          value: build.status
        }]
      }
    ]
  };
  return message;
}

SLACK_WEBHOOK_URL est une variable d'environnement Cloud Functions qui spécifie l'URL de webhook créée pour votre application Slack. Cette variable d'environnement est définie lors du déploiement de la fonction.

Ce programme utilise le webhook de Slack pour écouter et recevoir des messages de la fonction Cloud Functions. Lorsqu'un événement est déclenché, un message est envoyé au webhook, puis transmis à Slack.

La fonction createSlackMessage a été simplifiée pour cet exemple. Vous pouvez développer le message pour inclure beaucoup plus d'éléments comme des couleurs de texte, des images et la durée de compilation.

package.json

{
  "name": "google-container-slack",
  "version": "0.0.1",
  "description": "Slack integration for Google Cloud Build, using Google Cloud Functions",
  "main": "index.js",
  "dependencies": {
    "@slack/webhook": "5.0.1"
  }
}

package.json décrit les éléments suivants :

  • Le nom du programme, sa version et sa description
  • Son ou ses fichiers d'exécution principaux
  • Ses dépendances

Ce fichier est d'une simplicité trompeuse : vous pouvez ajouter plus de dépendances, d'exigences et d'autres informations le cas échéant.

index.js et package.json devraient maintenant s'afficher dans le répertoire gcb_slack.

Déployer la fonction Cloud Functions

Pour déployer la fonction subscribeSlack avec un déclencheur Cloud Pub/Sub, exécutez la commande suivante dans le répertoire gcb_slack :

gcloud functions deploy subscribeSlack --trigger-topic cloud-builds --runtime nodejs10 --set-env-vars "SLACK_WEBHOOK_URL=https://hooks.slack.com/…"

SLACK_WEBHOOK_URL définit l'URL de webhook créée pour votre application Slack. Le format d'URL est le suivant : https://hooks.slack.com/services/T…/B…/….

Le résultat obtenu devrait ressembler à ce qui suit :

Deploying function…
availableMemoryMb: 256
entryPoint: subscribeSlack
environmentVariables:
  SLACK_WEBHOOK_URL: https://hooks.slack.com/services/…
eventTrigger:
  eventType: google.pubsub.topic.publish
  failurePolicy: {}
  resource: projects/[PROJECT-ID]/topics/cloud-builds
  service: pubsub.googleapis.com
labels:
  deployment-tool: cli-gcloud
name: projects/[PROJECT-ID]/locations/us-central1/functions/subscribeSlack
runtime: nodejs10
serviceAccountEmail: [PROJECT-ID]@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/…
status: ACTIVE
timeout: 60s
updateTime: 'YYYY-MM-DDThh:mm:ssZ'
versionId: '1'

Une fois le déploiement de la fonction Cloud Functions terminé, vous recevez une notification Slack lorsqu'un événement de compilation se produit.

Notifications par e-mail

Les sections suivantes vous expliquent comment configurer des notifications par e-mail à l'aide de l'API Mailgun.

Si vous ne connaissez pas Mailgun, consultez la documentation de démarrage rapide.

Préparer les paramètres Mailgun

  1. Si vous ne l'avez pas déjà fait, créez un compte Mailgun.
  2. Utilisez un domaine de bac à sable Mailgun ou ajoutez un domaine, puis suivez les instructions de Mailgun.
  3. Sur la page des domaines, cliquez sur votre domaine pour ouvrir la page de paramètres correspondante.
  4. Sous API, cliquez sur Sélectionner, Node.js, puis copiez la clé API du domaine et enregistrez-la pour une utilisation ultérieure.

Vous devez également disposer des éléments suivants :

  • Une adresse e-mail destinée à l'envoi d'e-mails. Elle peut appartenir au domaine que vous fournissez. Si vous ne savez pas quelle adresse e-mail utiliser, renseignez-vous auprès de votre fournisseur de domaine. Vous pouvez également fournir une adresse e-mail inexistante si vous n'attendez pas de réponse du destinataire, par exemple noreply@mydomain.com.
  • Une adresse e-mail destinée à la réception d'e-mails.

Écrire la fonction Cloud Functions

Créez un répertoire nommé gcb_email et modifiez les sous-répertoires comme suit :

mkdir ~/gcb_email
cd ~/gcb_email

Créez ensuite les fichiers index.js, config.json et package.json dans le répertoire gcb_email :

index.js

const Mailgun = require('mailgun-js');
const humanizeDuration = require('humanize-duration');
const config = require('./config.json');

const mailgun = Mailgun({
  apiKey: config.MAILGUN_API_KEY,
  domain: config.MAILGUN_DOMAIN,
});

// subscribeMailgun is the main function called by Cloud Functions.
module.exports.subscribeMailgun = (pubSubEvent, context) => {
  const build = eventToBuild(pubSubEvent.data);

  // Skip if the current status is not in the status list.
  const status = ['SUCCESS', 'FAILURE', 'INTERNAL_ERROR', 'TIMEOUT'];
  if (status.indexOf(build.status) === -1) {
    return;
  }

  // Send email.
  const message = createEmail(build);
  mailgun.messages().send(message, (error, body) => console.log(body.message));
};

// eventToBuild transforms pubsub event message to a build object.
const eventToBuild = (data) => {
  return JSON.parse(Buffer.from(data, 'base64').toString());
}

// createEmail creates an email message from a build object.
const createEmail = (build) => {
  const duration = humanizeDuration(new Date(build.finishTime) - new Date(build.startTime));
  const msgText = `Build ${build.id} finished with status ${build.status}, in ${duration}.`;
  let msgHtml = `<p>${msgText}</p><p><a href="${build.logUrl}">Build logs</a></p>`;
  if (build.images) {
    const images = build.images.join(',');
    msgHtml += `<p>Images: ${images}</p>`;
  }
  const message = {
    from: config.MAILGUN_FROM,
    to: config.MAILGUN_TO,
    subject: `Build ${build.id} finished`,
    text: msgText,
    html: msgHtml
  };
  return message;
}

config.json

{
  "MAILGUN_API_KEY":"[API_KEY]",
  "MAILGUN_DOMAIN":"email.com",
  "MAILGUN_FROM":"me@email.com",
  "MAILGUN_TO":"someone@email.com"
}

Dans ce fichier, vous devez fournir les informations suivantes :

  • MAILGUN_API_KEY : la clé API que vous avez collectée.
  • MAILGUN_DOMAIN, le domaine que vous avez configuré.
  • MAILGUN_FROM : l'adresse e-mail appartenant au domaine à partir duquel l'e-mail est envoyé (même une adresse inexistante).
  • MAILGUN_TO : l'adresse e-mail à laquelle l'e-mail est envoyé.

package.json

{
  "name": "google-container-email",
  "version": "0.0.1",
  "description": "Email integration for Google Cloud Build, using Google Cloud Functions",
  "main": "index.js",
  "dependencies": {
    "humanize-duration": "3.10.0",
    "mailgun-js": "~0.11.2"
  },
  "devDependencies": {
    "async": "^2.1.5",
    "mocha": "3.2.0",
    "should": "11.2.1"
  }
}

package.json décrit les éléments suivants :

  • Le nom du programme, sa version et sa description
  • Son ou ses fichiers d'exécution principaux
  • Ses dépendances

index.js, config.json et package.json devraient maintenant s'afficher dans le répertoire gcb_email.

Déployer la fonction Cloud Functions

Pour déployer la fonction, exécutez la commande suivante dans le répertoire gcb_email :

gcloud functions deploy subscribeMailgun --trigger-topic cloud-builds --runtime nodejs10

Une fois le déploiement de la fonction Cloud Functions terminé, vous recevez une notification par e-mail lorsqu'un événement de compilation se produit.

Tester la fonction

Une fois la configuration terminée, vous devez tester votre mise en œuvre pour vous assurer qu'elle fonctionne comme prévu. Vous pouvez effectuer le test en envoyant un build à Cloud Build.

Créez un répertoire nommé gcb_test et modifiez les sous-répertoires comme suit :

mkdir ~/gcb_test
cd ~/gcb_test

Créez ensuite un fichier nommé request.json contenant le code suivant. Cette requête déclenche le clonage d'un dépôt par une compilation.

request.json

{
  "steps": [
    {
      "name": "gcr.io/cloud-builders/git",
      "args": [
        "clone",
        "https://github.com/GoogleCloudPlatform/cloud-builders"
      ]
    }
  ]
}

Exécutez ensuite la commande suivante dans le répertoire gcb_test :

Linux/macOS

curl \
  -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -T request.json \
  https://cloudbuild.googleapis.com/v1/projects/[PROJECT-ID]/builds

PowerShell

(Invoke-WebRequest `
  -Method POST `
  -Headers @{ "Authorization" = "Bearer $(gcloud auth print-access-token)" } `
  -ContentType "application/json; charset=utf-8" `
  -InFile request.json `
  -Uri https://cloudbuild.googleapis.com/v1/projects/[PROJECT-ID]/builds `
).Content

[PROJECT-ID] correspond à votre ID de projet

Vous devriez obtenir un résultat semblable à celui-ci :

{
  "name": "operations/build/[PROJECT-ID]/…",
  "metadata": {
    "@type": "type.googleapis.com/google.devtools.cloudbuild.v1.BuildOperationMetadata",
    "build": {
      "id": "…",
      "status": "QUEUED",
      "createTime": "…",
      "steps": [
        {
          "name": "gcr.io/cloud-builders/git",
          "args": [
            "clone",
            "https://github.com/GoogleCloudPlatform/cloud-builders"
          ]
        }
      ],
…

Si vous avez suivi les instructions Slack, une notification Slack semblable à celle-ci doit s'afficher :

Si vous avez suivi les instructions Mailgun, vous devriez recevoir un e-mail concernant la compilation.

Nettoyer

Afin d'éviter que des frais ne soient facturés sur votre compte Google Cloud Platform pour les ressources utilisées dans ce tutoriel, procédez comme suit :

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Pour 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.

Supprimer les fonctions cloud

Pour supprimer les fonctions Cloud Functions que vous avez déployées dans ce tutoriel, exécutez les commandes suivantes :

gcloud functions delete subscribeMailgun
gcloud functions delete subscribeSlack

Vous pouvez également supprimer des fonctions Cloud Functions à partir de la console Google Cloud.

Étape suivante