CI/CDのための最初のJenkins宣言型パイプラインを構築する

最初のJenkins宣言型パイプラインを構築することで、自動化されたソフトウェアデリバリーの力を解き放ちましょう。この包括的なガイドは、ソースコード管理の統合から、安全なビルド、テスト、条件付きデプロイメントステージの定義に至るまで、CI/CDワークフロー全体を網羅したステップバイステップのチュートリアルを提供します。`Jenkinsfile`の基本的な構造を学び、エージェントやクレデンシャルの扱いに関するベストプラクティスを実装することで、プロジェクトの堅牢で保守可能な自動化を実現できます。

33 ビュー

最初のJenkins宣言的パイプラインをCI/CDのために構築する

Jenkinsは、オープンソースの自動化サーバーの事実上の標準であり、何千もの組織で継続的インテグレーションおよび継続的デリバリー(CI/CD)パイプラインのバックボーンとして機能しています。Jenkinsにはスクリプト化(Scripted)と宣言的(Declarative)の2種類のパイプライン構文がありますが、宣言的パイプライン構文は、よりシンプルで構造化され、読みやすいGroovy DSLであるため、ほとんどのユーザーにとって推奨されるアプローチです。

本ガイドでは、最初の機能的なJenkins宣言的パイプラインを構築するための包括的なステップバイステップチュートリアルを提供します。ソースコード管理(SCM)の統合、ビルド環境の定義、テストの実行、サンプルのデプロイメントステージの実装について説明し、ソフトウェアデリバリーライフサイクルを自動化するための強固な基盤を提供します。

宣言的パイプラインの構造を理解する

宣言的パイプラインは、アプリケーションコードと共にSCMリポジトリ(例:Git)内に保存されるJenkinsfileというファイル内でワークフロー全体を定義します。このプラクティスはPipeline as Codeとして知られています。

宣言的パイプラインのコア要素

宣言的パイプラインには、以下のトップレベルブロックが含まれている必要があります。

  1. pipeline: パイプラインの内容を定義する必須の最も外側のブロック。
  2. agent: パイプラインまたは特定のステージが実行される場所を指定します(例:anynone、または特定のラベル)。
  3. stages: 1つ以上の順次stageブロックを含みます。
  4. stage: 作業の概念的なブロック(例:ビルド、テスト、デプロイ)を定義します。
  5. steps: stage内で実行される1つ以上のコマンドまたは関数を含みます。
pipeline {
    agent any 
    environment { // オプション: 環境変数を定義
        APP_VERSION = '1.0.0'
    }
    stages {
        stage('Build') {
            steps {
                // コマンドをここに記述
            }
        }
    }
    post { // オプション: パイプライン完了後に実行されるアクション
        always { 
            echo 'Pipeline finished.' 
        }
    }
}

ステップ1: Jenkinsジョブの設定

コードからパイプラインを実行するには、リポジトリからJenkinsfileを読み取るようにJenkinsジョブを設定する必要があります。

  1. Jenkinsダッシュボードに移動し、新規ジョブを選択します。
  2. パイプラインの名前を入力します(例:my-first-ci-pipeline)。
  3. アイテムタイプとしてパイプラインを選択し、OKをクリックします。
  4. 設定ページで、パイプラインセクションまでスクロールします。
  5. 定義をパイプラインスクリプトからSCMからパイプラインスクリプトに変更します。
  6. SCM(例:Git)を選択します。
  7. リポジトリURLを入力し、必要に応じて認証情報を設定します。
  8. スクリプトパスJenkinsfile(デフォルト)に設定されていることを確認します。

ステップ2: CI/CDのためのJenkinsfileの定義

標準的なステージを統合し、正常なデプロイメントをシミュレートする包括的なJenkinsfileを作成します。

ルートにJenkinsfileとアプリケーションのソースコード(例:単純なPythonまたはJavaプロジェクト)を含むリポジトリ構造があると仮定します。

完全な宣言的パイプラインの例

このパイプラインはnodeエージェント(設定されている場合)を使用し、基本的なシェルステップ(sh)を使用して実際の作業をシミュレートします。デプロイメントステージは条件付きであり、前のステージが正常に完了した場合にのみ実行されます。

