Articoli
Tutorial
Guide interattive
Integrazione di Concourse CI e Atlassian Open DevOps
Molti team utilizzano i propri strumenti per gestire le proprie esigenze o dispongono di strumenti legacy che usano da anni. Questi strumenti sono essenziali per il processo di sviluppo seguito da un team, ma non dispongono di integrazioni pronte all'uso con Jira. Fortunatamente, creare un'integrazione personalizzata utilizzando le API REST di Atlassian disponibili nella documentazione per sviluppatori Cloud - Atlassian Developer è semplicissimo. Concourse CI è un prodotto CI/CD che, al momento della stesura di questo articolo, non è integrato nell'Atlassian Marketplace. Questo articolo spiega come creare un'integrazione di base tra Jira e Concourse CI utilizzando le API REST di Atlassian.
Prerequisiti
Usa la documentazione necessaria per configurare Docker, docker-compose e Concourse CI. Concourse CI funziona su Docker e fornisce uno script docker-compose per semplificare le operazioni iniziali.
Scopri di più sull'applicazione demo ImageLabeller di Atlassian qui. Questo articolo spiega come utilizzare Concourse CI per distribuire il componente SubmitImage di ImageLabeller su AWS.
Docker
Configura Docker e docker-compose seguendo la documentazione associata:
Docker: https://docs.docker.com/get-docker/
docker-compose: https://docs.docker.com/compose/install/
Concourse CI
Una volta installati Docker e docker-compose, puoi avviare Concourse CI utilizzando il file docker-compose.yml fornito.
Segui la guida introduttiva di Concourse CI per iniziare a usare https://concourse-ci.org/quick-start.html#docker-compose-concourse. Questa guida richiede il passaggio sicuro delle credenziali a Concourse CI. La guida utilizza l'integrazione di Concourse CI con AWS Secrets Manager per questo scopo.
Integrazione di Concourse CI con AWS Secrets Manager
Qui puoi trovare la documentazione su come integrare Concourse CI con AWS Secrets Manager. Segui le istruzioni nella documentazione per abilitare l'integrazione e iniziare.
Il file docker-compose.yml utilizzato per avviare Concourse CI deve essere leggermente modificato affinché l'integrazione funzioni. Prendi il file docker-compose.yml predefinito fornito da Concourse CI e aggiungi
CONCOURSE_AWS_SECRETSMANAGER_ACCESS_KEY, CONCOURSE_AWS_SECRETSMANAGER_SECRET_KEY e CONCOURSE_AWS_SECRETSMANAGER_REGION.
version: '3'
services:
concourse-db:
image: postgres
environment:
POSTGRES_DB: concourse
POSTGRES_PASSWORD: concourse_pass
POSTGRES_USER: concourse_user
PGDATA: /database
concourse:
image: concourse/concourse
command: quickstart
privileged: true
depends_on: [concourse-db]
ports: ["8080:8080"]
environment:
CONCOURSE_POSTGRES_HOST: concourse-db
CONCOURSE_POSTGRES_USER: concourse_user
CONCOURSE_POSTGRES_PASSWORD: concourse_pass
CONCOURSE_POSTGRES_DATABASE: concourse
CONCOURSE_EXTERNAL_URL: http://localhost:8080
CONCOURSE_ADD_LOCAL_USER: test:test
CONCOURSE_MAIN_TEAM_LOCAL_USER: test
# instead of relying on the default "detect"
CONCOURSE_WORKER_BAGGAGECLAIM_DRIVER: overlay
CONCOURSE_CLIENT_SECRET: Y29uY291cnNlLXdlYgo=
CONCOURSE_TSA_CLIENT_SECRET: Y29uY291cnNlLXdvcmtlcgo=
CONCOURSE_X_FRAME_OPTIONS: allow
CONCOURSE_CONTENT_SECURITY_POLICY: "*"
CONCOURSE_CLUSTER_NAME: tutorial
CONCOURSE_WORKER_CONTAINERD_DNS_SERVER: "8.8.8.8"
CONCOURSE_WORKER_RUNTIME: "containerd"
CONCOURSE_ENABLE_ACROSS_STEP: "true"
CONCOURSE_ENABLE_PIPELINE_INSTANCES: "true"
CONCOURSE_AWS_SECRETSMANAGER_ACCESS_KEY: <add access key>
CONCOURSE_AWS_SECRETSMANAGER_SECRET_KEY: <add secret key>
CONCOURSE_AWS_SECRETSMANAGER_REGION: <add a region>
Una volta che l'integrazione è stata configurata e Concourse CI è in esecuzione con l'integrazione abilitata, aggiungi i seguenti segreti ad AWS Secrets Manager.
/concourse/main/bitbucket_username
/concourse/main/bitbucket_api_key
/concourse/main/bitbucket_ssh_key
/concourse/main/docker_username
/concourse/main/docker_api_key
/concourse/main/AWS_ACCESS_KEY_ID
/concourse/main/AWS_SECRET_ACCESS_KEY
/concourse/main/AWS_DEFAULT_REGION
Potrebbe essere necessario sostituire i segreti di Bitbucket e Docker se il lettore non utilizza Bitbucket per il codice e JFrog come repository Docker. Apportare modifiche per adattarlo agli strumenti individuali del lettore viene lasciato come esercizio.
Lavorare con Concourse CI
Esegui docker ps -a prima e dopo aver eseguito docker-compose up -d per vedere se Concourse CI è stato avviato correttamente.
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker-compose up -d
Creating network "restapiproject_default" with the default driver
Creating restapiproject_concourse-db_1 ... done
Creating restapiproject_concourse_1 ... done
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bd2b5afd0ac7 concourse/concourse "dumb-init /usr/loca…" 3 seconds ago Up 2 seconds 0.0.0.0:8080->8080/tcp restapiproject_concourse_1
bd9005b45636 postgres "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 5432/tcp restapiproject_concourse-db_1
Vai su http://localhost:8080/ dopo aver eseguito fly -t tutorial login -c http://localhost:8080 -u test -p test
fly -t tutorial login -c http://localhost:8080 -u test -p test
logging in to team 'main'
target saved
Al momento non sono state definite pipeline.
Una pipeline Hello World
Configura una pipeline Hello World seguendo questa documentazione di Concourse CI: https://concourse-ci.org/tutorial-hello-world.html. Questo è necessario per introdurre la CLI Fly e abituarsi a lavorare con Concourse CI dalla riga di comando.
La prossima sezione spiega come distribuire un AWS Lambda scritto in Golang in una singola regione AWS con Concourse CI e come scrivere un aggiornamento a un ticket Jira come parte del processo.
Distribuisci SubmitImage con Concourse CI
Ci sono tre passaggi per distribuire SubmitImage Lambda con Concourse CI. Il primo passaggio consiste nello scrivere un semplice script bash che utilizzi l'API REST di Jira Cloud per scrivere un commento in un ticket Jira. Questa è l'integrazione più semplice che possiamo creare. Il secondo passaggio consiste nel creare un'immagine Docker con gli strumenti necessari per creare e distribuire un AWS Lambda Golang. Il passaggio finale consiste nello scrivere due file di configurazione di Concourse CI. Il primo file di configurazione, parent.yml, monitora il repository SubmitImage alla ricerca di nuovi branch e avvia nuove pipeline per distribuire i commit da tali branch. Il secondo file di configurazione, child.yml, definisce l'insieme di passaggi necessari per distribuire una modifica.
Passaggio 1: aggiorna i ticket Jira tramite l'API REST
Questo script di aggiornamento utilizza l'API REST della piattaforma Jira Cloud per scrivere un commento a un ticket Jira specifico. Ci sono cinque parametri obbligatori che devono essere impostati ogni volta che viene eseguito lo script. I parametri jiraUsername, jiraApiToken e workspace in genere sono gli stessi per ogni esecuzione di una particolare pipeline. Il parametro issueKey dipenderà dal nome dello specifico branch che si sta distribuendo. È una best practice Jira inserire l'ID del ticket Jira nei nomi dei branch e i messaggi di commit quando si lavora su un particolare ticket. Questo articolo presuppone che venga seguita la best practice e che i nomi dei branch corrispondano all'ID del ticket Jira.
Come trovare i parametri
Nome utente Jira
Il nome utente Jira è l'indirizzo e-mail utilizzato per accedere a Jira.
Token API di Jira
Vai alle impostazioni dell'account
Clicca su Sicurezza
Clicca su Crea e gestisci i token API
Spazio di lavoro
Dato l'URL di un'istanza Jira come https://pmmquickstartguides01.atlassian.net/jira/software/projects/IM/boards/1?selectedIssue=IM-203, lo spazio di lavoro è pmmquickstartguide01.
Identificatore del ticket
Dato l'URL di un ticket Jira come https://pmmquickstartguides01.atlassian.net/jira/software/projects/IM/boards/1?selectedIssue=IM-203, l'identificatore ticket di Jira è IM-203. Inserisci l'ID del ticket Jira nei messaggi di commit e nei nomi dei branch in modo che l'integrazione possa scrivere gli aggiornamenti nella posizione corretta.
Commenta
Il commento può essere qualsiasi cosa.
Lo script di aggiornamento
Lo script di aggiornamento è un semplice script bash shell che utilizza l'endpoint dell'API REST per i commenti ai ticket Jira. Qui puoi trovare la documentazione per questa chiamata API. Lo script può essere modificato per fornire un'integrazione più profonda seguendo lo schema fornito per effettuare chiamate API aggiuntive. Copia questo script in un file chiamato concourse-ci-integration.sh e inseriscilo in un repository Bitbucket o GitHub chiamato updateScript.
#!/usr/bin/env bash
addCommentToIssue() {
printf "addCommentToIssue\n"
local jiraUsername=$1
shift
local jiraApiToken=$1
shift
local workspace=$1
shift
local issueKey=$1
shift
local comment=$1
shift
curl -s --request POST \
--url 'https://'"${workspace}"'.atlassian.net/rest/api/3/issue/'"${issueKey}"'/comment' \
--user "${jiraUsername}"':'"${jiraApiToken}" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"body": {
"type": "doc",
"version": 1,
"content": [{
"type": "paragraph",
"content": [{
"text": "'"${comment}"'",
"type": "text"
}]
}]
}
}' | jq
}
main() {
printf "main\n"
while getopts ":c:k:o:u:t:w:" opt; do
case $opt in
c)
local comment=$OPTARG
;;
k)
local issueKey=$OPTARG
;;
o)
local op=$OPTARG
;;
u)
local jiraUsername=$OPTARG
;;
t)
local jiraApiToken=$OPTARG
;;
w)
local workspace=$OPTARG
;;
*)
printf "invalid option: -${OPTARG}\n" >&2
exit 1
;;
esac
done
case $op in
ac)
addCommentToIssue ${jiraUsername} ${jiraApiToken} ${workspace} ${issueKey} "${comment}"
;;
*)
printf "invalid op: ${op}\n" >&2
exit 1
;;
esac
}
main "$@"
Passaggio 2: Dockerfile personalizzato
Crea un Dockerfile personalizzato con gli strumenti necessari per creare e distribuire un AWS Lambda scritto in Golang. Il Dockerfile installa alcune utilità, quindi aggiunge AWS SAM e Golang. L'immagine Git clona lo script di aggiornamento creato nel passaggio 1 da un repository Bitbucket. Devi sostituire questo repository Bitbucket con qualsiasi repository che hai creato per contenere lo script di aggiornamento. Docker crea questo Dockerfile e lo invia a un repository Docker.
Docker
# syntax = docker/dockerfile:1.3
FROM ubuntu:20.04
MAINTAINER wmarusiak@atlassian.com
WORKDIR /workspace
RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get -y install curl unzip tar openssh-client git jq
RUN curl https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip -L -o aws-sam-cli.zip \
&& mkdir sam-installation \
&& unzip aws-sam-cli.zip -d sam-installation \
&& ./sam-installation/install \
&& sam --version
RUN curl https://go.dev/dl/go1.18.2.linux-amd64.tar.gz -L -o go.tar.gz \
&& rm -rf /usr/local/go \
&& tar -C /usr/local -xzf go.tar.gz
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts
RUN --mount=type=ssh git clone git@bitbucket.org:pmmquickstartguides01/updatescript.git
ENV PATH $PATH:/usr/local/go/bin
Passaggio 3: file YAML della pipeline di distribuzione di Concourse CI
Crea un nuovo repository chiamato concourse e inseriscici due file. Parent.yml crea una pipeline che monitora un repository per i nuovi branch che corrispondono a un'espressione regolare. Il branch_regex è IM-*, che corrisponde a tutti i branch che iniziano con IM-. Parent.yml creerà una nuova pipeline utilizzando la configurazione in child.yml quando viene creato un nuovo branch che corrisponde all'espressione regolare IM-*. Dovresti aggiornare questo file in modo che rimandi alla tua versione del repository SubmitImage. Il codice SubmitImage può essere trovato qui. Copia il codice di questo repository in un repository con autorizzazioni di scrittura.
parent.yml
resource_types:
- name: git-branches
type: registry-image
source:
repository: aoldershaw/git-branches-resource
resources:
- name: feature-branches
type: git-branches
source:
uri: git@bitbucket.org:pmmquickstartguides01/submitimage.git
branch_regex: IM-*
private_key: ((bitbucket_ssh_key))
- name: examples
type: git
source:
uri: git@bitbucket.org:pmmquickstartguides01/concourse.git
private_key: ((bitbucket_ssh_key))
jobs:
- name: set-feature-pipelines
plan:
- in_parallel:
- get: feature-branches
trigger: true
- get: examples
- load_var: branches
file: feature-branches/branches.json
- across:
- var: branch
values: ((.:branches))
set_pipeline: dev
file: examples/child.yml
vars: {branch: ((.:branch.name))}
Child.yml definisce una pipeline con quattro passaggi. Innanzitutto, esegue sam validate per verificare che il file template.yml di AWS CloudFormation sia valido. Successivamente, esegue sam build per creare il pacchetto SubmitImage in un artefatto distribuibile. In terzo luogo, esegue sam deploy per distribuire il codice SubmitImage aggiornato su AWS. Infine, la pipeline richiama lo script di aggiornamento scritto nel passaggio 1 per scrivere un commento al ticket Jira corrispondente.
child.yml
resources:
- name: repo
type: git
source:
uri: git@bitbucket.org:pmmquickstartguides01/submitimage.git
branch: ((branch))
private_key: ((bitbucket_ssh_key))
jobs:
- name: deploy-submit-image
plan:
- get: repo
trigger: true
- task: run-sam-validate
config:
platform: linux
image_resource:
type: registry-image
source:
repository: docker.atl-paas.net/wmarusiak/ubuntuawssam
username: ((docker_username))
password: ((docker_api_key))
inputs: # add the get step as an input to this task
- name: repo
run:
path: sam
args: ["validate", "-t", "repo/template.yml"]
params:
AWS_ACCESS_KEY_ID: ((AWS_ACCESS_KEY_ID))
AWS_SECRET_ACCESS_KEY: ((AWS_SECRET_ACCESS_KEY))
AWS_DEFAULT_REGION: ((AWS_DEFAULT_REGION))
- task: run-sam-build
config:
platform: linux
image_resource:
type: registry-image
source:
repository: docker.atl-paas.net/wmarusiak/ubuntuawssam
username: ((docker_username))
password: ((docker_api_key))
inputs: # add the get step as an input to this task
- name: repo
run:
path: sam
args: ["build", "-t", "repo/template.yml"]
params:
AWS_ACCESS_KEY_ID: ((AWS_ACCESS_KEY_ID))
AWS_SECRET_ACCESS_KEY: ((AWS_SECRET_ACCESS_KEY))
AWS_DEFAULT_REGION: ((AWS_DEFAULT_REGION))
- task: run-sam-deploy
config:
platform: linux
image_resource:
type: registry-image
source:
repository: docker.atl-paas.net/wmarusiak/ubuntuawssam
username: ((docker_username))
password: ((docker_api_key))
inputs: # add the get step as an input to this task
- name: repo
run:
path: sam
args: ["deploy", "-t", "repo/template.yml", "--stack-name", "OpenDevOpsSubmitImage", "--s3-bucket", "open-devops-code-us-west-1-756685045356", "--capabilities", "CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"]
params:
AWS_ACCESS_KEY_ID: ((AWS_ACCESS_KEY_ID))
AWS_SECRET_ACCESS_KEY: ((AWS_SECRET_ACCESS_KEY))
AWS_DEFAULT_REGION: ((AWS_DEFAULT_REGION))
- task: run-update-script
config:
platform: linux
image_resource:
type: registry-image
source:
repository: docker.atl-paas.net/wmarusiak/ubuntuawssam
username: ((docker_username))
password: ((docker_api_key))
input:
-name: repo
run:
path: /workspace/updatescript/concourse-ci-integration.sh
args: ["-c", "successfully deployed submitImage via concourse-ci", "-k", "((branch))", "-o", "ac", "-u", "((bitbucket_username))", "-t", "((bitbucket_api_key))", "-w", "pmmquickstartguides01"]
Come avviare la pipeline principale
Esegui i seguenti tre comandi dalla directory con parent.yml. Il primo comando consente di accedere all'istanza Concourse CI in esecuzione localmente. Il secondo comando crea una pipeline chiamata wm in base alla configurazione in parent.yml. Il terzo comando riattiva la pipeline wm.
fly -t tutorial login -c http://localhost:8080 -u test -p test
fly -t tutorial set-pipeline -p wm -c parent.yml
fly -t tutorial unpause-pipeline -p wm
Vai al client web di Concourse CI dopo aver eseguito questi tre comandi per vedere se la pipeline wm è attiva e funzionante.
Dopo aver eseguito fly set-pipeline con parent.yml c'è una pipeline wm. Questa pipeline monitora SubmitImage per eventuali nuovi branch di funzioni e crea una pipeline per ogni branch di funzioni corrispondente all'espressione regolare in parent.yml.
Clicca sulla pipeline wm per vedere i passaggi eseguiti. Nota che il passaggio feature-branches presenta un branch IM-61. Questo è l'unico branch attualmente esistente in SubmitImage che corrisponde all'espressione regolare in parent.yml. Clicca sulla pipeline di sviluppo che è stata avviata automaticamente per vedere i passaggi che esegue.
Nota che c'è un passaggio per ottenere il repository SubmitImage e che il branch è IM-61. Nota anche che ci sono i passaggi run-sam-validate, run-sam-build, run-sam-deploy e run-update-script.
Al termine dell'esecuzione della pipeline di sviluppo, torna al ticket Jira IM-61 e nota che c'è un nuovo commento registrato un minuto fa che corrisponde alla stringa di commento di child.yml.
In conclusione...
Questa guida spiega come configurare una pipeline per distribuire automaticamente un AWS Lambda Golang in una singola regione AWS utilizzando Concourse CI. Questa guida spiega anche come usare uno script bash shell per scrivere una semplice integrazione con Jira. Lo script di integrazione può essere notevolmente ampliato approfondendo la documentazione dell'API REST di Atlassian disponibile qui.
Condividi l'articolo
Argomento successivo
Letture consigliate
Aggiungi ai preferiti queste risorse per ricevere informazioni sui tipi di team DevOps e aggiornamenti continui su DevOps in Atlassian.