デプロイの安全性

デプロイジョブはCI/CDジョブの一種です。パイプラインの他のジョブよりもデリケートで、特別な注意が必要な場合があります。GitLabには、デプロイのセキュリティと安定性を維持するためのいくつかの機能があります。

以下のようなことができます:

継続的デプロイのワークフローを使用していて、同じ環境への同時デプロイが起こらないようにしたい場合は、以下のオプションを有効にする必要があります:

概要については、CDパイプライン/ワークフローのセキュリティを確保する方法を参照してください。

クリティカルな環境への書き込みアクセスの制限

デフォルトでは、少なくとも開発者ロールを持つチームメンバーであれば、環境を変更できます。クリティカルな環境 (たとえば、production 環境) への書き込みアクセスを制限したい場合、保護された環境を設定できます。

一度に1つのデプロイジョブのみが実行されるようにします。

GitLab CI/CD のパイプラインジョブは並行して実行されるため、2つの異なるパイプラインの2つのデプロイジョブが同時に同じ環境にデプロイしようとする可能性があります。デプロイは順番に行われるべきなので、これは望ましい動作ではありません。

.gitlab-ci.ymlresource_group キーワード で、一度に1つのデプロイジョブしか実行されないようにすることができます。

使用例:

deploy:
 script: deploy-to-prod
 resource_group: prod

リソースグループを使用する前の、問題のあるパイプラインフローの例:

  1. deploy パイプラインAのジョブが実行開始。
  2. deploy パイプラインBのジョブが実行を開始します。これは予期しない結果を引き起こす可能性のある同時デプロイです。
  3. deploy パイプラインAのジョブが終了しました。
  4. deploy パイプラインBのジョブが終了しました。

リソースグループを使用した後の改善されたパイプラインフロー:

  1. deploy パイプラインAのジョブが実行開始。
  2. deploy パイプラインBのジョブが開始しようとしますが、最初のdeploy ジョブの終了を待ちます。
  3. deploy パイプラインAのジョブが終了します。
  4. deploy パイプラインBのジョブが実行を開始します。

詳細はリソースグループのドキュメントを参照してください。

古いデプロイジョブの防止

パイプラインジョブの効果的な実行順序は実行ごとに異なることがあり、望ましくない動作を引き起こす可能性があります。例えば、新しいパイプラインのデプロイジョブが古いパイプラインのデプロイジョブより先に終了する可能性があります。これにより、古いデプロイが後で終了し、「新しい」デプロイメントが上書 きされるという競合状態が発生します。

古い配置ジョブを防止]機能を有効にすると、新しい配置ジョブが開始されたときに古い 配置ジョブが実行されないようにできます。

古いデプロイ ジョブが開始されると、そのジョブは失敗し、ラベルが付けられます:

  • failed outdated deployment job と表示されます。
  • The deployment job is older than the latest deployment, and therefore failed. 完了したジョブを表示するとき。

古いデプロイ ジョブが手動である場合、再生ボタンは無効となり、This deployment job does not run automatically and must be started manually, but it's older than the latest deployment, and therefore can't run. というメッセージが表示されます。

ジョブの年齢はコミット時間ではなくジョブの開始時間によって決定されるため、状況によっては新しいコミットを防ぐことができます。

ロールバックデプロイのためのジョブの再試行

  • GitLab 15.6で導入されたジョブの再試行によるロールバック。
  • GitLab 16.3 で導入されたロールバックデプロイのジョブ再試行チェックボックス。

安定した古いデプロイに素早くロールバックする必要があるかもしれません。デフォルトでは、デプロイのロールバックのためのパイプラインジョブリトライは有効になっています。

パイプラインの再試行を無効にするには、[ロールバック デプロイメントのジョ ブの再試行を許可]チェックボックスをオフにします。機密性の高いプロジェクトでは、パイプラインの再試行を無効にする必要があります。

ロールバックが必要な場合は、以前のコミットで新しいパイプラインを実行する必要があります。

