Skip to content

Commit dfa7d78

Browse files
authored
add blog: before-deployment (#5788)
Signed-off-by: t-kikuc <[email protected]>
1 parent e92520b commit dfa7d78

File tree

3 files changed

+229
-0
lines changed

3 files changed

+229
-0
lines changed
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
---
2+
date: 2025-04-28
3+
title: "What Happens before Deployment? GitOps Mechanism"
4+
linkTitle: "What Happens before Deployment?"
5+
weight: 982
6+
author: Tetsuya Kikuchi ([@t-kikuc](https://github.com/t-kikuc))
7+
categories: ["Announcement"]
8+
tags: ["New Feature"]
9+
---
10+
11+
This article explains the process before a deployment begins in PipeCD. Since PipeCD is pull-based, there are various processes that take place before a deployment starts.
12+
13+
Probably, you have felt "What is Pending??" at least once:
14+
![Pending](/images/before-deploy-pending.png)
15+
16+
17+
The target audience is those who want to:
18+
- troubleshoot when "deployment doesn't start as expected..."
19+
- understand GitOps mechanisms and implementation
20+
- contribute to PipeCD
21+
22+
23+
_This article is based on PipeCD v0.51.2 (latest version at time of writing). The specifications in the [plugin version](https://zenn.dev/cadp/articles/pipecd-plugin-intro) are slightly different._
24+
25+
26+
_This article omits discussion of [Deployment Chain](https://pipecd.dev/docs-v0.51.x/user-guide/managing-application/deployment-chain/) (due to complexity)._
27+
28+
## Overview
29+
30+
The state transitions before deployment begins are shown in the diagram below.
31+
32+
```mermaid
33+
stateDiagram-v2
34+
Not_Started --> PENDING: [1] Trigger
35+
PENDING --> PLANNED: [2] Plan (Determine pipeline)
36+
PLANNED --> RUNNING: [3] Schedule (Execute stages)
37+
```
38+
39+
Phases [1] through [3] are **executed asynchronously by separate components (goroutines)**. This mechanism allows deployment to resume even if Piped crashes during the process.
40+
41+
![](/images/before-deploy-components.drawio.png)
42+
43+
## 1. Trigger
44+
45+
PipeCD initiates application deployment through four types of triggers:
46+
47+
- [A] Detecting changes in Git (main method)
48+
- Includes integration from CI through [EventWatcher](https://pipecd.dev/docs/user-guide/managing-piped/configuring-event-watcher/)
49+
- [B] Manual start from UI/pipectl
50+
- [C] Automatic deployment on drift detection (requires configuration)
51+
- [D] Deployment Chain (details omitted)
52+
53+
The above four points can be configured [`trigger`](https://pipecd.dev/docs-v0.51.x/user-guide/configuration-reference/#deploymenttrigger) in `app.pipecd.yaml`. **Only [C] is disabled by default**.
54+
55+
#### [A] Detecting changes in Git
56+
57+
This occurs when the following two conditions are met after fetching the latest commit from the Git repository:
58+
59+
1. There are new commits that haven't been deployed
60+
2. There is at least one change in files at the same level or below `app.pipecd.yaml`
61+
62+
For 2., the detection scope can be adjusted using [`paths`/`ignores` settings](https://pipecd.dev/docs-v0.51.x/user-guide/configuration-reference/#oncommit). This allows detection of changes in shared template files located in different directories, for example.
63+
64+
#### [B] Manual trigger from UI/pipectl
65+
66+
This is a push-style pattern.
67+
68+
From the UI, you can start it on the Application page. This is convenient for cases like "redeploying after a deployment failure due to environment issues rather than application issues."
69+
70+
You can also start it from pipectl using the [following command](https://pipecd.dev/docs-v0.51.x/user-guide/command-line-tool/#syncing-an-application). This is useful for cases like "direct deployment from CI (exceptionally) or workflows."
71+
```sh
72+
pipectl application sync --app-id={app-id}
73+
```
74+
75+
#### [C] Automatic deployment on drift detection (requires configuration)
76+
77+
This occurs when there's a difference between the Git definition (=desired state) and the actual environment. PipeCD has a separate mechanism called [Drift Detection](https://pipecd.dev/docs-v0.51.x/user-guide/managing-application/configuration-drift-detection/) that continuously detects drifts.
78+
79+
This trigger is disabled by default, and manual repair is the basic approach after drift detection. This trigger is for those who want to strictly treat Git as the Single Source of Truth.
80+
81+
Deployment is triggered when an application meets all four of the following conditions:
82+
83+
1. "Automatic deployment on drift detection" is enabled
84+
- Set the `trigger.onOutOfSync.disabled` item to `false` (**default is `true`**)
85+
2. Drift has occurred (status is `OutOfSync`)
86+
3. Not currently deploying
87+
4. A specified time has passed since the last deployment (default is 5 minutes)
88+
- This prevents the scenario where "deployment completes but the drift detection mechanism is delayed, causing false drift detection and deployment"
89+
- Can be configured with the `trigger.onOutOfSync.minWindow` item
90+
91+
https://pipecd.dev/docs-v0.51.x/user-guide/configuration-reference/#onoutofsync
92+
93+
#### Trigger code
94+
95+
See the `trigger` package, `trigger.go` is the entry point and `determiner.go` determines whether to deploy or not.
96+
97+
Personally, reading the `trigger` package significantly improves understanding of PipeCD's behavior.
98+
99+
https://github.com/pipe-cd/pipecd/blob/v0.51.2/pkg/app/piped/trigger/
100+
101+
## 2. Plan: Determine Pipeline
102+
103+
This phase determines "how to deploy using which pipeline." It mainly does two things:
104+
105+
1. Determine whether to use Quick Sync or Pipeline Sync
106+
2. Determine stages
107+
108+
The planner instance runs as a goroutine in a 1:1 relationship with Deployment, allowing multiple deployments to be processed concurrently.
109+
Also, piped is implemented to prevent multiple deployments from running simultaneously for the same application.
110+
111+
#### 2.1. Determining Quick Sync or Pipeline Sync
112+
113+
##### What are Quick Sync and Pipeline Sync?
114+
115+
PipeCD has two deployment strategies:
116+
117+
- **Quick Sync**
118+
- Executes deployment with a single stage (`K8S_SYNC` or `ECS_SYNC`, etc.)
119+
- Optimal for cases where "only Git synchronization is needed, no analysis required"
120+
121+
- **Pipeline Sync**
122+
- Executes deployment according to a defined pipeline
123+
- Optimal for cases requiring staged deployment like Canary deployment
124+
125+
##### Strategy determination logic
126+
127+
**Quick Sync is selected when any of the following conditions are met:**
128+
129+
- [A] User manually starts deployment from UI selecting "Quick Sync"
130+
- [B] No `pipeline` is configured in `app.pipecd.yaml`
131+
- [C] (k8s only) Conditions in `app.pipecd.yaml`'s [`planner.commitMatcher.quickSync`](https://pipecd.dev/docs-v0.51.x/user-guide/configuration-reference/#commitmatcher) are met
132+
- [D] (except Terraform) No successful deployment exists for that application
133+
- [E] (k8s only) No changes in workload or config ([details](https://pipecd.dev/docs-v0.51.x/user-guide/managing-application/defining-app-configuration/kubernetes/#quick-sync))
134+
135+
**Pipeline Sync is selected when any of the following conditions are met:**
136+
- [A] User manually starts deployment from UI selecting "Pipeline Sync"
137+
- [B] `planner.alwaysUsePipeline` is set to `true` in `app.pipecd.yaml` (default is `false`)
138+
- [C] (k8s only) Conditions in `app.pipecd.yaml`'s [`planner.commitMatcher.pipeline`](https://pipecd.dev/docs-v0.51.x/user-guide/configuration-reference/#commitmatcher) are met
139+
140+
The detailed decision flowchart is like this:
141+
```mermaid
142+
flowchart TD
143+
Start[Start] --> UI{Triggered from UI and selected 'Auto'?}
144+
145+
UI -->|Quick Sync selected| QuickSync
146+
UI -->|Not from UI or selected 'Auto'| Pipeline{Pipeline configured in app.pipecd.yaml?}
147+
UI -->|Pipeline Sync selected| PipelineSync
148+
149+
Pipeline-->|No| QuickSync
150+
Pipeline-->|Yes| CommitMatcherPipe{**k8s only**: meets commitMatcher.pipeline conditions in app.pipecd.yaml?}
151+
152+
CommitMatcherPipe-->|No / non-k8s | CommitMatcherQuick{**k8s only**: meets commitMatcher.quickSync conditions in app.pipecd.yaml?}
153+
CommitMatcherPipe-->|Yes| PipelineSync
154+
155+
CommitMatcherQuick-->|Yes| QuickSync
156+
CommitMatcherQuick-->|No / non-k8s | Always{alwaysUsePipeline=true in app.pipecd.yaml?}
157+
158+
Always-->|No| Succeeded{Successful deployment exists?}
159+
Always-->|Yes| PipelineSync
160+
161+
Succeeded-->|No| QuickSync
162+
Succeeded-->|Yes| Varied{Platform-specific determination logic}
163+
164+
Varied --> QuickSync
165+
Varied --> PipelineSync
166+
```
167+
168+
#### 2.2. Determining Stages
169+
170+
There's not much noteworthy here.
171+
172+
- For Quick Sync:
173+
- Since there's no user-defined pipeline, generates stages like `K8S_SYNC` for K8s or `ECS_SYNC` for ECS
174+
175+
- For Pipeline Sync:
176+
- Generates stages according to the user-defined pipeline
177+
178+
#### Planner code
179+
180+
The core logic of Plan is implemented per platform in the `planner` package. The `controller` package controls its execution.
181+
182+
https://github.com/pipe-cd/pipecd/blob/v0.51.2/pkg/app/piped/planner/kubernetes/kubernetes.go
183+
184+
## 3. Schedule: Execute Pipeline
185+
186+
The scheduler component manages pipeline progression. It mainly does two things:
187+
188+
1. Execute each stage of the pipeline
189+
2. Execute rollback on failure
190+
191+
Like the planner, the scheduler instance runs as a goroutine in a 1:1 relationship with Deployment, allowing multiple deployments to be processed concurrently.
192+
193+
#### 3.1. Executing Each Stage of the Pipeline
194+
195+
Executes each stage sequentially based on the pipeline generated in the Plan phase.
196+
Specific processing content varies by platform.
197+
198+
#### 3.2. Executing Rollback on Failure
199+
200+
If any stage fails, executes the rollback stage.
201+
Like 3.1., the rollback stage name and processing content vary by platform.
202+
203+
#### Scheduler code
204+
205+
The `Run()` and `executeStage()` methods in `scheduler.go` of the `controller` package are important.
206+
207+
https://github.com/pipe-cd/pipecd/blob/v0.51.2/pkg/app/piped/controller/scheduler.go#L191-L661
208+
209+
The specific processing logic of each stage is in the [`executor` package](https://github.com/pipe-cd/pipecd/blob/v0.51.2/pkg/app/piped/executor/).
210+
The `executor` package describes "execute this process in this stage," making it relatively easy to understand.
211+
212+
## Appendix: What is the controller?
213+
214+
This section is intended for those interested in code reading.
215+
216+
The controller is the manager of the planner and scheduler. Users don't need to be aware of it.
217+
218+
The controller package, which contains the planner and scheduler, includes code related to deployment flow control. The [`controller.go`](https://github.com/pipe-cd/pipecd/blob/v0.51.2/pkg/app/piped/controller/controller.go) is the entry point, and the controller runs continuously from Piped startup.
219+
220+
The controller performs the following every 10 seconds:
221+
- Create planner/scheduler for new deployments if needed
222+
- Delete completed planner/scheduler
223+
- Notify planner/scheduler when a user cancels deployment
224+
225+
## Conclusion
226+
227+
While PipeCD has many other features and code, the trigger and controller form its core.
228+
I hope this helps find which code to get hints when you think "it would be nice if PipeCD had a feature like xxx."
229+
Loading
52.9 KB
Loading

0 commit comments

Comments
 (0)