Hello les amis, Google a sorti un service Batch depuis quelques temps qui est un peu différent du service Cloudrun job. Contrairement à Cloudrun, il permet de lancer des commandes en compute sur plusieurs jours si besoin. Il permet également la flexibilité de pouvoir lancer tout ça dans depuis un container ou directement dans le compute et d’avoir une interface web de suivis des jobs.

Bim Bam Boum il schedule le “compute”, il lance la tâche et s’occupe de le détruire une fois qu’il à fini son boulot. On ne sait pas où, mais quelque part dans la région qu’on a définie, on ne voit même pas le compute qui pourrait polluer dans l’interface GCP. Du coup, pas besoin de s’occuper de maintenir les machines, pas de workload qui traîne, pas de plomberie un peu cheloue, pas de limite de temps trop restrictive, comme on pourrait avoir avec Cloudrun.

Autre point intéressant, on peut mapper des volumes sur la VM, et ajouter des GPU et donc plus facilement gérer de la manipulation de gros fichiers vidéo qu’il faudra en fin de traitement uploader sur GCS. Donc moi je dis, on va tester ça et voir si ça fait des miracles ou si je ressors mon gros packer et mon tf compute starter script infernal avec de gros cronjob de l’enfer :)

meme alien mais labélisé “cronjob” dans le but de se moquer des cronjobs

J’ai beau être matinal, j’ai mal

Si on fouille dans la doc de google Batch, on a un exemple Terraform qui ne vend pas trop du rêve. Déjà que la syntaxe Terraform est pas super lisible, on nous propose d’injecter du json en herodoc pour piloter des jobs.

https://cloud.google.com/batch/docs/create-run-job-using-terraform-and-cloud-scheduler

J’extrais les trucs un peu inutile du code de la doc et je proposerai une version plus propre. Déjà j’ai mal à mon Terraform quand on propose de faire les services account à la main et renseigner leur email en variable. Pourquoi ne pas créer les services account et mettre directement les permissions binding ? (on s’en occupe dans la suite de cet article)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
variable "cloud_scheduler_service_account_email" {
  type        = string
  description = "The service account email."
  default = "CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL"
}

variable "batch_service_account_email" {
  type        = string
  description = "The service account email."
  default = "BATCH_SERVICE_ACCOUNT_EMAIL"
}

les inconnues, j’ai beau être matinal, j’ai mal

Bof Bof, je vais proposer une version tf plus clean que ça, mais déjà on fait marcher, on verra ensuite.

Le code qui nous intéresse dans l’exemple est ici

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
resource "google_cloud_scheduler_job" "batch-job-invoker" {
  paused           = false # this cron job is enabled
  name             = "batch-job-invoker"
  project          = var.project_id
  region           = var.region
  schedule         = "*/5 * * * *" # when enabled, run every 5 minutes
  time_zone        = "America/Los_Angeles"
  attempt_deadline = "180s"

  retry_config {
    max_doublings        = 5
    max_retry_duration   = "0s"
    max_backoff_duration = "3600s"
    min_backoff_duration = "5s"
  }

  # when this cron job runs, create and run a Batch job
  http_target {
    http_method = "POST"
    uri = "https://batch.googleapis.com/v1/projects/${var.project_number}/locations/${var.region}/jobs"
    headers = {
      "Content-Type" = "application/json"
      "User-Agent"   = "Google-Cloud-Scheduler"
    }
    # Batch job definition
    body = base64encode(<<EOT
    {
      "taskGroups":[
        {
          "taskSpec": {
            "runnables":{
              "script": {
                "text": "echo Hello world! This job was created using Terraform and Cloud Scheduler."
              }
            }
          }
        }
      ],
      "allocationPolicy": {
        "serviceAccount": {
          "email": "${var.batch_service_account_email}"
        }
      },
      "labels": {
        "source": "terraform_and_cloud_scheduler_tutorial"
      },
      "logsPolicy": {
        "destination": "CLOUD_LOGGING"
      }
    }
    EOT
    )
    oauth_token {
      scope                 = "https://www.googleapis.com/auth/cloud-platform"
      service_account_email = var.cloud_scheduler_service_account_email
    }
  }
}

