Close

Déployer ImageLabeller avec GitLab

Portrait de Warren Marusiak
Warren Marusiak

Senior Technical Evangelist

Pour montrer comment développer, déployer et gérer des applications à l'aide de Jira Software et de divers outils connectés, notre équipe a créé ImageLabeller, une application de démo simple basée sur AWS qui utilise l'apprentissage machine pour appliquer des étiquettes à des images.

Cette page explique comment déployer ImageLabeller avec GitLab. Avant de commencer, nous vous recommandons de lire les pages consacrées à l'architecture d'ImageLabeller et à la configuration d'AWS SageMaker pour plus de contexte.

Prérequis

Si vous n'avez pas encore de groupe GitLab, suivez les étapes indiquées dans ce guide GitLab pour en créer un de A à Z.

Dépôts GitHub publics avec code ImageLabeller

https://github.com/AtlassianOpenDevOpsGuides

Vidéo de démo de l'intégration de Jira et GitLab

Intégrer Jira et GitLab

Depuis Jira, cliquez sur Board (Tableau), sur Apps, puis sur GitLab.

Capture d'écran du menu déroulant dans Jira Software pour accéder à GitLab

Cliquez sur Get it now (Télécharger maintenant).

Fenêtre modale de l'app GitLab dans Jira Software

Cliquez sur Apps, puis sur Manage your apps (Gérer vos apps).

Fenêtre modale de l'app GitLab dans Jira Software avec menu déroulant

Développez GitLab for Jira.

Développer GitLab sur l'écran de gestion des apps dans Jira Software

Cliquez sur Add namespace (Ajouter un espace de noms).

Écran d'ajout d'un espace de noms à votre configuration GitLab dans Jira Software

Sélectionnez votre espace de noms existant et cliquez sur Link (Lier). Ce guide part du principe que vous disposez déjà d'un compte GitLab et d'un groupe GitLab.

Associer un espace de noms GitLab dans Jira Software

Ajouter une clé SSH à GitLab

Cliquez sur l'icône de votre profil en haut à droite, puis sur Preferences (Préférences).

Navigation dans les préférences à l'aide du menu déroulant de GitLab

Cliquez sur SSH Keys (Clés SSH) et suivez les instructions pour générer une nouvelle clé SSH ou utiliser une clé SSH existante.

Créer un dépôt pour l'infrastructure AWS S3

Dans une boucle de développement standard, un développeur choisit généralement une tâche depuis Jira, la déplace vers la section Work in progress (Travail en cours), puis effectue le travail de développement. L'identifiant du ticket Jira est la clé qui relie le travail de développement au ticket Jira. C'est le principal composant d'intégration entre les deux systèmes.

Accédez à Jira et créez un ticket pour ajouter un dépôt d'infrastructure AWS S3 dans GitLab. Notez l'identifiant du ticket. Dans cet exemple : IM-5.

Création d'un ticket pour votre tableau dans Jira Software

Dans GitLab, cliquez sur New project (Nouveau projet).

Navigation pour créer un projet dans GitLab

Cliquez sur Create blank project (Créer un projet vierge).

Création d'un projet dans GitLab

Ajoutez un nom de projet (Project name) et choisissez le groupe approprié dans Project URL (URL du projet). Cliquez sur Create project (Créer un projet) pour continuer.

Création d'un projet : écran détaillé dans GitLab

Dans votre terminal, accédez à votre dépôt s3_infra et exécutez les commandes suivantes pour pusher votre fichier template.yml AWS CloudFormation vers GitLab.

git add --all
git commit -m "IM-5 add s3_infra repository to gitlab"
git remote add origin git@gitlab.com:pmmquickstartguides/s3_infra.git
git branch -m mainline
git push -u origin mainline

Ajouter une clé d'accès AWS

Cliquez sur Settings (Paramètres), puis sur CI/CD. Faites défiler l'écran vers le bas et développez Variables. Cliquez sur Add variable (Ajouter une variable).

Page des paramètres de CI/CD dans GitLab

Créez deux variables : une pour votre identifiant de clé d'accès AWS et une pour votre clé d'accès secrète AWS.

Fenêtre modale d'ajout de variable pour ajouter vos clés AWS dans GitLab

