Articles
Tutorials
Interactive Guides
Deploy ImageLabeller with GitLab
![Warren Marusiak headshot](https://wac-cdn.atlassian.com/dam/jcr:7509aefb-43e8-401d-90fe-0850cbe6bb13/wmarusiak_headshot%20(1).png?cdnVersion=2557)
Warren Marusiak
Senior Technical Evangelist
To demonstrate how to develop, deploy, and manage applications using Jira Software and various connected tools, our team created ImageLabeller, a simple demo application built on AWS that uses machine learning to apply labels to images.
This page covers how to deploy ImageLabeller with GitLab. Before you begin, we recommend reading the ImageLabeller architecture and AWS SageMaker setup pages for context.
Prerequisites
If you don’t already have a GitLab group, follow the steps in this GitLab guide to create one from scratch.
Public facing GitHub repositories with ImageLabeller code
Jira GitLab integration demo video
Integrate Jira and GitLab
From Jira click Board, then Apps, then GitLab.
![Screenshot of dropdown menu in Jira Software to navigate to GitLab](https://wac-cdn.atlassian.com/dam/jcr:233af7c0-b3a2-46fd-ad94-facbc7611a9f/screenshot_jsw_appsdropdownmenugitlab.png?cdnVersion=2557)
Click Get it now.
![GitLab app modal in Jira Software](https://wac-cdn.atlassian.com/dam/jcr:e1c978e6-347f-44e1-bfc1-a36237028ea1/screenshot_jsw_gitlabapp.png?cdnVersion=2557)
Click Apps, then Manage your apps.
![Gitlab app modal in Jira software with dropdown menu](https://wac-cdn.atlassian.com/dam/jcr:5ac45ad7-f8cc-4ee9-ab8e-cbfb6c967709/screenshot_jsw_appsdropdownmenumanage.png?cdnVersion=2557)
Expand GitLab for Jira.
![Expand Gitlab when on the Manage Apps screen in Jira Software](https://wac-cdn.atlassian.com/dam/jcr:3cf62621-d30a-4736-be56-ceaf0096a422/screenshot_jsw_manageappsgitlab.png?cdnVersion=2557)
Click Add namespace.
![Screen to add a namespace to your Gitlab Jira software configuration](https://wac-cdn.atlassian.com/dam/jcr:69aad4ef-ff26-422d-8953-23e4d21b79d1/screenshot_jsw_gitlabconfiguration.png?cdnVersion=2557)
Select your existing namespace, and click Link. This guide assumes you already have an existing GitLab account, and GitLab group.
![Linking a Gitlab namespace in Jira Software](https://wac-cdn.atlassian.com/dam/jcr:24dff71f-6c9e-45a7-8da9-1dce709e8e11/screenshot_jsw_manageappslinknamespace.png?cdnVersion=2557)
Add SSH Key to GitLab
Click on your profile icon in the top right corner, and click preferences.
![Navigating to preferences using dropdown menu in Gitlab](https://wac-cdn.atlassian.com/dam/jcr:dbccc133-4c4c-422c-8009-f7d0f6c30053/screenshot_jsw_sshkeygitlab.png?cdnVersion=2557)
Click SSH Keys and follow the instructions to generate a new SSH key or use an existing SSH key.
Create a repository for AWS S3 infrastructure
A standard developer loop typically has a developer picking up a task from Jira, moving it to work in progress, and then doing the development work. The Jira issue ID is the key which ties the development work to the Jira issue. It is the core integration component between the two systems.
Go to Jira, and create a new issue for adding an AWS S3 infrastructure repository to GitLab. Make note of the issue ID. IM-5 in this example.
![Creating a new issue for your board in Jira software](https://wac-cdn.atlassian.com/dam/jcr:6e6bf187-8e99-4a02-814d-9eaa13d22ce6/screenshot_jsw_createissues3infragitlab.png?cdnVersion=2557)
Go to GitLab and click New project.
![Navigating to create "New project" in GitLab](https://wac-cdn.atlassian.com/dam/jcr:2d21e5c9-67ce-48df-b183-6d8dda26ea2b/screenshot_gitlab_newproject.png?cdnVersion=2557)
Click Create blank project.
![Creating a new project in GitLab](https://wac-cdn.atlassian.com/dam/jcr:a6eccbb5-024c-43cd-bcc3-a26896d473f8/screenshot_gitlab_createnewproject.png?cdnVersion=2557)
Add a Project name, and choose the appropriate group in Project URL. Click Create project to proceed.
![Creating a new project - detailed screen in Gitlab](https://wac-cdn.atlassian.com/dam/jcr:9d941c88-2136-4235-b063-61a63dea9296/screenshot_gitlab_createnewprojectdetails.png?cdnVersion=2557)
In your terminal go to your s3_infra repository, and run the following to push your AWS CloudFormation template.yml file to 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
Add AWS access key
Click Settings, then CI/CD. Scroll down, and expand Variables. Click Add variable.
![CI/CD settings page in GitLab](https://wac-cdn.atlassian.com/dam/jcr:1e0cd540-9715-4fd9-ae2f-3aa8d478f882/screenshot_gitlab_awskeys.png?cdnVersion=2557)
Create two variables. One for your AWS access key ID, and one for your AWS secret access key.
!["Add variable" modal to add your AWS keys in GitLab](https://wac-cdn.atlassian.com/dam/jcr:d71599c4-5ee0-4d45-bf49-225c0a5dbb39/screenshot_gitlab_addvariables.png?cdnVersion=2557)
Protect the variables so they are only used by pipelines running on protected branches, and tags. Give the IAM user associated with the AWS access key AdministratorAccess. You can also opt to use more fine grained access control by choosing individual AWS access policies.
![AWS keys listed under "Variables" section in the CI/CD settings page in GitLab](https://wac-cdn.atlassian.com/dam/jcr:91899e7a-10f8-4ece-9c15-6545236b3ffa/screenshot_gitlab_moreaccesscontrols.png?cdnVersion=2557)
Configure protected branches for access to protected variables
Click Settings, then Repository. Scroll down, and expand Protected branches.
Enter your Jira issue ID prefix and a *.
The Jira issue IDs are like IM-5, and IM-6 in this example; The prefix is IM-.
Enter IM-*, and click Protect.
![Configuring protected branches in GitLab](https://wac-cdn.atlassian.com/dam/jcr:81267f5a-f6a1-42a1-8997-9b662b33e44c/screenshot_gitlab_congfigureprotectedbranches.png?cdnVersion=2557)
You will see mainline, and IM-* as protected branches.
Setup deployment environments
Click Deployments, then Environments. Click New environment to add new environments. There are Test environments in US-WEST-1, and US-EAST-2, and Production environments in US-WEST-2, US-EAST-1, and CA-CENTRAL-1 in this example.
![Setting up deployment environments in GitLab](https://wac-cdn.atlassian.com/dam/jcr:abdad29f-4810-45c3-97b9-4a4e7cc33686/screenshot_gitlab_deploymentenvironments.png?cdnVersion=2557)
.gitlab-ci.yml for deploying to AWS
Go to your s3_infra repository in your terminal, and create a branch named after your Jira issue ID.
git checkout -b IM-5
Create a .gitlab-ci.yml file with the following yaml. This defines a deployment workflow for your Test, Staging, and Production environments.
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
Understanding a .gitlab-ci.yml file
Stages
Add a stages block to define the execution order of your GitLab pipeline. Stages are executed in the order they are defined in the stages block. Jobs associated with a stage are executed in parallel.
stages:
- merge-request
- test-us-west-1
- test-us-east-2
- production-us-west-2
- production-us-east-1
- production-ca-central-1
Jobs
Jobs are associated with a stage, and can be associated with an environment. Rules control whether, or not a particular job will execute. The rule in this example checks if the pipeline branch is not the default branch, and if the pipeline is not being run automatically as part of a merge request.
You can specify a different image for each job. You can setup images with tools necessary for your job scripts. The script section defines the set of steps that run when the job is executed.
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
Merge request pipeline
A pipeline is run automatically by GitLab when a merge request is approved. You can create a job for this pipeline by adding a rule. The job always succeeds in this example.
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
Pushing to a feature branch
Run the following from the command line to push your changes to the IM-5 branch of your s3_infra repository. Include the Jira issue ID in commit messages, and branch names to enable the Jira GitLab integration to keep track of what is happening in your project.
git add --all
git commit -m "IM-5 add .gitlab-ci.yml to s3_infra"
git push -u origin IM-5
Click CI/CD, then Pipelines to see the pipeline run.
![CI/CD pipelines screen in GitLab](https://wac-cdn.atlassian.com/dam/jcr:82e3a1fc-6a33-4dc7-88e5-5a1d7650ce26/screenshot_gitlab_runningworkflows.png?cdnVersion=2557)
Click the pipeline ID of the running pipeline.
![Pipeline ID for the running pipeline in GitLab](https://wac-cdn.atlassian.com/dam/jcr:444f2984-262a-4386-8009-d7a248fb5d8e/screenshot_gitlab_pipelineID1.png?cdnVersion=2557)
Click on a job to see more details.
![Detailed job screen for running pipeline in GitLab](https://wac-cdn.atlassian.com/dam/jcr:2c69708d-2d3b-443b-887a-57b20b6c2119/screenshot_gitlab_job.png?cdnVersion=2557)
Create a merge request
To create a merge request click Merge requests, then Create merge request.
![Merge requests screen in GitLab](https://wac-cdn.atlassian.com/dam/jcr:a6ea4df4-88e6-4d41-bd61-99f17f241520/screenshot_gitlab_mergerequest.png?cdnVersion=2557)
Choose your feature branch as the source branch then, click Compare branches and continue.
![Comparing source branch and target branch in GitLab](https://wac-cdn.atlassian.com/dam/jcr:f3567b59-ee5e-42b3-87b3-f47b494383c5/screenshot_gitlab_newmergerequest.png?cdnVersion=2557)
Choose an Assignee, and a Reviewer.
![Choosing a reviewer for your merge request in GitLab](https://wac-cdn.atlassian.com/dam/jcr:668196dc-188e-4e9b-a24b-0f751a2b296e/screenshot_gitlab_choosereviewer.png?cdnVersion=2557)
Click Create merge request.
![Selecting "Create merge request" button in GitLab](https://wac-cdn.atlassian.com/dam/jcr:0f7c8d33-0df5-4843-b32f-297a9bc955c9/screenshot_gitlab_createmergerequest.png?cdnVersion=2557)
Review the code changes, then click Approve.
![Merge request detailed screen where you can review changes in GitLab](https://wac-cdn.atlassian.com/dam/jcr:7afdc633-e428-4bb5-ac06-4b1daa5cdf98/screenshot_gitlab_reviewmerge.png?cdnVersion=2557)
Click CI/CI, then click Pipelines to see the merge request pipeline run.
![Navigating to the "pipelines" screen in Gitlab to see run merge requests](https://wac-cdn.atlassian.com/dam/jcr:b75761e8-0f3e-48b4-8826-0e92ee7bebe3/screenshot_gitlab_pipelines.png?cdnVersion=2557)
Click the pipeline ID. Notice that the merge-request-pipeline-job is the only job that ran.
!["Pipeline" detailed page showing that only merge-request-pipeline-job ran in GitLab](https://wac-cdn.atlassian.com/dam/jcr:0d4ba1f1-4192-435e-9eed-033f13fe94a2/screenshot_gitlab_pipelineran.png?cdnVersion=2557)
Go back to the merge request by clicking Merge requests, then clicking the active merge request, and click Merge. This kicks off another pipeline.
![Merging the active merge request in GitLab](https://wac-cdn.atlassian.com/dam/jcr:2e2aa09f-fd1f-4af5-bb7f-4ff24db04934/screenshot_gitlab_mergerequests.png?cdnVersion=2557)
Click CI/CD, then click Pipelines. Click the pipeline ID.
![Pipeline detailed page in GitLab displaying "Merge branch 'IM-5' into 'mainline'"](https://wac-cdn.atlassian.com/dam/jcr:0ae790e4-8cd3-48ea-86e2-d2f71b26a6a9/screenshot_gitlab_pipelineID2.png?cdnVersion=2557)
Create a repository for SystemTests
Go to Jira and create a Jira issue for adding a SystemTests repository to GitLab. Take note of the Jira issue ID. In this example it is IM-7.
![Create an issue in Jira Software to "add GitLab repo for SubmitImage AWS Lambda"](https://wac-cdn.atlassian.com/dam/jcr:8b8cd7a2-3a69-4d5d-87a9-5ed5b42767fc/screenshot_jsw_createissueaddgitlabreposystemtest.png?cdnVersion=2557)
Add a Project name, and choose the appropriate group in Project URL. Click Create project to proceed.
![Filling in project details when creating a new project in GitLab](https://wac-cdn.atlassian.com/dam/jcr:d0ce901f-13d5-4f3d-b2a3-67fe9867c92e/screenshot_gitlab_createnewprojectsubmitiamge.png?cdnVersion=2557)
In your terminal go to your SystemTests repository, and run the following to push your code to 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
The SystemTests repository doesn’t need a .gitlab-ci.yml file. It has no pipeline of its own since it provides tests for other pipelines to run. Take note of your SystemTests' remote url. SubmitImage, GetImageLabel, and InvokeLabeller CI/CD pipelines will clone the SystemTests repository during testing steps. You will need to update the gitlab-ci.yml of later repositories with the correct url.
Add a Deploy token
You need to add a deploy token to clone this repository during the execution of other pipelines. Click Settings, then Repository. Scroll down, and expand Deploy tokens.
![Entering in an example name 'cloneMe' under "Deploy tokens" in GitLab](https://wac-cdn.atlassian.com/dam/jcr:9d40815a-f855-4f4f-ac01-81619b6740a5/screenshot_gitlab_deploytoken.png?cdnVersion=2557)
Enter a name, check read_repository, and click Create deploy token.
![Selecting the "read_repository" checkbox on the "Deploy tokens" settings page in GitLab](https://wac-cdn.atlassian.com/dam/jcr:968e49e7-2165-4903-8da9-220d3cb2ef08/screenshot_gitlab_createdeploytokenmodal.png?cdnVersion=2557)
The deploy token username is auto-generated. The deploy token password is provided once at creation. Add it to a secret management tool so it can be referenced later. Later in this guide the deploy token username is referenced as gitlab_deploy_token, and the deploy token password is referenced as gitlab_deploy_password.
![Deploy tokens screen in Gitlab, displaying Deploy Token username and password](https://wac-cdn.atlassian.com/dam/jcr:ee87828c-8430-46d6-a576-b581aff8d6a8/screenshot_GitLabDeployTokenCreation.png?cdnVersion=2557)
Create a repository for SubmitImage AWS Lambda
Go to Jira, and create a new issue for adding a SubmitImage AWS Lambda repository to GitLab. Make note of the issue ID. IM-8 in this example.
![Imagelabeller board in Jira software - highlighting issue "IM-8 add GitLab repo for SubmitImage AWS Lambda"](https://wac-cdn.atlassian.com/dam/jcr:63278d8a-9f7f-47af-9b14-c9e2fa24b874/screenshot_jsw_issueaddissuecreatereposubmitimage.png?cdnVersion=2557)
Go to GitLab and click New project, then Create blank project. Add a Project name, and choose the appropriate group in Project URL. Click Create project to proceed.
![screenshot of creating new project "submitimage" in gitlab](https://wac-cdn.atlassian.com/dam/jcr:d0ce901f-13d5-4f3d-b2a3-67fe9867c92e/screenshot_gitlab_createnewprojectsubmitiamge.png?cdnVersion=2557)
In your terminal go to your SubmitImage repository, and run the following to push your code to 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
You must add AWS access keys, configure protected branches, and setup deployment environments.
Then add the deploy keys from your SystemTests repository to enable the SubmitImage GitLab pipeline to download, and run the SystemTests.
Finally, add your AWS account ID as a CI/CD Variable.
![screenshot of variables screen in gitlab](https://wac-cdn.atlassian.com/dam/jcr:e7d826c0-bc7f-4bf8-9849-ac456fe5a3af/screenshot_gitlab_variables.png?cdnVersion=2557)
.gitlab-ci.yml for deploying to AWS
Go to your SubmitImage repository in your terminal, and create a branch named after your Jira issue ID.
git checkout -b IM-8
Create a .gitlab-ci.yml file with the following yaml. This defines a deployment workflow for your Test, Staging, and Production environments. You must update the git clone line for SystemTests to be your SystemTests repository.
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
The execution of the integration tests is commented out for now. The system tests will only pass when the entire application is deployed. Uncomment the integration test steps in your repository, and do another push to run the deployment pipeline after all components of ImageLabeller are deployed. You must update the git clone line for SystemTests to be your SystemTests repository.
Understanding a .gitlab-ci.yml file
This step executes unit tests that are a part of the SubmitImage repository.
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/...
This step deploys the SubmitImage AWS Lambda using AWS SAM. Notice the before_script section. This step runs before the script section, and can be used to install dependencies, and setup various tools.
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
This step downloads, and runs the integration tests in the SystemTests repository. You must update the git clone line for SystemTests to be your SystemTests repository.
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
The deploy token created earlier is referenced in the git clone line.
- git clone https://${gitlab_deploy_token}:${gitlab_deploy_password}@gitlab.com/pmmquickstartguides/systemtests.git
Pushing to a feature branch
Run the following from the command line to push your changes to the IM-8 branch of your SubmitImage repository. Include the Jira issue ID in commit messages, and branch names to enable the Jira GitLab integration to keep track of what is happening in your project.
git add --all
git commit -m "IM-8 add .gitlab-ci.yml to SubmitImage"
git push -u origin IM-8
Click CI/CD, then Pipelines to see the pipeline run.
![screenshot of pipeline run in gitlab](https://wac-cdn.atlassian.com/dam/jcr:9bef95c2-61b6-4b89-8aaa-3683083605dc/screenshot_gitlab_pipelinerun.png?cdnVersion=2557)
Create a merge request
Create a merge request to deploy to your production environments after GitLab deploys to your test environments. Choose the IM-8 branch.
![screenshot of merge requests in gitlab](https://wac-cdn.atlassian.com/dam/jcr:e6915a7c-00f3-4ee4-b1af-df7d936033a5/screenshot_gitlab_mergerequestssubmitimage.png?cdnVersion=2557)
Click CI/CD, then Pipelines to see the running merge request pipeline.
![screenshot of running merge request oin gitlab](https://wac-cdn.atlassian.com/dam/jcr:edec3e6b-830e-4fe8-af86-f67178bd83ba/screenshot_gitlab_runningmergerequest.png?cdnVersion=2557)
Merge the changes to mainline after the merge request pipeline completes. Click CI/CD, then Pipelines to see the running Production pipeline.
![screenshot of running production pipeline in gitlab](https://wac-cdn.atlassian.com/dam/jcr:29153944-0768-448a-8cdb-6c9e8f2989b1/screenshot_gitlab_runningproductionpipeline.png?cdnVersion=2557)
Create a repository for InvokeLabeller AWS Lambda
Go to Jira, and create a new issue for adding a InvokeLabeller AWS Lambda repository to GitLab. Make note of the issue ID. IM-10 in this example.
![screenshot of jira issue create repo "invokelabeller" in gitlab](https://wac-cdn.atlassian.com/dam/jcr:2917371c-fe94-4059-add8-2ca8d5739908/screenshot_jsw_createissuerepoinvokelabellergitlab.png?cdnVersion=2557)
Go to GitLab and click New project, then Create blank project. Add a Project name, and choose the appropriate group in Project URL. Click Create project to proceed.
![screenshot of creating new project "invokelabeller" in gitlab](https://wac-cdn.atlassian.com/dam/jcr:f8c18f79-7ac0-4c55-81f2-b877981bdeba/screenshot_gitlab_createprojectinvokelabeller.png?cdnVersion=2557)
In your terminal go to your InvokeLabeller repository, and run the following to push your code to 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
You must add AWS access keys, configure protected branches, and setup deployment environments.
Then add the deploy keys from your SystemTests repository to enable the InvokeLabeller GitLab pipeline to download, and run the SystemTests.
Finally, add your AWS account ID as a CI/CD Variable.
![screenshot of variables page in gitlab](https://wac-cdn.atlassian.com/dam/jcr:e958bb2f-019a-417e-88b6-a9fa33c082be/screenshot_gitlab_variables2.png?cdnVersion=2557)
.gitlab-ci.yml for deploying to AWS
Go to your InvokeLabeller repository in your terminal, and create a branch named after your Jira issue ID.
git checkout -b IM-10
Create a .gitlab-ci.yml file with the following yaml. This defines a deployment workflow for your Test, Staging, and Production environments. You must update the git clone line for SystemTests to be your SystemTests repository.
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
The execution of the integration tests is commented out for now. The system tests will only pass when the entire application is deployed. Uncomment the integration test steps in your repository, and do another push to run the deployment pipeline after all components of ImageLabeller are deployed. You must update the git clone line for SystemTests to be your SystemTests repository.
Update src/app.py with AWS SageMaker endpoint
Open InvokeLabeller’s src/app.py file and look for query_endpoint. Change the endpoint_name, and client region_name to match your AWS SageMaker notebook.
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
Pushing to a feature branch
Run the following from the command line to push your changes to the IM-10 branch of your InvokeLabeller repository. Include the Jira issue ID in commit messages, and branch names to enable the Jira GitLab integration to keep track of what is happening in your project.
git add --all
git commit -m "IM-10 add .gitlab-ci.yml to InvokeLabeller"
git push -u origin IM-10
Click CI/CD, then Pipelines to see the pipeline run.
![screenshot of pipeline running in gitlab](https://wac-cdn.atlassian.com/dam/jcr:06f6da58-4877-422c-a2cc-22873f81ae59/screenshot_gitlab_pipelinerunninginvokelabeller.png?cdnVersion=2557)
Create a merge request
Create a merge request to deploy to your production environments after GitLab deploys to your test environments. Choose the IM-10 branch.
![screenshot of creating merge request in gitlab](https://wac-cdn.atlassian.com/dam/jcr:46a6d6b8-6086-4ce3-81e6-4f2e84ea90db/screenshot_gitlab_createmergerequestinvokelabeller.png?cdnVersion=2557)
Merge the changes to mainline after the merge request pipeline completes. Click CI/CD, then Pipelines to see the running Production pipeline.
![screenshot of running production pipeline in gitlab](https://wac-cdn.atlassian.com/dam/jcr:221f4820-b1f9-455b-bf5c-b64dba9b64f5/screenshot_gitlab_runningproductionpipelineinvokelabeller.png?cdnVersion=2557)
If you’ve made this far, congratulations! You just deployed ImageLabeller. The next step is to set up monitoring ImageLabeller with Opsgenie.
Share this article
Next Topic
Recommended reading
Bookmark these resources to learn about types of DevOps teams, or for ongoing updates about DevOps at Atlassian.
![Devops illustration](https://wac-cdn.atlassian.com/dam/jcr:bd9d8b2c-ca36-444f-8595-719cb1990e64/Devops-community.png?cdnVersion=2557)
DevOps community
![Devops illustration](https://wac-cdn.atlassian.com/dam/jcr:297108ea-d232-4368-af51-b53af230c4fe/Simulation-workshop.png?cdnVersion=2557)
DevOps learning path
![Map illustration](https://wac-cdn.atlassian.com/dam/jcr:25f6330a-4191-408f-a4e5-2e24bfba67b4/Maturity-model.png?cdnVersion=2557)