Close

Het integreren van Concourse-CI en Atlassian Open DevOps

Veel teams gebruiken hun eigen tools om in hun behoeften te voorzien of hebben verouderde tools die ze al jaren gebruiken. Deze tools zijn essentieel voor het ontwikkelingsproces dat een team volgt, maar ze zijn niet direct geïntegreerd met Jira. Gelukkig is het eenvoudig om een aangepaste integratie te genereren met behulp van de REST-API's van Atlassian die te vinden zijn in de documentatie voor Cloudontwikkelaars: - Atlassian Developer . Concourse-CI is een CI/CD-product dat op het moment dat dit artikel werd geschreven geen integratie had in de Atlassian Marketplace. Dit artikel laat zien hoe je een basisintegratie kunt genereren tussen Jira en Concourse-CI met behulp van de REST-API's van Atlassian.

Vereisten

Gebruik de noodzakelijke documentatie om Docker, docker-compose en Concourse-CI in te stellen. Concourse-CI draait op Docker en biedt een docker-compose script om het gemakkelijker te maken om aan de slag te gaan.

Lees hier meer over de ImageLabeller-demotoepassing van Atlassian. Dit artikel laat zien hoe je Concourse-CI kunt gebruiken om het SubmitImage-component van ImageLabeller in AWS te implementeren.

Docker

Stel Docker en docker-compose in door de bijbehorende documentatie te volgen:

Docker: https://docs.docker.com/get-docker/
docker-compose: https://docs.docker.com/compose/install/

Concourse-CI

Zodra Docker en docker-compose zijn geïnstalleerd, kun je Concourse-CI starten met het bijgeleverde docker-compose.yml-bestand.

Volg de snelstartgids van Concourse-CI om aan de slag te gaan met https://concourse-ci.org/quick-start.html#docker-compose-concourse. Deze handleiding vereist dat inloggegevens op een veilige manier worden overgebracht aan Concourse-CI. De handleiding maakt hiervoor gebruik van de AWS Secrets Manager-integratie met Concourse-CI.

Integratie van Concourse-CI met AWS Secrets Manager

Hier is de documentatie over hoe je Concourse-CI kunt integreren met AWS Secrets Manager. Volg de instructies in de documentatie om de integratie mogelijk te maken en aan de slag te gaan.

Het docker-compose.yml-bestand dat wordt gebruikt om Concourse-CI te starten, moet enigszins worden aangepast om de integratie te laten werken. Neem het standaard docker-compose.yml-bestand dat door Concourse-CI is aangeleverd en voeg
CONCOURSE_AWS_SECRETSMANAGER_ACCESS_KEY, CONCOURSE_AWS_SECRETSMANAGER_SECRET_KEY en 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>

Zodra de integratie is ingesteld, Concourse-CI actief is en de integratie is ingeschakeld, voeg dan de volgende geheimen toe aan 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

De geheimen van Bitbucket en Docker moeten mogelijk worden vervangen als de lezer Bitbucket niet gebruikt voor zijn code, en JFrog niet als Docker-repository. Dit aanpassen aan het individuele toolgebruik van de lezer blijft over als een oefening.

geheimen van bitbucket en docker

Werken met Concourse-CI

Voer docker ps -a eerst uit en nadat je docker-compose up -d hebt uitgevoerd om te controleren of Concourse-CI correct is gestart.

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

Ga naar http://localhost:8080/ na het uitvoeren van de fly -t tutorial login -c http://localhost:8080 -u test -p tes

fly -t tutorial login -c http://localhost:8080 -u test -p test
logging in to team 'main'
target saved

Er zijn op dit moment geen gedefinieerde pipelines.

Een 'hello world'-pipeline

Stel een 'hello world'-pijplijn in door deze Concourse-CI-documentatie te volgen: https://concourse-ci.org/tutorial-hello-world.html. Dit is nodig om de Fly-cli te introduceren en om te wennen aan het werken met Concourse-CI van de opdrachtregel.