fff ffff ffff, chiant !

femme énervée avec de la vapeur qui sort des oreilles

Donc si on suivait aveuglément cet exemple, il faudrait mettre notre script bash dans la clef script text, sans erreur de syntaxe, en échappant tous les caractères spéciaux et que ça tienne dans une grande chaîne de caractère. Un beau bordel à développer, debugger et à maintenir, dès qu’on commence à faire un truc un peu compliqué.

Bon heureusement, on peut emballer tout ça dans un container et juste lancer un script en entrypoint du container. ça permet de faire des itérations plus rapides et de versionner et déployer bien plus proprement et rapidement (en plus de pouvoir tester plus facilement sur une machine de dev). Voire même de lancer des tâches avec tout les trucs exotiques que tu peux coller dans un docker, hihihi je te vois toi et ton script perl de l’enfer :)

Comme à chaque fois, on prend la durée de build et deploy dans les dents à chaque itération, mais je pense que c’est préférable à l’option de tout lancer en startup script et installer les dépendances et librairies à la volée à chaque exécution du batch. On maîtrise le code et les dépendances beaucoup plus simplement en container.

Appropriation de l’outil

Donc je reprends l’exemple de la doc et je l’adapte pour le faire marcher dans mon env.

Je me suis embourbé dans des histoires de permissions à essayer de comprendre et compléter l’exemple fourni.

J’ai gâché 2 bonnes heures entière à cause de ce message

│ Error: Error creating Job: googleapi: Error 403: The principal (user or service account) lacks IAM permission "cloudscheduler.jobs.create" for the resource "projects/batch-project-391715/locations/europe-west9" (or the resource may not exist).

A priori un truc très bête, le service batch ne fonctionne pas encore en zone europe-west9 puisque j’ai changé de région et ça a fonctionné (les problèmes qu’on aime tellement sur AWS qui arrivent parfois aussi sur GCP hahaha). Du coup europe-west6 it is !

juge judy, time is up

Au passage les valeurs de timezone possibles je les ai choppé ici. https://cloud.google.com/looker/docs/reference/param-view-timezone-values

voici le code “tombe en marche” que j’ai produit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
locals {

  scheduler_roles = [
    "roles/batch.jobsEditor",
    "roles/iam.serviceAccountUser",
  ]
  batch_roles = [
    "roles/batch.agentReporter",
    "roles/logging.logWriter",
]
}

resource "google_service_account" "batch_service_account" {
  account_id   = "batch-service-account"
  display_name = "Batch Service Account"
}



resource "google_project_iam_member" "batch_iam_binding" {
  count   = length(local.batch_roles)
  project = var.project
  role    = local.batch_roles[count.index]
  member  = "serviceAccount:${google_service_account.batch_service_account.email}"
}


resource "google_project_iam_member" "scheduler_iam_binding" {
  count   = length(local.scheduler_roles)
  project = var.project
  role    = local.scheduler_roles[count.index]
  member  = "serviceAccount:${google_service_account.scheduler_service_account.email}"
}

resource "google_service_account" "scheduler_service_account" {
  account_id   = "scheduler-service-account"
  display_name = "Batch scheduler Service Account"
}


resource "google_cloud_scheduler_job" "batch-job-invoker" {
  paused           = false # this cron job is enabled
  name             = "batch-job-invoker"
  project          = var.project
  region           = var.region
  schedule         = "*/5 * * * *" # when enabled, run every 5 minutes
  time_zone        = "Etc/Greenwich"
  attempt_deadline = "180s"

  retry_config {
    max_doublings        = 5
    max_retry_duration   = "0s"
    max_backoff_duration = "3600s"
    min_backoff_duration = "5s"
  }

  # when this cron job runs, create and run a Batch job
  http_target {
    http_method = "POST"
    uri         = "https://batch.googleapis.com/v1/projects/${var.project}/locations/${var.region}/jobs/"
    headers = {
      "Content-Type" = "application/json"
      "User-Agent"   = "Google-Cloud-Scheduler"
    }
    # Batch job definition
    body = base64encode(<<EOT
    {
      "taskGroups":[
        {
          "taskSpec": {
            "runnables":{
              "script": {
                "text": "echo Hello world! This job was created using Terraform and Cloud Scheduler."
              }
            }
          }
        }
      ],
      "allocationPolicy": {
        "serviceAccount": {
          "email": "${google_service_account.batch_service_account.email}"
        }
      },
      "labels": {
        "source": "terraform_and_cloud_scheduler_tutorial"
      },
      "logsPolicy": {
        "destination": "CLOUD_LOGGING"
      }
    }
    EOT
    )
    oauth_token {
      scope                 = "https://www.googleapis.com/auth/cloud-platform"
      service_account_email = google_service_account.scheduler_service_account.email
    }
  }
}