Protégez les variables afin qu'elles ne soient utilisées que par des pipelines s'exécutant sur des branches et des étiquettes protégées. Donnez accès à l'utilisateur IAM associé à la clé d'accès AWS AdministratorAccess. Vous pouvez aussi choisir d'utiliser un contrôle d'accès plus fin en optant pour des politiques d'accès AWS individuelles.

Clés AWS répertoriées dans la section « Variables » de la page des paramètres de CI/CD de GitLab

Configurer des branches protégées pour accéder à des variables protégées

Cliquez sur Settings (Paramètres), puis sur Repository (Dépôt). Faites défiler l'écran vers le bas et développez Protected branches (Branches protégées).

Saisissez le préfixe de l'identifiant de votre ticket Jira et le symbole *.

Dans cet exemple, les identifiants des tickets Jira sont les suivants : IM-5 et IM-6. Leur préfixe est donc « IM- ».

Saisissez IM-*, puis cliquez sur Protect (Protéger).

Configuration de branches protégées dans GitLab

Vous verrez la branche principale et IM-* comme des branches protégées.

Configurer des environnements de déploiement

Cliquez sur Deployments (Déploiements), puis sur Environments (Environnements). Cliquez sur New environment (Nouvel environnement) pour ajouter de nouveaux environnements. Dans cet exemple, nous voyons des environnements de test (US-WEST-1 et US-EAST-2) et des environnements de production (US-WEST-2, US-EAST-1 et CA-CENTRAL-1).

Configuration d'environnements de déploiement dans GitLab

Fichier .gitlab-ci.yml pour le déploiement sur AWS

Accédez au dépôt s3_infra de votre terminal, créez une branche portant l'identifiant de votre ticket Jira.

git checkout -b IM-5

Créez un fichier .gitlab-ci.yml avec le code yaml suivant. Cela définit un workflow de déploiement pour vos environnements de test, de staging et de production.

stages:
  - merge-request
  - test-us-west-1
  - test-us-east-2
  - production-us-west-2
  - production-us-east-1
  - production-ca-central-1

merge-request-pipeline-job:
  stage: merge-request
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - echo "This pipeline always succeeds and enables merges during merge requests"
    - echo true

deploy-test-us-west-1:
  stage: test-us-west-1
  environment: test-us-west-1
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - aws cloudformation deploy --region us-west-1 --template-file template.yml --stack-name OpenDevOpsS3Infra

deploy-test-us-east-2:
  stage: test-us-east-2
  environment: test-us-east-2
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - aws cloudformation deploy --region us-east-2 --template-file template.yml --stack-name OpenDevOpsS3Infra

deploy-production-us-west-2:
  stage: production-us-west-2
  environment: production-us-west-2
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - aws cloudformation deploy --region us-west-2 --template-file template.yml --stack-name OpenDevOpsS3Infra

deploy-production-us-east-1:
  stage: production-us-east-1
  environment: production-us-east-1
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - aws cloudformation deploy --region us-east-1 --template-file template.yml --stack-name OpenDevOpsS3Infra

deploy-production-ca-central-1:
  stage: production-ca-central-1
  environment: production-ca-central-1
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - aws cloudformation deploy --region ca-central-1 --template-file template.yml --stack-name OpenDevOpsS3Infra

Comprendre un fichier .gitlab-ci.yml

Étapes

Ajoutez un bloc stages (étapes) pour définir l'ordre d'exécution de votre pipeline GitLab. Les étapes sont exécutées dans l'ordre dans lequel elles sont définies dans le bloc des étapes. Les tâches associées à une étape sont exécutées en parallèle.

stages:
  - merge-request
  - test-us-west-1
  - test-us-east-2
  - production-us-west-2
  - production-us-east-1
  - production-ca-central-1

Emplois

Les tâches sont associées à une étape et peuvent être liées à un environnement. Les règles contrôlent si une tâche donnée doit être exécutée ou non. La règle de cet exemple vérifie si la branche du pipeline n'est pas la branche par défaut et si le pipeline n'est pas exécuté automatiquement dans le cadre d'une demande de merge.

Vous pouvez spécifier une image différente pour chaque tâche. Vous pouvez créer des images à l'aide des outils nécessaires à vos scripts de tâche. La section script définit l'ensemble des étapes qui s'exécutent lorsque la tâche est lancée.

deploy-test-us-west-1:
  stage: test-us-west-1
  environment: test-us-west-1
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - aws cloudformation deploy --region us-west-1 --template-file template.yml --stack-name OpenDevOpsS3Infra

