JenkinsとJFrog Pipelines: CI/CDの連携によるソフトウェアのリリース
ソフトウェア開発者はリリースを継続して行うと同時に技術を先に進める必要があります。Jenkinsの継続的インテグレーション(CI)パイプラインをより新しい最適化されたシステムに移行することは、それほど難しいことではありません。また皆様の企業で現在の作業を完全に中断し、システムを丸ごと入れ替えるような余裕はないでしょう。
私たちはCI/CDソリューションであるJFrog Pipelinesを構築した時に、このことを深く理解していました。そのため、現在のJenkinsパイプラインとJFrog Pipelinesパイプラインを容易に接続できるようにしました。
多くの組織と同様に皆様も多くのJenkinsパイプラインを構築するために何百時間もの開発者の時間を費やしてきたかも知れません。これらのJenkinsパイプラインはCIの基本的な部分を継続して実行することができますが、JFrog Pipelinesの新しいワークフローに引き渡すことができます。
ここではJenkinsとJFrog Pipelinesの連携を可能にするための方法を見てみましょう。
Pipelinesとプラットフォームの違い
Pipelinesは「ワンストップDevOps」のためのソリューションを提供するJFrog DevOps PlatformのエンドツーエンドのCI/CDコンポーネントです。ArtifactoryをベースとしたJFrogプラットフォームはアーティファクトリポジトリ、バイナリの配布、セキュリティスキャン、CI/CD自動化から組織のソフトウェアデリバリーを管理するために必要なすべてを提供します。
皆様のJenkinsパイプラインは、すでにGo、Docker、HelmなどのアーティファクトとビルドをArtifactoryリポジトリにプッシュしている可能性も十分にあるでしょう。これはArtifactoryのユニバーサルリポジトリ管理が、様々なDevOpsツールとの接続を可能にしているからです。そのおかげでArtifactoryはバイナリリポジトリ管理の業界標準として受け入れられるようになりました。
JFrog Pipelinesは、JFrog DevOps Platformのすべてのツールを統合する自動化ツールです。Jenkinsと同様に、コードからビルド、バイナリ、そして配布に至るまでの各段階でソフトウェアを移動させることができます。しかし、JFrog Platformの一部として、Artifactory、Xray、およびDistributionと自然に統合されており、統一したパーミッションモデルで管理することができ、きめ細かなアクセス制御が可能です。
Pipelinesはエンタープライズ規模で運用も可能であり、すべての管理者とチームに単一のプラットフォームを提供し、何百ものCI/CDパイプラインをサポートすることができます。
これらの理由から、CIをJenkinsからPipelinesに移行することをお勧めしますが、一度に移行するのは現実的ではないかもしれません。
JenkinsからPipelinesへ
この例では、Jenkinsがビルド、ユニットテストを実行し、ステージングDockerリポジトリにプッシュするGo RESTアプリケーションを構築しました。次に、JFrog PipelinesがDocker GoアプリケーションをステージングリポジトリからKubernetesクラスタにデプロイします。ここではGoogle Kubernetes Engine(GKE)を使用します。さらに、Dockerレジストリとして Artifactoryを使用します。これにより、同じビルドを別のリリースレジストリにプッシュすることなく、簡単にリリースへのプロモーションを行うことができます。
この例のコードリポジトリには、Go REST アプリケーション、Jenkins パイプライン Jenkinsfile、および JFrog Pipelines YAML ファイルが含まれています。ベストプラクティスでは、パイプラインのインフラストラクチャもこれらのファイルで定義されています。
Jenkins パイプライン
Jenkinsパイプラインは、アプリケーションの初期ビルドとテストを実行し、Dockerコンテナをビルド情報とともにリポジトリにプッシュします。
それでは、Jenkinsのパイプラインを見てみましょう。以下のJenkinsfileの重要なセクションは、Publish Build Infoとpostステージです。JenkinsがGoアプリケーションイメージをビルドしてテストした後、ビルド情報をArtifactoryに公開します。
stages {
stage('Build') {
steps {
container('golang'){
sh 'go build'
}
}
}
stage('Unit Tests') {
steps {
container('golang'){
sh 'go test ./... -run Unit'
}
}
}
stage('Docker Build') {
steps {
container('docker'){
sh "docker build -t partnership-public-images.jfrog.io/goci-example:latest ."
}
}
}
stage('Docker Push to Repo') {
steps {
container('docker'){
script {
docker.withRegistry( 'https://partnership-public-images.jfrog.io', 'gociexamplerepo' ) {
sh "docker push partnership-public-images.jfrog.io/goci-example:latest"
}
}
}
}
}
stage('Publish Build Info') {
environment {
JFROG_CLI_OFFER_CONFIG = false
}
steps {
container('jfrog-cli-go'){
withCredentials([usernamePassword(credentialsId: 'gociexamplerepo', passwordVariable: 'APIKEY', usernameVariable: 'USER')]) {
sh "jfrog rt bce $JOB_NAME $BUILD_NUMBER"
sh "jfrog rt bag $JOB_NAME $BUILD_NUMBER"
sh "jfrog rt bad $JOB_NAME $BUILD_NUMBER \"go.*\""
sh "jfrog rt bp --build-url=https://jenkins.openshiftk8s.com/ --url=https://partnership.jfrog.io/artifactory --user=$USER --apikey=$APIKEY $JOB_NAME $BUILD_NUMBER"
}
}
}
}
}
次にpostステージでは、Pipelines REST APIのwebhookでビルド情報を送り、JFrog Pipelinesをトリガーします。次に、このWebhookがJFrog Pipelinesでどのように設定されているかについて説明します。
post {
success {
script {
sh "curl -XPOST -H \"Authorization: Basic amVmabcdefM25rMW5z=\" \"https://partnership-pipelines-api.jfrog.io/v1/projectIntegrations/17/hook\" -d '{\"buildName\":\"$JOB_NAME\",\"buildNumber\":\"$BUILD_NUMBER\",\"buildInfoResourceName\":\"jenkinsBuildInfo\"}' -H \"Content-Type: application/json\""
}
}
}
JenkinsとJFrog Pipelinesを接続するには、まずPipelinesデプロイメントでJenkins インテグレーションを作成する必要があります(ここではjenkins_openshiftk8s_comと呼びます)。このUIは上記のcurl webhookコマンドを提供し、JenkinsパイプラインがJFrog Pipelinesをトリガーできるようにします。
JFrog Pipelines
JFrog Pipelinesは、Jenkinsパイプラインによってプッシュされたビルド情報を介してトリガーされ、残りのデプロイメントとステージングアクションを実行してリリースします。
JFrog Pipelinesは、パイプラインのステップをYAMLで定義します。このファイルの最初のセクションはリソースです。これらはパイプラインで使用されるデータのソースとデスティネーションです。この例では、GitHubリポジトリ、jenkins_openshiftk8s_com Jenkinsインテグレーションに接続されたBuildInfoリソース、リリースを促進するための最終的なBuildInfoリソースを定義しています。BuildInfoリソースはビルドのメタデータを保存するために使用します。
resources:
- name: gociexampleGithubRepo
type: GitRepo
configuration:
gitProvider: myGithub
path: myaccount/goci-example
- name: jenkinsBuildInfo
type: BuildInfo
configuration:
sourceArtifactory: MyArtifactory
buildName: goci-example/master
buildNumber: 1
externalCI: jenkins_openshiftk8s_com
- name: releaseBuildInfo
type: BuildInfo
configuration:
sourceArtifactory: MyArtifactory
buildName: goci-example/master
buildNumber: 1
最初のステップは、jenkinsBuildInfoを通してJenkinsのトリガーを受け取るBashステップです。
- name: start_from_jenkins
type: Bash
configuration:
inputResources:
- name: jenkinsBuildInfo
execution:
onExecute:
- echo 'Jenkins job triggered Pipelines'
すべてがうまくいったら、Go RESTアプリケーションをステージング環境にデプロイします。ここではGKE クラスタを使用します。このクラスタは、gociexampleClusterCreds という名前のKubernetes インテグレーションを通して参照します。kubeconfigデータをIntegrationオブジェクトとして提供することで、任意のKubernetesクラスタと統合することができます。
HelmDeployステップを使用して、リポジトリのHelmChartディレクトリを使用してアプリケーションをデプロイします。
- name: deploy_staging
type: HelmDeploy
configuration:
inputSteps:
- name: start_from_jenkins
inputResources:
- name: gociexampleGithubRepo
trigger: false
integrations:
- name: gociexampleClusterCreds
releaseName: goci-example
chartPath: chart/goci-example/
次に、Go RESTアプリケーションが利用可能になるのを待つBashステップがあります。
- name: wait_for_server
type: Bash
configuration:
inputSteps:
- name: deploy_staging
execution:
onExecute:
- timeout 60 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' https://goci-example.35.238.177.209.xip.io)" != "200" ]]; do sleep 5; done' || true
Go REST アプリケーションがステージング環境で起動したら、ステージングテストを実行します。
- name: staging_test
type: Bash
configuration:
inputSteps:
- name: wait_for_server
inputResources:
- name: gociexampleGithubRepo
trigger: false
runtime:
type: image
image:
auto:
language: go
versions:
- "1.13"
environmentVariables:
STAGING_URL: "https://goci-example.35.238.177.209.xip.io"
execution:
onExecute:
- cd ../dependencyState/resources/gociexampleGithubRepo
- go mod download
- go test ./test -run Staging
最後に、ステージングテストをパスした場合は、ビルドをリリースに向けてプロモーションします。
- name: promote_release
type: PromoteBuild
configuration:
targetRepository: partnership-public-images.jfrog.io
status: Released
comment: Passed staging tests.
inputResources:
- name: jenkinsBuildInfo
outputResources:
- name: releaseBuildInfo
JFrog Pipelinesをさらに拡張して、エンドシステムやJFrog Edgeシステムにソフトウェアを公開するために、JFrog Distributionを使用して継続的デリバリー(CD)を実現することができます。ただし、これについては今後のブログ記事に譲ることにします。
DevOpsへの道を続ける
ご覧のように、JenkinsパイプラインをJFrog Pipelinesに接続するのは簡単なプロセスです。必要に応じて、JFrog PipelinesからJenkinsパイプラインをトリガーすることもできます。
ツールのパッチワークからソフトウェアデリバリーツールチェーンを開発するのは、時間がかかり、イライラすることがあります。JFrog Platformのような統一されたツールチェーンを使用することで、ツールではなくソフトウェアに集中することができます。しかし、既存のツールがある場合は、それらを簡単にJFrogプラットフォームに接続して、その機能を活用することができます。