保護された環境、安全なデプロイ方法、デプロイメントの承認
(トップページはこちら) - (アプリケーションのデプロイとリリースを始める)
「本番環境に誤ったコードがデプロイされた」「複数のデプロイが競合して障害が発生した」「承認なしに重要な変更が本番に反映された」。こうした問題は、デプロイメントプロセスの管理が不十分な組織で頻繁に発生します。
GitLabは、環境保護、デプロイメント承認、安全性制御の3つの機能を組み合わせることで、これらの課題を解決します。本記事では、段階的な導入方法と実践的な設定パターンを解説します。
1. デプロイメント管理の課題と解決策
1.1 よくある課題
課題1: 権限管理の不備
開発者全員が本番環境にデプロイできる状態では、意図しない変更や設定ミスのリスクが高まります。特に、新しいメンバーが誤って本番環境を操作してしまうケースが多発します。
課題2: 同時デプロイによる競合
複数のパイプラインが並行実行される環境では、2つのデプロイが同時に実行され、予期しない状態になることがあります。
課題3: 古いコードによる上書き
パイプラインの実行順序と完了順序が異なる場合、新しいデプロイの後に古いデプロイが完了し、最新のコードが上書きされてしまいます。
課題4: 承認プロセスの欠如
本番環境への変更に対して、セキュリティチームや運用チームのレビューが必要な場合でも、自動的にデプロイが実行されてしまいます。
1.2 GitLabの解決アプローチ
2. 環境保護による権限管理
環境保護(Protected Environments)は、デプロイ権限を細かく制御する基盤となる機能です。
2.1 基本的な設定
設定手順
- Settings > CI/CD > Protected environments を開く
- Protect an environment を選択
- 環境を選択(例:
production) - Allowed to deploy でデプロイ権限を設定
- Protect をクリック
設定可能な権限レベル
| 設定値 | 対象ユーザー | 使用場面 |
|---|---|---|
| Maintainers | メンテナーロール以上 | 小規模チーム、開発環境 |
| Developers | デベロッパーロール以上 | テスト環境、ステージング環境 |
| 特定のグループ | 指定したグループのメンバー | 運用チーム専用の本番環境 |
| 特定のユーザー | 個別に指定したユーザー | 特殊な権限が必要な場合 |
2.2 デプロイメント専用アクセスの設定
開発者にはコードの変更権限を与えず、デプロイのみを許可したい場合に使用します。
ユースケース: 運用チームがコードを書かないが、承認されたコードを本番環境にデプロイする責任を持つ場合
設定手順
- 運用チーム用のグループを作成(例:
ops-team) - グループをReporterロールでプロジェクトに招待
- 環境保護設定で
ops-teamをAllowed to deployに追加
# .gitlab-ci.yml
production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
when: manual
このグループのメンバーは、ブランチへのプッシュやマージはできませんが、デプロイジョブは実行できます。
2.3 実践的な権限設計パターン
パターン1: 3層環境モデル
設定例
- 開発環境: Developers以上
-
ステージング環境: 特定のグループ(
senior-devs,ops-team) -
本番環境: 特定のグループ(
ops-team)のみ
パターン2: 機能別環境モデル
複数のマイクロサービスを運用する場合、サービスごとに異なる運用チームが担当することがあります。
-
サービスA本番環境:
service-a-opsグループ -
サービスB本番環境:
service-b-opsグループ -
共通インフラ環境:
platform-opsグループ
3. グループレベルの環境保護
大規模組織では、プロジェクトごとに環境保護を設定するのは非効率です。グループレベルの環境保護を使用すると、組織全体で一貫したポリシーを適用できます。
3.1 デプロイメント階層の概念
グループレベルでは、環境名ではなくデプロイメント階層(Deployment Tier)を使用します。
なぜ階層を使うのか
プロジェクトごとに環境名が異なる場合でも、統一的なルールを適用できます。
| プロジェクト | 環境名 | デプロイメント階層 |
|---|---|---|
| プロジェクトA | gprd |
production |
| プロジェクトB | Production |
production |
| プロジェクトC | prod-env |
production |
すべてproduction階層として保護されます。
3.2 組織構造と権限設計
3.3 設定手順
ステップ1: デプロイメント階層の定義
.gitlab-ci.ymlで各環境に階層を設定します。
stages:
- deploy
deploy_staging:
stage: deploy
script:
- ./deploy.sh staging
environment:
name: staging
deployment_tier: staging
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
deployment_tier: production
when: manual
ステップ2: グループレベルでの保護設定
- トップレベルグループの Settings > CI/CD を開く
- Protected environments セクションを展開
-
Environment で
production階層を選択 -
Allowed to deploy で
operationsグループを選択 - Protect をクリック
ステップ3: 権限の確認
-
operationsグループのメンバー: すべてのプロジェクトのproduction階層にデプロイ可能 -
developmentグループのメンバー:production階層にはデプロイ不可
3.4 プロジェクトレベルとの組み合わせ
グループレベルとプロジェクトレベルの両方で環境保護が設定されている場合、両方の条件を満たす必要があります。
例: 追加の制限を設けるケース
-
グループレベル:
operationsグループがデプロイ可能 -
プロジェクトA: さらに
project-a-specialistsグループも必要
この場合、operationsグループとproject-a-specialistsグループの両方に属するユーザーのみがデプロイできます。
4. デプロイメント承認による多層防御
環境保護でデプロイ権限を制限しても、承認プロセスがなければ、権限を持つユーザーが単独で判断してデプロイできてしまいます。デプロイメント承認を追加することで、複数の目によるチェックを強制できます。
4.1 承認が必要なケース
ケース1: セキュリティレビュー
セキュリティに影響する変更は、セキュリティチームの承認が必要です。
ケース2: 変更管理プロセス
ITIL準拠の組織では、変更諮問委員会(CAB)の承認が必要です。
ケース3: ビジネス承認
重要な機能リリースは、プロダクトオーナーの承認が必要です。
4.2 承認ルールの設定
基本設定
- Settings > CI/CD > Protected environments を開く
- 環境を保護する際にApproversを設定
- Approval rulesで必要な承認数を設定
設定例: 2段階承認
-
Approvers:
ops-teamグループ、security-teamグループ - Required approvals: 2
この設定では、ops-teamから1名、security-teamから1名の承認が必要です。
4.3 承認フロー
4.4 承認の実行
承認者の操作手順
- Operate > Environments を開く
- 環境を選択
- デプロイメントのStatus badge(例:
blocked)をクリック - 変更内容を確認
- コメントを追加(例: 「セキュリティスキャン結果を確認しました」)
- Approveをクリック
却下する場合
問題がある場合はRejectをクリックします。却下されたデプロイメントは実行できません。
4.5 セルフ承認の制御
デフォルトでは、パイプラインをトリガーしたユーザーは自分自身のデプロイメントを承認できません。
セルフ承認を許可すべきケース
- 小規模チームで、同じ人が開発と運用を兼任している
- 緊急時の迅速な対応が必要
セルフ承認を禁止すべきケース
- コンプライアンス要件がある
- 職務分離が必要
- 大規模組織
設定方法
Settings > CI/CD > Protected environments > Approval options で Allow pipeline triggerer to approve deployment を設定します。
4.6 複数承認ルールの設計パターン
パターン1: 並列承認(AND条件)
# 設定イメージ
Approvers:
- ops-team (1名必要)
- security-team (1名必要)
Required approvals: 2
両方のチームから承認が必要です。
パターン2: 単一チーム内の複数承認
# 設定イメージ
Approvers:
- ops-team
Required approvals: 2
ops-team内の2名から承認が必要です。
パターン3: 階層的承認
# プロジェクトレベル
Approvers:
- tech-lead
Required approvals: 1
# グループレベル
Approvers:
- ops-team
Required approvals: 1
テックリードと運用チームの両方から承認が必要です。
5. デプロイメントの安全性制御
承認と権限管理に加えて、技術的な安全性制御を実装することで、デプロイメントの信頼性を高めます。
5.1 同時デプロイメントの防止
問題のシナリオ
2つのデプロイが同時に実行され、データベースマイグレーションの競合やファイルの上書きが発生します。
解決策: resource_group
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
resource_group: production-deploy
動作
パイプラインBは、パイプラインAの完了を待ってから実行されます。
5.2 古いデプロイメントの防止
問題のシナリオ
解決策: Prevent outdated deployment jobs
設定手順
- Settings > CI/CD > Deployment jobs を開く
- Prevent outdated deployment jobs を有効化
動作
5.3 ロールバック戦略
デフォルト動作: ジョブ再試行によるロールバック
問題が発生した場合、以前のパイプラインのデプロイジョブを再実行することで、素早くロールバックできます。
ロールバック手順
- Operate > Environments を開く
- 環境を選択
- デプロイメント履歴から安定したバージョンを探す
- そのデプロイメントのRe-deployボタンをクリック
機密プロジェクトでの設定
コンプライアンス要件が厳しい場合、ジョブ再試行を無効化します。
- Settings > CI/CD > Deployment jobs を開く
- Allow job retries for rollback deployments をオフ
この場合、ロールバックには以前のコミットで新しいパイプラインを実行する必要があります。
5.4 デプロイフリーズ
ユースケース
- 年末年始の休暇期間
- 大規模イベント期間中
- メンテナンスウィンドウ
設定方法
- Operate > Environments を開く
- Deploy freeze タブを選択
- 期間を設定(例: 2024-12-28 18:00 から 2025-01-06 09:00)
- Add deploy freeze をクリック
デプロイフリーズ期間中は、すべてのデプロイメントジョブが自動的に失敗します。
5.5 シークレット管理
保護された変数の設定
# .gitlab-ci.yml
deploy_production:
stage: deploy
script:
- echo "APIキーを使用してデプロイ"
- ./deploy.sh --api-key $PRODUCTION_API_KEY
environment:
name: production
only:
- main
変数の設定
- Settings > CI/CD > Variables を開く
- Add variable をクリック
- Key:
PRODUCTION_API_KEY - Value: 実際のAPIキー
- Protect variable をオン
- Mask variable をオン
- Environment scope:
production
効果
- 保護されたブランチ(
main)でのみ変数が利用可能 -
production環境でのみ変数が利用可能 - ログに値が表示されない(マスクされる)
6. 段階的な導入ガイド
6.1 フェーズ1: 基本的な環境保護(1週間)
目標: 本番環境への不正なデプロイを防ぐ
実施内容
- 本番環境を保護
- 運用チームのみにデプロイ権限を付与
- 手動デプロイに変更
# .gitlab-ci.yml
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
when: manual # 手動実行に変更
only:
- main
検証方法
- 開発者がデプロイジョブを実行できないことを確認
- 運用チームメンバーがデプロイできることを確認
6.2 フェーズ2: 承認プロセスの追加(2週間)
目標: 複数の目によるチェックを導入
実施内容
- 承認ルールを追加(運用チーム1名、セキュリティチーム1名)
- 承認フローをチームに周知
- 承認時のチェックリストを作成
チェックリスト例
- テスト環境で動作確認済み
- セキュリティスキャン結果を確認
- データベースマイグレーションの影響を確認
- ロールバック手順を確認
6.3 フェーズ3: 安全性制御の強化(1週間)
目標: 技術的な競合を防ぐ
実施内容
-
resource_groupを追加 - Prevent outdated deployment jobsを有効化
- デプロイフリーズを設定(次回の休暇期間)
# .gitlab-ci.yml (改善版)
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
deployment_tier: production
resource_group: production-deploy
when: manual
only:
- main
6.4 フェーズ4: グループレベルへの拡大(2週間)
目標: 組織全体で一貫したポリシーを適用
実施内容
- すべてのプロジェクトで
deployment_tierを設定 - グループレベルで環境保護を設定
- プロジェクトレベルの設定を削除(グループレベルに統一)
移行手順
- 各プロジェクトの
.gitlab-ci.ymlを更新 - グループレベルで保護設定を追加
- プロジェクトレベルの設定を削除
- 動作確認
7. 実践的な設定パターン
7.1 小規模チーム向け(5-10名)
特徴
- 開発者と運用者が兼任
- 迅速なデプロイが必要
- シンプルな承認プロセス
推奨設定
# .gitlab-ci.yml
stages:
- test
- deploy
test:
stage: test
script:
- npm test
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
resource_group: production-deploy
when: manual
only:
- main
環境保護設定
- Allowed to deploy: Maintainers
- Approvers: Maintainers
- Required approvals: 1
- Allow pipeline triggerer to approve deployment: オン
7.2 中規模組織向け(20-50名)
特徴
- 開発チームと運用チームが分離
- 複数のプロジェクト
- セキュリティレビューが必要
推奨設定
# .gitlab-ci.yml
stages:
- test
- security
- deploy
test:
stage: test
script:
- npm test
security_scan:
stage: security
script:
- npm audit
- ./security-scan.sh
deploy_staging:
stage: deploy
script:
- ./deploy.sh staging
environment:
name: staging
deployment_tier: staging
resource_group: staging-deploy
only:
- main
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
deployment_tier: production
resource_group: production-deploy
when: manual
only:
- main
グループレベル環境保護設定
-
production階層
-
Allowed to deploy:
ops-teamグループ -
Approvers:
ops-teamグループ、security-teamグループ - Required approvals: 2
- Allow pipeline triggerer to approve deployment: オフ
-
Allowed to deploy:
-
staging階層
-
Allowed to deploy:
senior-devsグループ、ops-teamグループ -
Approvers:
ops-teamグループ - Required approvals: 1
-
Allowed to deploy:
7.3 大規模エンタープライズ向け(100名以上)
特徴
- 複数の事業部、複数のプロダクト
- 厳格なコンプライアンス要件
- 変更管理プロセス(CAB)
推奨設定
# .gitlab-ci.yml
stages:
- test
- security
- compliance
- deploy
test:
stage: test
script:
- npm test
coverage: '/Coverage: \d+\.\d+%/'
security_scan:
stage: security
script:
- ./sast-scan.sh
- ./dependency-scan.sh
artifacts:
reports:
sast: gl-sast-report.json
dependency_scanning: gl-dependency-scanning-report.json
compliance_check:
stage: compliance
script:
- ./compliance-check.sh
only:
- main
deploy_staging:
stage: deploy
script:
- ./deploy.sh staging
environment:
name: staging
deployment_tier: staging
resource_group: staging-deploy
only:
- main
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
deployment_tier: production
resource_group: production-deploy
when: manual
only:
- main
グループレベル環境保護設定
-
production階層
-
Allowed to deploy:
ops-teamグループ -
Approvers:
ops-teamグループ、security-teamグループ、compliance-teamグループ - Required approvals: 3
- Allow pipeline triggerer to approve deployment: オフ
-
Allowed to deploy:
追加設定
- Prevent outdated deployment jobs: オン
- Allow job retries for rollback deployments: オフ
- デプロイフリーズ: 休暇期間、重要イベント期間
- 保護された変数: すべての本番シークレット
- 監査ログ: 有効化
7.4 マイクロサービス環境向け
特徴
- 複数のサービスが独立してデプロイ
- サービスごとに異なる運用チーム
- 依存関係の管理が必要
推奨設定
# サービスA/.gitlab-ci.yml
deploy_service_a_production:
stage: deploy
script:
- ./deploy-service-a.sh production
environment:
name: service-a-production
deployment_tier: production
resource_group: service-a-production
when: manual
only:
- main
# サービスB/.gitlab-ci.yml
deploy_service_b_production:
stage: deploy
script:
- ./deploy-service-b.sh production
environment:
name: service-b-production
deployment_tier: production
resource_group: service-b-production
when: manual
only:
- main
プロジェクトレベル環境保護設定
-
サービスA
-
Allowed to deploy:
service-a-opsグループ -
Approvers:
service-a-opsグループ - Required approvals: 1
-
Allowed to deploy:
-
サービスB
-
Allowed to deploy:
service-b-opsグループ -
Approvers:
service-b-opsグループ - Required approvals: 1
-
Allowed to deploy:
グループレベル環境保護設定
-
production階層
-
Allowed to deploy:
platform-opsグループ(すべてのサービスに適用) -
Approvers:
platform-opsグループ - Required approvals: 1
-
Allowed to deploy:
この設定により、各サービスの運用チームと、プラットフォーム全体の運用チームの両方から承認が必要になります。
8. トラブルシューティング
8.1 デプロイジョブが実行できない
症状: 「You are not allowed to deploy to this environment」エラー
原因と解決策
| 原因 | 確認方法 | 解決策 |
|---|---|---|
| 環境保護設定で権限がない | Settings > CI/CD > Protected environmentsを確認 | 自分のユーザーまたはグループをAllowed to deployに追加 |
| グループレベルとプロジェクトレベルの両方で制限されている | 両方の設定を確認 | 両方の設定で権限を付与 |
| ブランチが保護されていない | パイプラインが実行されているブランチを確認 | 保護されたブランチ(mainなど)で実行 |
8.2 承認後もジョブが実行されない
症状: 承認は完了しているが、デプロイジョブが開始されない
原因: 承認後は自動実行されません
解決策: 手動でジョブを実行する
- Operate > Environments を開く
- 環境を選択
- 承認済みのデプロイメントを探す
- Runボタンをクリック
8.3 古いデプロイメントが失敗する
症状: 「The deployment job is older than the latest deployment」エラー
原因: Prevent outdated deployment jobsが有効で、より新しいデプロイメントが既に実行されている
解決策
- 意図的な動作です。最新のコードをデプロイしてください
- ロールバックが必要な場合は、Re-deploy機能を使用するか、新しいパイプラインを実行してください
8.4 Reporterロールでトリガージョブが実行できない
症状: デプロイメント専用アクセスを持つユーザーが、triggerキーワードを使用したジョブを実行できない
原因: triggerキーワードとenvironmentキーワードの組み合わせは現在サポートされていません
解決策
トリガージョブを使用する場合は、Developerロール以上を付与するか、トリガージョブとデプロイジョブを分離してください。
# 回避策: ジョブを分離
trigger_downstream:
stage: trigger
trigger:
project: other-project
branch: main
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
when: manual
8.5 承認ルール削除後の履歴が見えない
症状: 承認ルールを削除したら、過去のデプロイメントの承認者が表示されなくなった
原因: 承認ルールが削除されると、UI上の承認者情報も削除されます
解決策
承認者の情報は監査イベントに残っています。
- Settings > Audit Events を開く
- デプロイメントの日時で検索
- 承認イベントを確認
9. まとめ
9.1 機能の組み合わせによる効果
9.2 導入による効果
セキュリティの向上
- 権限のないユーザーによる不正なデプロイを防止
- シークレットの露出を最小限に抑制
- 承認プロセスによる多層防御
- 監査証跡の確保
運用の安定性
- 同時デプロイメントによる競合状態を回避
- 古いコードによる上書きを防止
- デプロイフリーズによる計画的なメンテナンス
- 迅速なロールバック
組織のガバナンス
- 開発者とオペレーターの責任分離
- グループレベルでの一貫したポリシー適用
- コンプライアンス要件への対応
- 変更管理プロセスの自動化
9.3 次のステップ
ステップ1: 現状評価(1日)
- 現在のデプロイメントプロセスを文書化
- リスクを特定
- 優先順位を決定
ステップ2: パイロット導入(1-2週間)
- 1つのプロジェクトで環境保護を試験的に導入
- チームからフィードバックを収集
- 設定を調整
ステップ3: 段階的な展開(1-2ヶ月)
- フェーズ1: 環境保護
- フェーズ2: 承認プロセス
- フェーズ3: 安全性制御
- フェーズ4: グループレベルへの拡大
ステップ4: 継続的な改善
- デプロイメントメトリクスを監視
- 承認プロセスの効率化
- チームのトレーニング
9.4 利用可能なティア
| 機能 | Free | Premium | Ultimate |
|---|---|---|---|
| プロジェクトレベル環境保護 | - | ✓ | ✓ |
| グループレベル環境保護 | - | ✓ | ✓ |
| デプロイメント承認 | - | ✓ | ✓ |
| resource_group | ✓ | ✓ | ✓ |
| Prevent outdated deployment jobs | ✓ | ✓ | ✓ |
| デプロイフリーズ | ✓ | ✓ | ✓ |
| 保護された変数 | ✓ | ✓ | ✓ |
GitLabの環境保護、デプロイメント承認、安全性制御機能を適切に組み合わせることで、組織の規模や要件に応じた、安全で信頼性の高いデプロイメントプロセスを構築できます。段階的に導入し、チームのフィードバックを反映しながら、最適な設定を見つけてください。