Pipeline de demandes de merge

Un pipeline est automatiquement exécuté par GitLab lorsqu'une demande de merge est approuvée. Vous pouvez créer une tâche pour ce pipeline en ajoutant une règle. La tâche réussit toujours dans cet exemple.

merge-request-pipeline-job:
  stage: merge-request
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - echo "This pipeline always succeeds and enables merges during merge requests"
    - echo true

Faire un push vers une branche de fonctionnalité

Exécutez l'instruction suivante depuis la ligne de commande pour pusher vos changements vers la branche IM-5 de votre dépôt s3_infra. Incluez l'identifiant du ticket Jira dans les messages de commit et les noms des branches pour permettre à l'intégration Jira GitLab de suivre l'évolution de votre projet.

git add --all
git commit -m "IM-5 add .gitlab-ci.yml to s3_infra"
git push -u origin IM-5

Cliquez sur CI/CD, puis sur Pipelines pour voir le pipeline s'exécuter.

Écran des pipelines de CI/CD dans GitLab

Cliquez sur l'identifiant du pipeline en cours d'exécution.

Identifiant du pipeline en cours d'exécution dans GitLab

Cliquez sur une tâche pour en savoir plus.

Écran détaillé des tâches pour le pipeline en cours d'exécution dans GitLab

Créer une demande de merge

Pour créer une demande de merge, cliquez sur Merge requests (Demandes de merge), puis sur Create merge request (Créer une demande de merge).

Écran de demandes de merge dans GitLab

Choisissez votre branche de fonctionnalité comme branche source, puis cliquez sur Compare branches and continue (Comparer les branches et continuer).

Comparaison de la branche source et de la branche cible dans GitLab

Choisissez un responsable (Assignee) et un réviseur (Reviewer).

Choix d'un réviseur pour votre demande de merge dans GitLab

Cliquez sur Create merge request (Créer une demande de merge).

Sélection du bouton de création d'une demande de merge dans GitLab

Passez en revue les changements apportés au code, puis cliquez sur Approve (Approuver).

Écran détaillé de demande de merge où vous pouvez consulter les changements apportés à GitLab

Cliquez sur CI/CD, puis sur Pipelines pour voir le pipeline de demandes de merge s'exécuter.

Navigation vers l'écran « Pipelines » de GitLab pour voir les demandes de merge

Cliquez sur l'identifiant du pipeline. Notez que la tâche merge-request-pipeline-job est la seule qui a été exécutée.

Page détaillée « Pipeline » montrant que seule la tâche merge-request-pipeline-job a été exécutée dans GitLab

Pour revenir à la demande de merge, cliquez sur Merge requests (Demandes de merge), sur la demande de merge active, puis sur Merge (Merger). Cela lance un autre pipeline.

Merge de la demande de merge active dans GitLab

Cliquez sur CI/CD, puis sur Pipelines. Cliquez sur l'identifiant du pipeline.

Page détaillée du pipeline dans GitLab affichant « Merge branch 'IM-5' into 'mainline' » (Merger la branche « IM-5 » dans la « branche principale »)

Créer un dépôt pour SystemTests

Accédez à Jira et créez un ticket Jira pour ajouter un dépôt SystemTests dans GitLab. Notez l'identifiant du ticket Jira. Dans cet exemple : IM-7.

Création d'un ticket dans Jira Software pour ajouter un dépôt GitLab pour SubmitImage AWS Lambda

Ajoutez un nom de projet (Project name) et choisissez le groupe approprié dans Project URL (URL du projet). Cliquez sur Create project (Créer un projet) pour continuer.

Saisie des informations du projet lors de la création d'un projet dans GitLab

Dans votre terminal, accédez à votre dépôt SystemTests et exécutez les commandes suivantes pour pusher votre code vers GitLab.

git add --all
git commit -m "IM-7 add SystemTests repository to gitlab"
git remote add origin git@gitlab.com:pmmquickstartguides/systemtests.git
git branch -m mainline
git push -u origin mainline