Donc ce que je comprends du bouzin que je viens de lancer, on recycle le cloudscheduler de GCP, mais dans un contexte particulier qui fait des appel au service batch. Le service batch créer un queue de workload, génère un instance group, balance un compute avec un starter script dedans et regarde si le script se lance sans erreur.

J’imagine que ça ne serait pas trop compliqué à coupler ça avec des évènements GCS ou pub/sub par exemple, il faudrait une cloudfunction probablement pour adapter l’appel à service batch.

Avec le bouton d’accès rapide au log, directement dans l’interface de batch on à un accès précis aux logs de la tâche qui nous intéresse. ça met un peu de temps à arriver mais c’est très appréciable !

1
INFO 2023-07-05T13:46:02.287420150Z Hello world! This job was created using Terraform and Cloud Scheduler.

Bon maintenant qu’on a un script qui fait echo dans un compute, on va essayer de faire des trucs un peu plus compliqués avec des containers. J’ai très envie de travailler sur l’amélioration de la syntaxe de mon TF. le mélange json + herodoc + HCL est particulièrement infâme !

couverture du livre pour enfant Beurk Beurk Beurk,Évelyne Delmon-Le Loc’h et Nathalie Janer Collection : Albums - Humour

Tips un peu à l’arrache, si on lance une création de service Batch à la main, on peut récupérer la commande gcloud pour lancer la même création en ligne de commande. Et donc un peu indirectement, on a le json qu’on peut bricolax à coup de marteau.

On a des exemples de json avec différentes configuration dans la doc https://cloud.google.com/batch/docs/create-run-job?hl=fr .

Avec un truc un peu rigolo où on peut attacher un bucket GCS directement avec fuse, hihihi :) (j’ai oublié cette idée parce que j’ai pas réussi à le faire fonctionner vraiment, en même temps fuse quand ça fonctionne, ça fonctionne pas !)

Voici ce que me donne la commande gcloud pour faire un petit container avec une image nginx et un gcs fuze accroché.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
gcloud beta batch jobs submit job-ljptdlb1 --location us-central1 --config - <<EOD
{
  "name": "projects/batch-project-391715/locations/us-central1/jobs/job-ljptdlb1",
  "taskGroups": [
    {
      "taskCount": "1",
      "parallelism": "1",
      "taskSpec": {
        "computeResource": {
          "cpuMilli": "1000",
          "memoryMib": "512"
        },
        "runnables": [
          {
            "container": {
              "imageUri": "nginx:latest",
              "entrypoint": "",
              "volumes": []
            }
          }
        ],
        "volumes": [
          {
            "gcs": {
              "remotePath": "garbage-bucket-tralala"
            },
            "mountPath": "/garbage"
          }
        ]
      }
    }
  ],
  "allocationPolicy": {
    "instances": [
      {
        "policy": {
          "provisioningModel": "STANDARD",
          "machineType": "e2-micro"
        }
      }
    ]
  },
  "logsPolicy": {
    "destination": "CLOUD_LOGGING"
  }
}
EOD

Missa ‘ancé gcloud batche dans cloud et… boum!

Star Wars, la menace fantôme, première rencontre avec Jar Jar Binks

On fait un code un peu plus élégant et maintenable

On va sortir le json dans un fichier templatable à part de la conf du scheduler.

Trois coups de ciseaux et ça a déjà plus d’allure :)

edward aux mains d’argent scène du toilettage du chien