Het volgende deel laat zien hoe je een in Golang geschreven AWS Lambda kunt implementeren in één AWS-regio met Concourse-CI en hoe je een update kunt schrijven over een Jira-issue als onderdeel van het proces.

Implementeer SubmitImage met Concourse-CI

Er zijn drie stappen om de SubmitImage Lambda in te implementeren met Concourse-CI. De eerste stap is het schrijven van een eenvoudig bash-script dat de Jira Cloud REST-API gebruikt om een opmerking te schrijven in een Jira-issue. Dit is de eenvoudigste integratie die we kunnen creëren. De tweede stap is het maken van een Docker-afbeelding met de noodzakelijke tools om een Golang AWS Lambda te genereren en te implementeren. De laatste stap is het schrijven van een tweetal Concourse-CI-configuratiebestanden. Het eerste configuratiebestand, parent.yml, controleert de SubmitImage-repository voor nieuwe branches en zorgt voor nieuwe pipelines om commits van die branches te implementeren. Het tweede configuratiebestand, child.yml, definieert de noodzakelijke stappen om een wijziging te implementeren.

Stap 1 - Jira issues bijwerken via REST-API

Dit updatescript gebruikt de REST API van het Jira Cloud-platform om een opmerking te schrijven over een specifieke Jira-issue. Er zijn vijf vereiste parameters die telkens weer moeten worden ingesteld wanneer het script wordt uitgevoerd. De Jira-gebruikersnaam, Jira-Apitoken, en de workspace zijn doorgaans hetzelfde voor elke run van een bepaalde pipeline. De issuesleutel zal afhankelijk zijn van de branchnaam van de specifieke branch die wordt geïmplementeerd. Het is een aanbevolen werkwijze voor Jira om de Jira issue-ID in de branchnamen te verwerken en berichten vast te leggen wanneer er aan een bepaald issue wordt gewerkt. In dit artikel wordt ervan uitgegaan dat de aanbevolen werkwijzen worden gevolgd en dat de namen van branch gelijk zijn aan de Jira issue-ID.

Hoe vind je de parameters
Jira-gebruikersnaam


De gebruikersnaam van Jira is het e-mailadres dat wordt gebruikt om in te loggen op Jira.

Jira API-token
Ga naar Accountinstellingen

Accountinstellingen voor JIRA API-tokens

Klik op Beveiliging

accountbeveiliging

Klik op API-tokens aanmaken en beheren

Workspace

Met een URL van een Jira-installatie, zoals https://pmmquickstartguides01.atlassian.net/jira/software/projects/IM/boards/1?selectedIssue=IM-203, de workspace is pmmquickstartguide01.

Issuesleutel

Met een URL van een Jira-issue zoals https://pmmquickstartguides01.atlassian.net/jira/software/projects/IM/boards/1?selectedIssue=IM-203 is de Jira-issuesleutel IM-203. Zet de Jira issue-ID in commit-berichten en branchnamen zodat de integratie de updates naar de juiste locatie kan schrijven.

Opmerking

De opmerking kan van alles zijn.

Het updatescript

Het updatescript is een eenvoudig bash-shellscript dat gebruik maakt van het eindpunt van de REST-API van Jira issue-opmerking. Hier is de documentatie voor deze API-call. Het script kan worden aangepast voor een diepere integratie door het bijgeleverde patroon te volgen om extra API-calls uit te voeren. Kopieer dit script naar een bestand met de naam concourse-ci-integration.sh en plaats het in een Bitbucket- of GitHub-repo met de naam 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 "$@"

Stap 2 - Dockerbestand op maat

Maak een aangepast Dockerbestand met de tools die nodig zijn om in Golang geschreven AWS Lambda te genereren en te implementeren. Het Dockerbestand installeert enkele hulpprogramma's en voegt daar AWS, SAM en Golang aan toe. De afbeelding kloont het updatescript met Git clone dat in stap 1 is gemaakt vanuit een Bitbucket-repository. Je moet deze Bitbucket-repository vervangen door de repository die je hebt gemaakt om het updatescript op te slaan. Docker build dit Dockerbestand en voer een push uit naar een Docker-repository.

Dockerfile

# 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

