Migration de base de données avec Cloud Seed.
Pour commencer, nous allons d’abord explorer Cloud Seed.
Cloud Seed is an open-source collaboration between Google Cloud and GitLab to accelerate cloud adoption and app-modernization.
Cloud Seed makes it ridiculously simple to provision and consume Google Cloud services within the GitLab web UI.
Dans cet article, on verra comment utiliser Cloud Seed pour concevoir des pipelines de migrations de base de données sur Cloud SQL. À la base, Cloud Seed nous permet d’effectuer un certain nombre de choses tel que :
- Déployer des applications Web basées sur des conteneurs sur Cloud Run
- Créer des instances de Cloud SQL pour PostgreSQL, MySQL, SQL Server, …
L’objectif de cet article, est de tirer parti des avantages de Cloud Seed pour effectuer d’autres actions comme la migration de base de données.
Let’s go …
- Configuration de l’environnement
Dans le dashboard du projet GitLab, sélectionnez Infrastructure > Google Cloud > Configuration. Après cela, vous serez amené à vous connecter avec votre compte Google Cloud.
Une fois que c’est fait, nous allons utiliser Cloud Seed pour créer un service account qui va nous permettre d’accéder à certains services Google Cloud tels que : Cloud Run, Cloud SQL for Postgres, Cloud Storage, …
Personnellement, je pense que le fait d’avoir un service account qui dispose d’une panoplie de rôles n’est pas trop bon pour la sécurité.
Lors de la création du service account nous allons choisir la branche
ou le tag
qui sera lié à ce dernier.
Maintenant, nous allons configurer la région
dans laquelle nous allons exécuter notre charge de travail.
Pour finir, nous allons créer une instance Cloud SQL pour Postgres.
Aller dans Infrastructure > Google Cloud > Databases.
Une fois que c’est bon, nous allons configurer le fichier .gitlab-ci.yml
pour l’intégration continue.
# File: .gitlab-ci.yml
stages:
- database-migration
database-migration:
stage: database-migration
image: registry.gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library/google-cloud-sdk-for-gitlab:main
script:
- chmod +x cloud-migration.sh
- ./cloud-migration.sh
environment:
name: migration/$CI_COMMIT_REF_NAME
action: stop
Dans le fichier .gitlab-ci.yml
, nous allons exécuter le fichier cloud-migration.sh
que voici 👇.
## cloud-migration.sh
## utils
error_and_exit() {
local MESSAGE="${1}"
local HINT="${2}"
echo ""
echo "🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥"
echo ""
echo "Error \`cloud-run.sh\`"
echo "===================="
echo ""
echo "Message"
echo "-------"
echo "$MESSAGE"
echo ""
echo "Hint"
echo "----"
echo "$HINT"
echo ""
echo "/end"
echo ""
exit 1
}
## required environment variables
if [[ -z "$GCP_PROJECT_ID" ]]; then
error_and_exit "\$GCP_PROJECT_ID is not set" "Did you setup a service account?"
fi
if [[ -z "$GCP_SERVICE_ACCOUNT" ]]; then
error_and_exit "\$GCP_SERVICE_ACCOUNT is not set" "Did you setup a service account?"
fi
if [[ -z "$GCP_SERVICE_ACCOUNT_KEY" ]]; then
error_and_exit "\$GCP_SERVICE_ACCOUNT_KEY is not set" "Did you setup a service account?"
fi
if [[ -z "$CI_PROJECT_ID" ]]; then
error_and_exit "\$CI_PROJECT_ID is not set"
fi
if [[ -z "$CI_COMMIT_REF_SLUG" ]]; then
error_and_exit "\$CI_COMMIT_REF_SLUG is not set"
fi
## private variables
SERVICE_NAME="gitlab-$CI_PROJECT_ID-$CI_COMMIT_REF_SLUG"
__GCP_SERVICE_ACCOUNT_KEY_PRIVATE_KEY_DATA_FILE_NAME=local-service-account-key-private-key-data.txt
__GCP_SERVICE_ACCOUNT_KEY_FILE_NAME=local-service-account-key-file.json
## cleanup tmp files
rm --force $__GCP_SERVICE_ACCOUNT_KEY_PRIVATE_KEY_DATA_FILE_NAME
rm --force $__GCP_SERVICE_ACCOUNT_KEY_FILE_NAME
## extract service account key file
case "$GCP_SERVICE_ACCOUNT_KEY" in
*privateKeyData*)
echo "🟩🟩 '.privateKeyData' found"
echo "$GCP_SERVICE_ACCOUNT_KEY" | jq --raw-output '.privateKeyData' >$__GCP_SERVICE_ACCOUNT_KEY_PRIVATE_KEY_DATA_FILE_NAME
base64 --decode $__GCP_SERVICE_ACCOUNT_KEY_PRIVATE_KEY_DATA_FILE_NAME >$__GCP_SERVICE_ACCOUNT_KEY_FILE_NAME
;;
*private_key_data*)
echo "🟩🟩 '.private_key_data' found"
echo "$GCP_SERVICE_ACCOUNT_KEY" | jq --raw-output '.private_key_data' >$__GCP_SERVICE_ACCOUNT_KEY_FILE_NAME
;;
*)
error_and_exit "Failed to extract service account key file" "Did you setup a service account?"
;;
esac
## gcloud auth and configure
gcloud auth activate-service-account --key-file $__GCP_SERVICE_ACCOUNT_KEY_FILE_NAME || error_and_exit "Failed to activate service account"
gcloud config set project $GCP_PROJECT_ID || error_and_exit "Failed to set GCP project"
## gcloud command for migration
gcloud builds submit . --config=cloudbuild.yaml || error_and_exit "Failed to Database Migration "
Avec cloud-migration.sh
nous allons établir la connexion avec Google Cloud et faire appel à Cloud Build afin d’exécuter le fichier cloudbuild.yaml
pour effectuer notre migration.
# File: cloudbuild.yaml
steps:
# build the container image
- name: 'gcr.io/cloud-builders/docker'
args: [ 'build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/students/${_IMAGE_NAME}', '.' ]
# push the container image
- name: 'gcr.io/cloud-builders/docker'
args: [ 'push', 'us-central1-docker.pkg.dev/$PROJECT_ID/students/${_IMAGE_NAME}']
- name: "gcr.io/google-appengine/exec-wrapper"
entrypoint: 'bash'
args: ["-c",
"/buildstep/execute.sh -i us-central1-docker.pkg.dev/$PROJECT_ID/students/${_IMAGE_NAME} -s $$CONNECTION_NAME -e DATABASE_URL=$$DATABASE_URL -- alembic upgrade head"]
secretEnv: ['DATABASE_URL', 'CONNECTION_NAME']
options:
logging: CLOUD_LOGGING_ONLY
substitutions:
_IMAGE_NAME: "img-students-api"
availableSecrets:
secretManager:
- versionName: projects/$PROJECT_ID/secrets/DATABASE_URL/versions/latest
env: 'DATABASE_URL'
- versionName: projects/$PROJECT_ID/secrets/CONNECTION_NAME/versions/latest
env: 'CONNECTION_NAME'
Dans le fichier cloudbuild.yaml
, il y a deux variables d’environnement à savoir DATABASE_URL
et CONNECTION_NAME
que nous allons stocker dans Secret Manager pour des raisons de sécurité.
DATABASE_URL=postgresql://username:password@localhost/databasename?host=/cloudsql/project-id:region:instance-id
CONNECTION_NAME=project-id:region:instance-id
Pour enregistrer une variable dans Secret Manager
, sélectionnez Security
suivi de Secret Manager
dans le menu en haut à gauche de Google Cloud. Cliquez ensuite sur CREATE SECRET
et mettez le nom de la variable et la valeur du secret. Laissez le reste des paramètres par défaut et créer votre secret.
NB: Utiliser les vraies variables.
- Service account
Nous allons apporter des modifications au service account qui a été créé plus haut parce qu’il dispose de certains rôles dont nous n’avons pas besoin. Pour cela, il faut sélectionner IAM & Admin
suivi de IAM
dans le menu en haut à gauche. Une fois que vous êtes dans IAM
, chercher le service account sous la forme gitlab-xxxxxxxxxxxxxxxxxxxxxx
et modifier ces rôles comme suit 👇.
Pour effectuer notre migration, le service account de Cloud Build aura besoin des rôles suivant : Cloud Build Service Account
, Cloud SQL Client
, Secret Manager Secret Accessor
et Service Account User
.
- Artifact Registry
Pour finir, nous allons créer un repo Docker pour stocker nos images Docker.
C’est le moment de lancer notre pipeline pour la migration de données🤞.
Mission accomplie, la migration a été effectuer avec succès.
Le code est disponible ici 👇 .
Merci pour la lecture, j’espère que vous avez aimé. À la prochaine.👋