物件例

時代遅れのデプロイジョブを防止]を有効にする前の、問題のあるパイプラインフローの例です:

  1. パイプラインAはデフォルトブランチに作成されます。
  2. その後、パイプライン B が (より新しいコミット SHA で) デフォルトブランチに作成されます。
  3. パイプライン B のdeploy ジョブが先に終了し、新しいコードがデプロイされます。
  4. パイプラインAのdeploy のジョブは後で終了し、古いコードをデプロイし、新しい(最新の)デプロイを上書きします。

古いデプロイジョブを有効にした後の改善されたパイプラインの流れ:

  1. パイプラインAはデフォルトブランチに作成されます。
  2. その後、パイプライン B が (より新しい SHA で) デフォルトブランチに作成されます。
  3. パイプライン B のdeploy ジョブが先に終了し、新しいコードがデプロイされます。
  4. パイプラインAのdeploy ジョブは、新しいパイプラインからのデプロイを上書きしないように、失敗します。

デプロイフリーズウィンドウ中のデプロイを防止します。

ほとんどの従業員が外出する計画的な休暇期間など、特定の期間にデプロイを実 行しないようにするには、[デプロイフリーズ]を設定します。デプロイ フリーズ期間中は、デプロイを実行できません。これは、デプロイが予期せず実行されないようにするために役立ちます。

次に設定されたデプロイ フリーズは、環境デプロイ一覧ページの上部に表示されます。

プロダクションシークレットの保護

デプロイを成功させるには、プロダクション・シークレットが必要です。例えば、クラウドにデプロイする場合、クラウドプロバイダーはサービスに接続するためにこれらのシークレットを必要とします。プロジェクト設定では、これらのシークレットに対してCI/CD変数を定義し、保護することができます。保護された変数は保護されたブランチまたは保護されたタグで実行されているパイプラインにのみ渡されます。他のパイプラインは保護された変数を取得しません。変数を特定の環境にスコープすることもできます。シークレットが意図せずに公開されないように、保護された環境上で保護された変数を使用することをお勧めします。ランナー側でプロダクションシークレットを定義することもできます。これにより、メンテナーのロールを持つ他のユーザーがシークレットを読むことができなくなり、ランナーが保護されたブランチでのみ実行されるようになります。

詳細はパイプラインセキュリティを参照してください。

デプロイ用の別プロジェクト

プロジェクトのメンテナー ロールを持つすべてのユーザーは、本番環境のシークレットにアクセスできます。本番環境にデプロイできるユーザー数を制限する必要がある場合は、別のプロジェクトを作成し、CD 権限を元のプロジェクトから分離し、プロジェクトのメンテナー ロールを持つ元のユーザーが本番用シークレットと CD 設定にアクセスできないようにする新しい権限モデルを設定できます。マルチプロジェクトパイプラインを使用して、CDプロジェクトを開発プロジェクトに接続できます。

.gitlab-ci.yml を変更から保護します。

.gitlab-ci.yml には、アプリケーションを本番サーバーにデプロイするルールが含まれていることがあります。このデプロイは通常、マージリクエストをプッシュした後に自動的に実行されます。開発者が を変更できないようにするには、.gitlab-ci.yml別のリポジトリで定義 .gitlab-ci.ymlします。.gitlab-ci.ymlこの設定は、まったく異なる権限を持つ別のプロジェクトのファイルを参照することができます(デプロイ用にプロジェクトを分離するのと同様です)。 .gitlab-ci.ymlこの.gitlab-ci.ymlシナリオでは、ファイルは .gitlab-ci.yml公開されますが、他のプロジェクトの適切な権限を持つユーザーだけが編集できます。

詳細については、カスタムCI/CD設定パスを参照してください。

デプロイ前に承認者が必要

デプロイを本番環境に昇格させる前に、専用のテスト グループでデプロイをクロス ベリファイすることは、安全性を確保するための効果的な方法です。詳細については、「デプロイの承認者」を参照してください。