デプロイメントの安全性

デプロイジョブはパイプラインの他のジョブよりも機密性が高く、特別な注意が必要な場合があります。 GitLabには、デプロイのセキュリティと安定性を維持するのに役立つ機能がいくつかあります。

できます:

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

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

デフォルトでは、環境は開発者権限以上のチームメンバーであれば誰でも変更できます。重要な環境 (たとえば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のジョブが実行されます。

詳細については、.gitlab-ci.yml](../yaml/README.md#resource_group)の[resource_group キーワードを参照してください。

古くなったデプロイメントジョブをスキップ

たとえば、新しいパイプラインのデプロイ ジョブが古いパイプラインのデプロイ ジョブより先に終了すると、古いデプロイが後で終了し、「新しい」デプロイ が上書きされるという競合状態が発生します。

古いデプロイ[ジョブをスキップ]](../pipelines/settings.md#skip-outdated-deployment-jobs)機能を有効にすると、新しいデプロイ ジョブが実行されたときに古いデプロイ ジョブが自動的にキャンセルされます。

Skipの古いデプロイジョブを有効にする前の、問題のあるパイプラインフローの例:

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

古いデプロイジョブをスキップできるようにしたことでパイプラインの流れが改善されました:

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

デプロイフリーズウィンドウ中のデプロイの防止

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

トラブルシューティング

パイプラインのジョブは、次のように失敗します。The deployment job is older than the previously succeeded deployment job...

これは、古いデプロイジョブをスキップする機能によって発生します。 同じ環境に対して複数のジョブ (デプロイジョブ以外も含む) がある場合などに、この問題が発生する可能性があります:

build:service-a:
  environment:
    name: production

build:service-b:
  environment:
    name: production

古いデプロイジョブをスキップ]は、この構成ではうまく機能しない可能性があるため、無効にする必要があります。

このイシューに対処するため、環境に関する新しいアノテーションを導入する計画があります。