On réduit le code du scheduler et on découple la conf qui aura son propre cycle de vie.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
locals {

  scheduler_roles = [
    "roles/batch.jobsEditor",
    "roles/iam.serviceAccountUser",
  ]
  batch_roles = [
    "roles/batch.agentReporter",
    "roles/logging.logWriter",
    "roles/artifactregistry.serviceAgent",
    "roles/storage.objectAdmin"
  ]
}

resource "google_service_account" "batch_service_account" {
  account_id   = "batch-service-account"
  display_name = "Batch Service Account"
}



resource "google_project_iam_member" "batch_iam_binding" {
  count   = length(local.batch_roles)
  project = var.project
  role    = local.batch_roles[count.index]
  member  = "serviceAccount:${google_service_account.batch_service_account.email}"
}


resource "google_project_iam_member" "scheduler_iam_binding" {
  count   = length(local.scheduler_roles)
  project = var.project
  role    = local.scheduler_roles[count.index]
  member  = "serviceAccount:${google_service_account.scheduler_service_account.email}"
}

resource "google_service_account" "scheduler_service_account" {
  account_id   = "scheduler-service-account"
  display_name = "Batch scheduler Service Account"
}


resource "google_cloud_scheduler_job" "batch-job-invoker" {
  paused           = false # this cron job is enabled
  name             = "batch-job-invoker"
  project          = var.project
  region           = var.region
  schedule         = "*/5 * * * *" # when enabled, run every 5 minutes
  time_zone        = "Etc/Greenwich"
  attempt_deadline = "180s"

  retry_config {
    max_doublings        = 5
    max_retry_duration   = "0s"
    max_backoff_duration = "3600s"
    min_backoff_duration = "5s"
  }

  # when this cron job runs, create and run a Batch job
  http_target {
    http_method = "POST"
    uri         = "https://batch.googleapis.com/v1/projects/${var.project}/locations/${var.region}/jobs/"
    headers = {
      "Content-Type" = "application/json"
      "User-Agent"   = "Google-Cloud-Scheduler"
    }

    # Batch job definition
    body = base64encode(templatefile("${path.module}/batch-configuration.json", {
      docker_batch_image           = var.docker_batch_image
      bucket_name                  = var.bucket_name
      bucket_path                  = var.bucket_path
      machine_type                 = var.machine_type
      google_service_account_email = google_service_account.batch_service_account.email

    }))

    oauth_token {
      scope                 = "https://www.googleapis.com/auth/cloud-platform"
      service_account_email = google_service_account.scheduler_service_account.email
    }
  }
}

Notre fichier de conf json, qu’on peux plus facilement auditer et vérifier:

  • Le json n’est plus complètement mélangé avec le reste du tf
  • le templating des variables sera vérifié à chaque fois
  • on peux vérifier la validité du json avec un coup de jq très rapidement
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
{
  "taskGroups": [
    {
      "taskCount": "1",
      "parallelism": "1",
      "taskSpec": {
        "computeResource": {
          "cpuMilli": "1000",
          "memoryMib": "512"
        },
        "runnables": [
          {
            "container": {
              "imageUri": "${docker_batch_image}"
            },
            "environment": {
              "variables": {
                "BUCKET_PATH": "${bucket_path}",
                "BUCKET_NAME" :"${bucket_name}"
              }
            }
          }
        ]
      }
    }
  ],
  "allocationPolicy": {
    "serviceAccount": {
      "email": "${google_service_account_email}"
    },
    "instances": [
      {
        "policy": {
          "provisioningModel": "STANDARD",
          "machineType": "${machine_type}"
        }
      }
    ]
  },
  "logsPolicy": {
    "destination": "CLOUD_LOGGING"
  }
}

Je sais pas si c’est moche et compliqué parce qu’on appelle le service batch par HTTP, ou si c’est crados par design !

Peux être qu’on peut faire des jobs plus simplement avec des objets HCL natif, mais faut reconnaître que c’est casse-pied.

Quand je trouve des trucs comme ça …