// Jenkinsfile
pipeline {
    // 1. エージェントの定義: パイプライン全体が実行される場所を指定
    agent { 
        label 'my-build-agent' // 利用可能な場合は特定のラベルを使用、または 'any'
    }

    // 2. 環境変数: パイプライン全体で使用可能な変数を定義
    environment {
        CONTAINER_REGISTRY = 'registry.example.com'
        IMAGE_NAME = 'myapp'
    }

    stages {

        // ステージ1: チェックアウト (ソースコード管理)
        stage('Checkout Source') {
            steps {
                // 'checkout scm' ステップは、Jenkinsジョブ設定で定義された設定に基づいてコードを自動的にチェックアウトします。
                checkout scm
                sh 'echo "Source code successfully checked out."
            }
        }

        // ステージ2: アーティファクトのビルド
        stage('Build Artifact') {
            steps {
                sh 'echo "Starting build for $IMAGE_NAME:$BUILD_ID"'
                // シミュレーション: Dockerイメージのビルドまたはjar/warファイルのコンパイル
                sh "docker build -t ${IMAGE_NAME}:${BUILD_ID} ."
            }
        }

        // ステージ3: テストと品質ゲート
        stage('Run Tests') {
            steps {
                sh './run_unit_tests.sh'
                sh 'echo "Running integration tests..."'
                // テスト結果の収集例(適切なプラグインが必要)
                // junit '**/target/surefire-reports/*.xml'
            }
        }

        // ステージ4: デプロイメント (条件付き)
        stage('Deploy to Staging') {
            // 'when' ディレクティブは、特定の条件下でのみステージが実行されることを保証します
            when {
                branch 'main'
            }
            steps {
                sh "docker push ${CONTAINER_REGISTRY}/${IMAGE_NAME}:${BUILD_ID}"
                sh 'kubectl apply -f k8s/deployment-staging.yaml'
                script {
                    // スクリプトブロックにより、宣言的ステップ内で従来のGroovyロジックが可能になります
                    echo "Deployment successful to Staging environment."
                }
            }
        }
    }

    // 3. 後処理アクション: 最終的なパイプラインのステータスに基づいてアクションを定義
    post {
        success {
            echo 'Pipeline completed successfully. Notifying team via Slack...'
            // slackSend channel: '#devops-alerts', message: 'CI/CD Success!'
        }
        failure {
            echo 'Pipeline failed. Review logs for errors.'
        }
        cleanup {
            sh 'docker rmi -f $(docker images -aq --filter label=build_id=$BUILD_ID)'
        }
    }
}

ステップ3: パイプラインの実行と監視

Jenkinsfileがコミットされ、Jenkinsジョブで設定されたブランチにプッシュされると:

  1. Jenkinsジョブページで、ビルド実行をクリックします(またはSCMポーリング/Webhookトリガーを待ちます)。
  2. ビルド履歴パネルでビルドを監視します。
  3. 実行中のビルド番号をクリックし、コンソール出力を選択して、実行の詳細をステップごとに表示します。
  4. また、ステージビュー(プラグインがインストールされている場合)を使用して、CheckoutBuildTestDeployステージの進行状況をグラフィカルに確認することもできます。

ベストプラクティスと高度な機能

ライブラリと共有コードの活用

複雑または繰り返しが多いステップの場合、Jenkinsfile内に冗長なGroovyを直接記述することは避けてください。代わりに共有ライブラリを使用します。これらの外部ライブラリにより、標準的なデプロイメントルーチンや通知機能などの共通関数を定義でき、複数のパイプラインから呼び出すことでJenkinsfileをよりクリーンに保つことができます。

// 共有ライブラリステップの呼び出し
stage('Custom Setup') {
    steps {
        customLibrary.initializeEnvironment(env: 'prod')
    }
}

認証情報の操作

機密情報(パスワード、トークン、APIキー)をJenkinsfileに直接ハードコードしないでください。Jenkinsの組み込み認証情報管理システムを使用します。

withCredentialsステップを使用すると、保存されているシークレットに安全にアクセスできます。

stage('Authenticate Registry') {
    steps {
        withCredentials([usernamePassword(credentialsId: 'docker-registry-creds', 
                                          passwordVariable: 'PASS', 
                                          usernameVariable: 'USER')]) {
            sh "docker login -u ${USER} -p ${PASS} ${CONTAINER_REGISTRY}"
        }
    }
}

警告: エージェントの選択

ヒント: agent anyではなく、常にlabelを使用してagentを具体的に定義してください。agent anyを使用すると、パイプラインがJenkinsコントローラーノードで実行される可能性があり、セキュリティリスクとなり、コントローラーのパフォーマンスに影響を与える可能性があります。Docker、Maven、Node.jsなどの必要なツールがインストールされたJenkinsエージェント(ノード)を適切に設定していることを確認してください。

結論

Jenkins宣言的パイプラインは、継続的インテグレーションと継続的デリバリーを実装するための、強力で読みやすく、保守しやすいフレームワークを提供します。エージェント、環境変数、順次ステージ、ビルド後のアクションを含むワークフロー構造を定義することにより、ソフトウェア自動化プロセスに対する完全な可視性と制御を得ることができます。この基本的なJenkinsfileを確立したことで、自動セキュリティスキャン、アーティファクトの公開、マルチ環境プロモーションなどのより複雑なステップを統合する準備が整いました。