Le dépôt SystemTests n'a pas besoin d'un fichier .gitlab-ci.yml. Il n'a pas de pipeline propre, puisqu'il permet de tester le fonctionnement d'autres pipelines. Notez l'URL distante de votre dépôt SystemTests. Les pipelines de CI/CD SubmitImage, GetImageLabel et InvokeLabeller cloneront le dépôt SystemTests pendant les étapes de test. Vous devrez mettre à jour le fichier gitlab-ci.yml des dépôts ultérieurs avec la bonne URL.

Ajouter un jeton de déploiement

Vous devez ajouter un jeton de déploiement pour cloner ce dépôt lors de l'exécution d'autres pipelines. Cliquez sur Settings (Paramètres), puis sur Repository (Dépôt). Faites défiler l'écran vers le bas et développez Deploy tokens (Jetons de déploiement).

Saisie d'un exemple de nom « CloneMe » sous « Deploy tokens » (Jetons de déploiement) dans GitLab

Saisissez un nom, cochez read_repository, puis cliquez sur Create deploy token (Créer un jeton de déploiement).

Activation de la case « read_repository » sur la page des paramètres « Deploy tokens » (Jetons de déploiement) dans GitLab

Le nom d'utilisateur correspondant au jeton de déploiement est généré automatiquement. Le mot de passe est fourni une seule fois lors de la création. Ajoutez-le à un outil de gestion des secrets afin de vous y reporter ultérieurement. Plus loin dans ce guide, le nom d'utilisateur associé au jeton de déploiement est appelé gitlab_deploy_token et le mot de passe, gitlab_deploy_password.

Écran des jetons de déploiement dans GitLab, affichant le nom d'utilisateur et le mot de passe associés à un jeton de déploiement

Créer un dépôt pour SubmitImage AWS Lambda

Accédez à Jira et créez un ticket pour ajouter un dépôt SubmitImage AWS Lambda dans GitLab. Notez l'identifiant du ticket. Dans cet exemple : IM-8.