shohei-ihaya-dena commented on Jan 25
Is Cloud Batch ( https://cloud.google.com/batch/docs/get-started ) supported?

I can't find the terraform resources named batch ...

edwardmedia commented on Jan 26
Not supported

RodolpheGohard commented on Jan 30
I was wondering the same. Is there any plan to implement it ? should we create feature request ?

github-actions bot commented on Mar 2
I'm going to lock this issue because it has been closed for 30 days hourglass_flowing_sand. 
[...]

source https://github.com/hashicorp/terraform-provider-google/issues/13568

ça peut expliquer le code mélangé du scheduler Terraform avec le json un peu fouilli :)

captain picard, facepalm à l’Aquarelle

je compile un Dockerfile et un script bash un peu bullshit et on regarde où ça nous emmène.

1
2
3
4
5
FROM google/cloud-sdk
COPY ./script.sh .
RUN chmod +x ./script.sh
RUN mkdir /opt/garbage
CMD ["./script.sh"]

le minimum pour utiliser gsutil, avoir un répertoire où écrire et rendre le script exécutable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash
for i in {1..5}
do
    random_string="$(echo $RANDOM | sha256sum | base64 | head -c 32 ; echo)"
    random_file="${BUCKET_PATH}/${random_string}.txt"
    echo "write file $random_file"
    head -c "5MB" /dev/urandom > "$random_file"
    sleep 1
    ls -la "${BUCKET_PATH}"
done

gsutil cp "${BUCKET_PATH}*" "gs://$BUCKET_NAME"

Rien de super malin, on fait une boucle qui nous génère des fichiers avec des noms random. Le but c’est de vérifier que nos fichiers sont bien créés et copiés dans le bucket.

un coup de gsutil cp pour envoyer ça dans un bucket en fin de script.

ça a l’air de rien mais notre moulinette nous permet de tester ces actions:

  • lancer un script dans un container custom
  • lire des variables d’env dans le container
  • appel vers des services managé (envoi des fichiers vers GCS)
  • vérifier que notre container peut avoir des droits via le service account custom fourni dans la conf
  • pouvoir lire les logs de manières simple et efficace

Voici les logs de mon batch, bon les logs de gsutil sont en erreurs mais ça doit être gsutil qui écrit pas correctement dans stdout de façon propre et standard.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
INFO 2023-07-09T16:35:49.175667512Z write file /opt/garbage/MGM4NWFlMTIwYTRmNjRlNWVmMDNhNzBi.txt
INFO 2023-07-09T16:35:49.401667531Z write file /opt/garbage/ZTNjOWEzMDI3NDRiZDVkMTg3NDZmM2Q5.txt
INFO 2023-07-09T16:35:49.422526493Z write file /opt/garbage/NjY4YmM3NzgyNDRjZGZkN2Y5NDkwNWI3.txt
INFO 2023-07-09T16:35:49.663122603Z write file /opt/garbage/ZGQ0NWE2Njc1NTI2ZWQ4NTlmNTMzZjhj.txt
INFO 2023-07-09T16:35:49.903603773Z write file /opt/garbage/MTczNDAzYTJlM2MxYWUzYzA0ZmFkZGZh.txt
ERROR 2023-07-09T16:35:59.900131415Z Copying file:///opt/garbage/MGM4NWFlMTIwYTRmNjRlNWVmMDNhNzBi.txt [Content-Type=text/plain]...
ERROR 2023-07-09T16:35:59.900397765Z / [0 files][ 0.0 B/ 4.8 MiB]
ERROR 2023-07-09T16:36:01.178535092Z / [0 files][264.0 KiB/ 4.8 MiB] -
ERROR 2023-07-09T16:36:01.508609861Z - [1 files][ 4.8 MiB/ 4.8 MiB]
ERROR 2023-07-09T16:36:01.511401282Z Copying file:///opt/garbage/ZTNjOWEzMDI3NDRiZDVkMTg3NDZmM2Q5.txt [Content-Type=text/plain]...
ERROR 2023-07-09T16:36:01.511560412Z - [1 files][ 4.8 MiB/ 9.5 MiB]
ERROR 2023-07-09T16:36:02.655755534Z - [1 files][ 5.0 MiB/ 9.5 MiB] \
ERROR 2023-07-09T16:36:02.966976938Z \ [2 files][ 9.5 MiB/ 9.5 MiB]
ERROR 2023-07-09T16:36:02.969391558Z Copying file:///opt/garbage/ZGQ0NWE2Njc1NTI2ZWQ4NTlmNTMzZjhj.txt [Content-Type=text/plain]... \ [2 files][ 9.5 MiB/ 14.3 MiB]
ERROR 2023-07-09T16:36:03.659255624Z |
ERROR 2023-07-09T16:36:03.968133199Z | [3 files][ 14.3 MiB/ 14.3 MiB]
ERROR 2023-07-09T16:36:03.971052339Z Copying file:///opt/garbage/NjY4YmM3NzgyNDRjZGZkN2Y5NDkwNWI3.txt [Content-Type=text/plain]... | [3 files][ 14.3 MiB/ 19.1 MiB]
ERROR 2023-07-09T16:36:04.669470734Z /
ERROR 2023-07-09T16:36:04.976088599Z / [4 files][ 19.1 MiB/ 19.1 MiB]
ERROR 2023-07-09T16:36:04.978421779Z ==> NOTE: You are performing a sequence of gsutil operations that may run significantly faster if you instead use gsutil -m cp ... Please see the -m section under "gsutil help options" for further information about when gsutil -m can be advantageous.
ERROR 2023-07-09T16:36:04.979072349Z Copying file:///opt/garbage/MTczNDAzYTJlM2MxYWUzYzA0ZmFkZGZh.txt [Content-Type=text/plain]...
ERROR 2023-07-09T16:36:04.979376309Z / [4 files][ 19.1 MiB/ 23.8 MiB]
ERROR 2023-07-09T16:36:05.680937556Z -
ERROR 2023-07-09T16:36:05.997089773Z - [5 files][ 23.8 MiB/ 23.8 MiB]
ERROR 2023-07-09T16:36:05.998942663Z Operation completed over 5 objects/23.8 MiB.