Stap 3 - YAML-bestanden voor Concourse-CI-implementatie en -pipeline

Maak een nieuwe repository, genaamd concourse, en plaats er twee bestanden in. Parent.yml creëert een pipeline die een repository controleert voor nieuwe branches die overeenkomen met een regex. De branch_regex is GB-* en dat komt overeen met alle branches, beginnend met GB-. Parent.yml zal een nieuwe pipeline aanmaken met behulp van de configuratie in child.yml wanneer een nieuwe branch wordt aangemaakt die overeenkomt met regex GB-*. Je moet dit bestand updaten zodat het verwijst naar je eigen versie van de SubmitImage-repo. De code voor de SubmitImage vind je hier. Kopieer de code van deze repository naar een repository met schrijfrechten.

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 definieert een pipeline in vier stappen. Allereerst wordt op dezelfde manier gevalideerd om te controleren of het bestand AWS CloudFormation template.yml geldig is. Vervolgens wordt Sam-build uitgevoerd om het pakket SubmitImage om te genereren tot een inzetbaar artefact. Ten derde wordt Sam-implementeren uitgevoerd om de bijgewerkte SubmitImage-code naar AWS te implementeren. Tot slot wordt in de pipeline het updatescript dat werd geschreven in stap 1 aangeroepen om een commentaar te schrijven op het overeenkomstige Jira-issue.

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"]

Hoe start je de bovenliggende pipeline

Voer de volgende drie opdrachten uit vanuit de map met parent.yml. De eerste opdracht logt in op de Concourse-CI-installatie die lokaal wordt uitgevoerd. De tweede opdracht maakt een pipeline aan genaamd wm op basis van de configuratie in parent.yml. De derde opdracht zet de wm-pipeline op niet-gepauzeerd.

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

Ga naar de webclient van Concourse-CI nadat je deze drie opdrachten hebt uitgevoerd om te zien of de wm-pipeline actief is.

concourse ci webclient afbeelding

Nadat de fly set-pipeline met parent.html is uitgevoerd, is er een wm-pipeline. Deze pipeline monitort SubmitImage voor alle nieuwe functie-branches en maakt een pipeline aan voor elke functie-branch die overeenkomt met de regex in parent.yml.

fly set-pipeline

Klik op de wm-pipeline om te zien welke stappen worden uitgevoerd. Merk op dat in de stap functies-branches er een GB-61-branch wordt vermeld. Dit is momenteel de enige branch in SubmitImage die overeenkomt met regex in parent.yml. Klik op de ontwikkelingspipeline die automatisch is opgestart om te zien welke stappen worden uitgevoerd.

wm-pipeline fly set-pipeline

Let op dat er een stap is om de SubmitImage-repo te verkrijgen en dat de branch GB-61 is. Let ook op dat er run-sam-validate, run-sam-build, run-sam-deploy en run-update-script stappen zijn.

GB 61, Jira issue-omschrijving

Nadat de ontwikkelingspipeline klaar is, ga dan terug naar de GB-61 Jira-issue en hier zul je zien dat er een minuut geleden een nieuwe opmerking is geregistreerd die overeenkomt met de opmerkingenreeks van child.yml

Conclusie...

Deze handleiding laat zien hoe je een pipeline in kunt stellen om automatisch een Golang AWS Lambda te implementeren naar één enkele AWS-regio met behulp van Concourse-CI. Deze handleiding laat ook zien hoe je een bash-shellscript kunt gebruiken om een eenvoudige integratie met Jira te schrijven. Het integratiescript kan enorm worden uitgebreid door dieper in de Atlassian REST-API-documentatie te duiken die hier beschikbaar is.

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.

Deel dit artikel

Aanbevolen artikelen

Bookmark deze resources voor meer informatie over soorten DevOps-teams of voor voortdurende updates over DevOps bij Atlassian.

Toelichting DevOps

DevOps-community

Toelichting DevOps

DevOps-leertraject

Afbeelding van kaart

Gratis aan de slag

Meld je aan voor onze DevOps-nieuwsbrief

Thank you for signing up