Tableau ImageLabeller dans Jira Software : mise en évidence du ticket « IM-8 add GitLab repo for SubmitImage AWS Lambda » (IM-8 Ajout d'un dépôt GitLab pour SubmitImage AWS Lambda)

Dans GitLab, cliquez sur New project (Nouveau projet), puis sur Create blank project (Créer un projet vierge). Ajoutez un nom de projet (Project name) et choisissez le groupe approprié dans Project URL (URL du projet). Cliquez sur Create project (Créer un projet) pour continuer.

Capture d'écran montrant la création d'un projet « SubmitImage » dans GitLab

Dans votre terminal, accédez à votre dépôt SubmitImage et exécutez les commandes suivantes pour pusher votre code vers GitLab.

git add --all
git commit -m "IM-8 add SubmitImage to gitlab"
git remote add origin git@gitlab.com:pmmquickstartguides/submitimage.git
git branch -m mainline
git push -u origin mainline

Vous devez ajouter des clés d'accès AWS, configurer des branches protégées et configurer des environnements de déploiement.

Ensuite, ajoutez les clés de déploiement de votre dépôt SystemTests pour permettre le téléchargement du pipeline SubmitImage GitLab, et lancez SystemTests.

Enfin, ajoutez votre identifiant de compte AWS en tant que variable de CI/CD.

Capture d'écran montrant l'écran des variables dans GitLab

Fichier .gitlab-ci.yml pour le déploiement sur AWS

Accédez au dépôt SubmitImage de votre terminal, créez une branche portant l'identifiant de votre ticket Jira.

git checkout -b IM-8

Créez un fichier .gitlab-ci.yml avec le code yaml suivant. Cela définit un workflow de déploiement pour vos environnements de test, de staging et de production. Vous devez mettre à jour la ligne git clone pour que SystemTests devienne votre dépôt SystemTests.

stages:
  - merge-request
  - run-unit-tests
#US-WEST-1
  - deploy-us-west-1
  - test-us-west-1
#US-EAST-2
  - deploy-us-east-2
  - test-us-east-2
#US-WEST-2
  - deploy-us-west-2
  - test-us-west-2
#US-EAST-1
  - deploy-us-east-1
  - test-us-east-1
#CA-CENTRAL-1
  - deploy-ca-central-1
  - test-ca-central-1

merge-request-pipeline-job:
  stage: merge-request
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - echo "This pipeline always succeeds and enables merge"
    - echo true

run-unit-tests:
  stage: run-unit-tests
  image: golang:buster
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  script:
    - cd submitImage
    - go test ./opendevopslambda/...

#US-WEST-1
deploy-us-west-1:
  stage: deploy-us-west-1
  environment: test-us-west-1
  image: python:latest
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
    - wget https://golang.org/dl/go1.16.6.linux-amd64.tar.gz
    - rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.6.linux-amd64.tar.gz
    - export PATH=$PATH:/usr/local/go/bin
    - go version
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file submit-image-packaged.yaml --s3-bucket open-devops-code-us-west-1-$AWS_ACCOUNT_ID --region us-west-1
    - sam deploy --template-file submit-image-packaged.yaml --stack-name OpenDevOpsSubmitImage  --s3-bucket open-devops-code-us-west-1-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region us-west-1 --no-fail-on-empty-changeset

      #test-us-west-1:
      #  stage: test-us-west-1
      #  environment: test-us-west-1
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=us-west-1

#US-EAST-2
deploy-us-east-2:
  stage: deploy-us-east-2
  environment: test-us-east-2
  image: python:latest
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
    - wget https://golang.org/dl/go1.16.6.linux-amd64.tar.gz
    - rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.6.linux-amd64.tar.gz
    - export PATH=$PATH:/usr/local/go/bin
    - go version
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file submit-image-packaged.yaml --s3-bucket open-devops-code-us-east-2-$AWS_ACCOUNT_ID --region us-east-2
    - sam deploy --template-file submit-image-packaged.yaml --stack-name OpenDevOpsSubmitImage  --s3-bucket open-devops-code-us-east-2-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region us-east-2 --no-fail-on-empty-changeset

      #test-us-east-2:
      #  stage: test-us-east-2
      #  environment: test-us-east-2
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=us-east-2

#US-WEST-2
deploy-us-west-2:
  stage: deploy-us-west-2
  environment: production-us-west-2
  image: python:latest
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
    - wget https://golang.org/dl/go1.16.6.linux-amd64.tar.gz
    - rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.6.linux-amd64.tar.gz
    - export PATH=$PATH:/usr/local/go/bin
    - go version
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file submit-image-packaged.yaml --s3-bucket open-devops-code-us-west-2-$AWS_ACCOUNT_ID --region us-west-2
    - sam deploy --template-file submit-image-packaged.yaml --stack-name OpenDevOpsSubmitImage  --s3-bucket open-devops-code-us-west-2-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region us-west-2 --no-fail-on-empty-changeset

      #test-us-west-2:
      #  stage: test-us-west-2
      #  environment: production-us-west-2
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=us-west-2

#US-EAST-1
deploy-us-east-1:
  stage: deploy-us-east-1
  environment: production-us-east-1
  image: python:latest
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
    - wget https://golang.org/dl/go1.16.6.linux-amd64.tar.gz
    - rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.6.linux-amd64.tar.gz
    - export PATH=$PATH:/usr/local/go/bin
    - go version
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file submit-image-packaged.yaml --s3-bucket open-devops-code-us-east-1-$AWS_ACCOUNT_ID --region us-east-1
    - sam deploy --template-file submit-image-packaged.yaml --stack-name OpenDevOpsSubmitImage  --s3-bucket open-devops-code-us-east-1-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region us-east-1 --no-fail-on-empty-changeset

      #test-us-east-1:
      #  stage: test-us-east-1
      #  environment: production-us-east-1
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=us-east-1

#CA-CENTRAL-1
deploy-central-1:
  stage: deploy-ca-central-1
  environment: production-ca-central-1
  image: python:latest
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
    - wget https://golang.org/dl/go1.16.6.linux-amd64.tar.gz
    - rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.6.linux-amd64.tar.gz
    - export PATH=$PATH:/usr/local/go/bin
    - go version
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file submit-image-packaged.yaml --s3-bucket open-devops-code-ca-central-1-$AWS_ACCOUNT_ID --region ca-central-1
    - sam deploy --template-file submit-image-packaged.yaml --stack-name OpenDevOpsSubmitImage  --s3-bucket open-devops-code-ca-central-1-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region ca-central-1 --no-fail-on-empty-changeset

      #test-central-1:
      #  stage: test-ca-central-1
      #  environment: production-ca-central-1
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=ca-central-1

L'exécution des tests d'intégration est commentée pour l'instant. Les tests système ne seront réussis que lorsque l'application complète sera déployée. Supprimez les commentaires pour les étapes des tests d'intégration dans votre dépôt et effectuez un autre push pour exécuter le pipeline de déploiement une fois que tous les composants d'ImageLabeller sont déployés. Vous devez mettre à jour la ligne git clone pour que SystemTests devienne votre dépôt SystemTests.

Comprendre un fichier .gitlab-ci.yml

Cette étape exécute des tests unitaires qui font partie du dépôt SubmitImage.

unit-test-us-west-1:
  stage: unit-test-us-west-1
  environment: test-us-west-1
  image: golang:buster
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  script:
    - cd submitImage
    - go test ./opendevopslambda/...

Cette étape déploie SubmitImage AWS Lambda à l'aide d'AWS SAM. Notez la section before_script. Cette étape s'exécute avant la section script, et peut être utilisée pour installer des dépendances et configurer divers outils.

deploy-us-west-1:
  stage: deploy-us-west-1
  environment: test-us-west-1
  image: python:latest
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
    - wget https://golang.org/dl/go1.16.6.linux-amd64.tar.gz
    - rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.6.linux-amd64.tar.gz
    - export PATH=$PATH:/usr/local/go/bin
    - go version
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file submit-image-packaged.yaml --s3-bucket open-devops-code-us-west-1-$AWS_ACCOUNT_ID --region us-west-1
    - sam deploy --template-file submit-image-packaged.yaml --stack-name OpenDevOpsSubmitImage  --s3-bucket open-devops-code-us-west-1-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region us-west-1 --no-fail-on-empty-changeset

Cette étape télécharge et exécute les tests d'intégration dans le dépôt SystemTests. Vous devez mettre à jour la ligne git clone pour que SystemTests devienne votre dépôt SystemTests.

test-us-west-1:
  stage: test-us-west-1
  environment: test-us-west-1
  image: golang:buster
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
    - cd systemtests
    - go test -v ./... -aws_region=us-west-1

Le jeton de déploiement créé précédemment est indiqué dans la ligne git clone.

- git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git

Faire un push vers une branche de fonctionnalité

Exécutez l'instruction suivante depuis la ligne de commande pour pusher vos changements vers la branche IM-8 de votre dépôt SubmitImage. Incluez l'identifiant du ticket Jira dans les messages de commit et les noms des branches pour permettre à l'intégration Jira GitLab de suivre l'évolution de votre projet.

git add --all
git commit -m "IM-8 add .gitlab-ci.yml to SubmitImage"
git push -u origin IM-8

Cliquez sur CI/CD, puis sur Pipelines pour voir le pipeline s'exécuter.

Capture d'écran de pipeline exécuté dans GitLab

Créer une demande de merge

Créez une demande de merge à déployer dans vos environnements de production après le déploiement de GitLab dans vos environnements de test. Choisissez la branche IM-8.

Capture d'écran de demandes de merge dans GitLab

Cliquez sur CI/CD, puis sur Pipelines pour voir le pipeline de demandes de merge en cours d'exécution.

Capture d'écran d'une demande de merge en cours d'exécution dans GitLab

Mergez les changements apportés à la branche principale une fois le pipeline de demandes de merge terminé. Cliquez sur CI/CD, puis sur Pipelines pour voir le pipeline de production en cours d'exécution.

Capture d'écran d'un pipeline de production en cours d'exécution dans GitLab

Créer un dépôt pour InvokeLabeller AWS Lambda

Accédez à Jira et créez un ticket pour ajouter un dépôt InvokeLabeller AWS Lambda dans GitHub. Notez l'identifiant du ticket. Dans cet exemple : IM-10.

Capture d'écran du ticket Jira de création du dépôt « InvokeLabeller » dans GitLab

Dans GitLab, cliquez sur New project (Nouveau projet), puis sur Create blank project (Créer un projet vierge). Ajoutez un nom de projet (Project name) et choisissez le groupe approprié dans Project URL (URL du projet). Cliquez sur Create project (Créer un projet) pour continuer.

Capture d'écran de création d'un projet « InvokeLabeller » dans GitLab

Dans votre terminal, accédez à votre dépôt InvokeLabeller et exécutez les commandes suivantes pour pusher votre code vers GitLab.

git add --all
git commit -m "IM-10 add InvokeLabeller to gitlab"
git remote add origin git@gitlab.com:pmmquickstartguides/invokelabeller.git
git branch -m mainline
git push -u origin mainline

Vous devez ajouter des clés d'accès AWS, configurer des branches protégées et configurer des environnements de déploiement.

Ensuite, ajoutez les clés de déploiement de votre dépôt SystemTests pour permettre le téléchargement du pipeline InvokeLabeller GitLab, et lancez SystemTests.

Enfin, ajoutez votre identifiant de compte AWS en tant que variable de CI/CD.

Capture d'écran de la page des variables dans GitLab

Fichier .gitlab-ci.yml pour le déploiement sur AWS

Accédez au dépôt InvokeLabeller de votre terminal, créez une branche portant l'identifiant de votre ticket Jira.

git checkout -b IM-10

Créez un fichier .gitlab-ci.yml avec le code yaml suivant. Cela définit un workflow de déploiement pour vos environnements de test, de staging et de production. Vous devez mettre à jour la ligne git clone pour que SystemTests devienne votre dépôt SystemTests.

stages:
  - merge-request
  - run-unit-tests
#US-WEST-1
  - deploy-us-west-1
  - test-us-west-1
#US-EAST-2
  - deploy-us-east-2
  - test-us-east-2
#US-WEST-2
  - deploy-us-west-2
  - test-us-west-2
#US-EAST-1
  - deploy-us-east-1
  - test-us-east-1
#CA-CENTRAL-1
  - deploy-ca-central-1
  - test-ca-central-1

merge-request-pipeline-job:
  stage: merge-request
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - echo "This pipeline always succeeds and enables merge"
    - echo true

run-unit-tests:
  stage: run-unit-tests
  image: python:3.8-buster
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install pytest
    - pip3 install moto
    - pip3 install -r tst/requirements.txt --user
  script:
    - python3 -m pytest -v tst/unit --junitxml=test-reports/report.xml

#US-WEST-1
deploy-us-west-1:
  stage: deploy-us-west-1
  environment: test-us-west-1
  image: python:3.8-buster
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file invoke-labeller-packaged.yaml --s3-bucket open-devops-code-us-west-1-$AWS_ACCOUNT_ID --region us-west-1
    - sam deploy --template-file invoke-labeller-packaged.yaml --stack-name OpenDevOpsInvokeLabeller  --s3-bucket open-devops-code-us-west-1-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region us-west-1 --no-fail-on-empty-changeset

      #test-us-west-1:
      #  stage: test-us-west-1
      #  environment: test-us-west-1
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=us-west-1

#US-EAST-2
deploy-us-east-2:
  stage: deploy-us-east-2
  environment: test-us-east-2
  image: python:3.8-buster
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file invoke-labeller-packaged.yaml --s3-bucket open-devops-code-us-east-2-$AWS_ACCOUNT_ID --region us-east-2
    - sam deploy --template-file invoke-labeller-packaged.yaml --stack-name OpenDevOpsInvokeLabeller  --s3-bucket open-devops-code-us-east-2-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region us-east-2 --no-fail-on-empty-changeset

      #test-us-east-2:
      #  stage: test-us-east-2
      #  environment: test-us-east-2
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=us-east-2

#US-WEST-2
deploy-us-west-2:
  stage: deploy-us-west-2
  environment: production-us-west-2
  image: python:3.8-buster
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file invoke-labeller-packaged.yaml --s3-bucket open-devops-code-us-west-2-$AWS_ACCOUNT_ID --region us-west-2
    - sam deploy --template-file invoke-labeller-packaged.yaml --stack-name OpenDevOpsInvokeLabeller  --s3-bucket open-devops-code-us-west-2-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region us-west-2 --no-fail-on-empty-changeset

      #test-us-west-2:
      #  stage: test-us-west-2
      #  environment: production-us-west-2
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=us-west-2

#US-EAST-1
deploy-us-east-1:
  stage: deploy-us-east-1
  environment: production-us-east-1
  image: python:3.8-buster
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file invoke-labeller-packaged.yaml --s3-bucket open-devops-code-us-east-1-$AWS_ACCOUNT_ID --region us-east-1
    - sam deploy --template-file invoke-labeller-packaged.yaml --stack-name OpenDevOpsInvokeLabeller  --s3-bucket open-devops-code-us-east-1-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region us-east-1 --no-fail-on-empty-changeset

      #test-us-east-1:
      #  stage: test-us-east-1
      #  environment: production-us-east-1
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=us-east-1

#CA-CENTRAL-1
deploy-central-1:
  stage: deploy-ca-central-1
  environment: production-ca-central-1
  image: python:3.8-buster
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
  before_script:
    - pip3 install awscli --upgrade
    - pip3 install aws-sam-cli --upgrade
  script:
    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
    - sam build
    - sam package --output-template-file invoke-labeller-packaged.yaml --s3-bucket open-devops-code-ca-central-1-$AWS_ACCOUNT_ID --region ca-central-1
    - sam deploy --template-file invoke-labeller-packaged.yaml --stack-name OpenDevOpsInvokeLabeller  --s3-bucket open-devops-code-ca-central-1-$AWS_ACCOUNT_ID --capabilities CAPABILITY_IAM --region ca-central-1 --no-fail-on-empty-changeset

      #test-central-1:
      #  stage: test-ca-central-1
      #  environment: production-ca-central-1
      #  image: golang:buster
      #  rules:
      #    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "merge_request_event"
      #  script:
      #    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
      #    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
      #    - git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
      #    - cd systemtests
      #    - go test -v ./... -aws_region=ca-central-1

L'exécution des tests d'intégration est commentée pour l'instant. Les tests système ne seront réussis que lorsque l'application complète sera déployée. Supprimez les commentaires pour les étapes des tests d'intégration dans votre dépôt et effectuez un autre push pour exécuter le pipeline de déploiement une fois que tous les composants d'ImageLabeller sont déployés. Vous devez mettre à jour la ligne git clone pour que SystemTests devienne votre dépôt SystemTests.

Mettre à jour src/application.py avec le point de terminaison AWS SageMaker

Ouvrez le fichier src/application.py d'InvokeLabeller et recherchez query_endpoint. Changez le nom du point de terminaison (endpoint_name) et le nom de la région (region_name) du client pour qu'ils correspondent à votre bloc-notes AWS SageMaker.

def query_endpoint(img):
  endpoint_name = 'jumpstart-dft-image-labeller-endpoint'
  client = boto3.client(service_name='runtime.sagemaker', region_name='us-west-1')
  response = client.invoke_endpoint(EndpointName=endpoint_name, ContentType='application/x-image', Body=img)
  model_predictions = json.loads(response['Body'].read())['predictions'][0]
  return model_predictions

Faire un push vers une branche de fonctionnalité

Exécutez l'instruction suivante depuis la ligne de commande pour pusher vos changements vers la branche IM-10 de votre dépôt InvokeLabeller. Incluez l'identifiant du ticket Jira dans les messages de commit et les noms des branches pour permettre à l'intégration Jira GitLab de suivre l'évolution de votre projet.

git add --all
git commit -m "IM-10 add .gitlab-ci.yml to InvokeLabeller"
git push -u origin IM-10

Cliquez sur CI/CD, puis sur Pipelines pour voir le pipeline s'exécuter.

Capture d'écran de pipeline en cours d'exécution dans GitLab

Créer une demande de merge

Créez une demande de merge à déployer dans vos environnements de production après le déploiement de GitLab dans vos environnements de test. Choisissez la branche IM-10.

Capture d'écran montrant la création d'une demande de merge dans GitLab

Mergez les changements apportés à la branche principale une fois le pipeline de demandes de merge terminé. Cliquez sur CI/CD, puis sur Pipelines pour voir le pipeline de production en cours d'exécution.

Capture d'écran d'un pipeline de production en cours d'exécution dans GitLab

Si vous êtes arrivé jusqu'ici, félicitations ! Vous venez de déployer ImageLabeller. L'étape suivante consiste à configurer la surveillance d'ImageLabeller avec Opsgenie.

Warren Marusiak
Warren Marusiak

Warren is a Canadian developer from Vancouver, BC with over 10 years of experience. He came to Atlassian from AWS in January of 2021.


Partager cet article

Lectures recommandées

Ajoutez ces ressources à vos favoris pour en savoir plus sur les types d'équipes DevOps, ou pour les mises à jour continues de DevOps chez Atlassian.

Illustration DevOps

Communauté DevOps

Illustration DevOps

Parcours de formation DevOps

Illustration d'une carte

Essayez la solution gratuitement

Inscrivez-vous à notre newsletter DevOps

Thank you for signing up