Au final on se retrouve avec

Le scheduler dans l’interface GCP, qui va nous planifier des jobs toutes les 5 minutes.

capture UI de cloud scheduler, status de l’exécution success region europe-west6 status enable frequency */5 * * * *  ETC

les jobs planifiés et exécutés dans le service batch.

En un coup d’œil on à l’historique des jobs et des résultats d’exécution de façon précise.

capture UI des jobs dans batch, 1 job success 2 jobs sheduled

mes fichiers généré que je retrouve dans GCS

vue des fichiers dans le bucket gcs cible

Infusion

Est ce qu’on préfère pas des computes et des crontab à l’ancienne ?

ça vous dit pas de maintenir des machines à l’ancienne et de faire des connections SSH comme au bon vieux temps ? Le plaisir infini de faire des df pour voir si les disques sont pleins et le plaisir absolu de faire des apt upgrade manuellement ! On adore garder allumé des machines qui font rien la plupart du temps et s’émerveiller de les voir planter à intervalle régulier !

pot de moutarde à l’ancienne

Bon OK, de toute façon chatGPT va tous nous remplacer, le moment où il sait faire une connexion SSH sur la prod on est tous foutu :)

En attendant, j’adore la philosophie de ce service batch :

  • on sait à l’échelle industrielle si nos batchs fonctionnent ou pas
  • on pose le truc dans un coin et on s’en occupe plus jamais si ça fonctionne
    • c’est marrant tiens, exactement comme nos cron tout pourris en compute
  • on peut livrer du code en containers de manières industrielle
    • et ça change tout pas rapport à un compute chaussette sale
  • le truc tourne seulement quand on en à besoin sur une très longues période si besoin et on paye ce qu’on consomme
  • le truc est configurable et fonctionne pour faire du HPC ou du GPU si tu veux
    • tu veux faire du bash en compute ? pas de soucis !
    • je vous ai déjà dit que j’adore les services qui jugent pas ?

Tout s’est bien passé, j’ai presque pas galéré, j’ai trouvé de la doc (que j’ai lue en diagonales) et des exemples qui fonctionnent.

Je sais pas quoi dire de plus sur ce service, encore une fois bravo Google.

obama boit une bière au bar avec la légende well played

merci à Emmanuel Chaplais pour la correction