<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>IaC / Platform 部署 CI/CD on Tarragon</title><link>https://tarrragon.github.io/blog/ci/iac-platform-deploy/</link><description>Recent content in IaC / Platform 部署 CI/CD on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 06 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/ci/iac-platform-deploy/index.xml" rel="self" type="application/rss+xml"/><item><title>IaC plan、apply、drift 與 recovery 流程</title><link>https://tarrragon.github.io/blog/ci/iac-platform-deploy/plan-apply-drift-recovery-flow/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ci/iac-platform-deploy/plan-apply-drift-recovery-flow/</guid><description>&lt;p>IaC 發布流程的核心責任是把基礎設施變更變成可審查、可套用、可追溯的狀態轉移。Terraform、Pulumi、Helm 或平台自動化會改變網路、權限、資料庫、節點、DNS 與部署平台，因此 CI/CD 要把 plan、review、apply、&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/infrastructure-drift/" data-link-title="Infrastructure Drift" data-link-desc="說明真實基礎設施狀態與 IaC 宣告分叉時的偵測、判讀與修復責任">Infrastructure Drift&lt;/a> 與 recovery 分成明確 gate。&lt;/p>
&lt;h2 id="流程定位">流程定位&lt;/h2>
&lt;p>IaC 的風險集中在共享狀態與不可逆資源。應用部署失敗常可回退 artifact；基礎設施變更可能刪除資料、替換節點、改掉 IAM 權限或讓 state 與真實環境分叉。發布流程應讓 reviewer 在 apply 前看到「將要改什麼」，並讓 apply 後能確認「環境是否真的符合宣告」。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>責任&lt;/th>
 &lt;th>判讀訊號&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Plan&lt;/td>
 &lt;td>預覽資源差異與風險&lt;/td>
 &lt;td>create / update / replace / destroy&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Review&lt;/td>
 &lt;td>審核變更意圖、權限與影響面&lt;/td>
 &lt;td>高風險資源、跨環境、資料資源&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Apply&lt;/td>
 &lt;td>在鎖定狀態下套用變更&lt;/td>
 &lt;td>state lock、timeout、partial apply&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Verify&lt;/td>
 &lt;td>確認環境符合預期&lt;/td>
 &lt;td>health、policy、smoke、connectivity&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/infrastructure-drift/" data-link-title="Infrastructure Drift" data-link-desc="說明真實基礎設施狀態與 IaC 宣告分叉時的偵測、判讀與修復責任">Infrastructure Drift&lt;/a>&lt;/td>
 &lt;td>偵測真實環境與宣告分叉&lt;/td>
 &lt;td>手動 hotfix、console edit、外部系統&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Recovery&lt;/td>
 &lt;td>回退、補正或 state repair&lt;/td>
 &lt;td>是否能安全恢復服務與 state&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Plan 階段負責產生可審查差異。Plan 是 reviewer 判斷資源替換、權限擴大、資料刪除與網路暴露的主要材料。CI 應保留 plan artifact，讓 apply 使用同一份輸入與版本。&lt;/p>
&lt;p>Review 階段負責把風險放到正確 owner。平台、資安、資料庫或服務 owner 應依資源類型參與審核；高風險變更需要額外 gate，例如 maintenance window、人工 approval 或雙人審核。&lt;/p>
&lt;p>Apply 階段負責把宣告狀態寫入環境。&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/state-lock/" data-link-title="State Lock" data-link-desc="說明 IaC apply 如何用狀態鎖避免併發變更覆寫基礎設施狀態">State Lock&lt;/a>、credential、workspace 與環境變數都要固定；partial apply 或 timeout 後，要先判斷 state 與真實資源是否一致，再決定下一步。&lt;/p>
&lt;p>Verify 階段負責確認平台可用。Apply 成功只代表 provider API 接受變更；仍需要 connectivity test、policy check、service smoke test、DNS / certificate check 或 cluster health，確認服務真的能跑。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/infrastructure-drift/" data-link-title="Infrastructure Drift" data-link-desc="說明真實基礎設施狀態與 IaC 宣告分叉時的偵測、判讀與修復責任">Infrastructure Drift&lt;/a> 階段負責發現宣告與現況分叉。手動 hotfix、雲端 console 調整、外部 controller 或 provider 預設值都可能造成 drift；drift detection 要定期執行，並把修復責任導回宣告檔。&lt;/p>
&lt;p>Recovery 階段負責處理失敗套用。IaC 回復不一定是 &lt;code>git revert&lt;/code> 後 apply；可能需要 import、state mv、taint / untaint、手動修復資料資源或 forward fix。流程要先保護資料與服務，再修正宣告與 state。&lt;/p>
&lt;h2 id="plan-review-判讀">Plan review 判讀&lt;/h2>
&lt;p>Plan review 的責任是讓變更影響在 apply 前被看見。Reviewer 應依資源語意判斷，讓 diff 行數退居輔助訊號。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Plan 訊號&lt;/th>
 &lt;th>判讀&lt;/th>
 &lt;th>下一步&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>destroy&lt;/code>&lt;/td>
 &lt;td>資源將被刪除&lt;/td>
 &lt;td>確認資料、依賴與備份&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>replace&lt;/code>&lt;/td>
 &lt;td>先刪後建或重建資源&lt;/td>
 &lt;td>檢查 downtime、IP、DNS、資料&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>IAM 權限擴大&lt;/td>
 &lt;td>blast radius 增加&lt;/td>
 &lt;td>資安或平台 owner 審核&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Network 開放&lt;/td>
 &lt;td>暴露面增加&lt;/td>
 &lt;td>檢查 security group / firewall&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>State 大量漂移&lt;/td>
 &lt;td>宣告與現況長期分叉&lt;/td>
 &lt;td>先處理 drift，再進 feature change&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>這張表讓 review 從「有人按 approve」變成風險判讀。IaC review 的價值在於提前看見不可逆或高代價變更。&lt;/p></description><content:encoded><![CDATA[<p>IaC 發布流程的核心責任是把基礎設施變更變成可審查、可套用、可追溯的狀態轉移。Terraform、Pulumi、Helm 或平台自動化會改變網路、權限、資料庫、節點、DNS 與部署平台，因此 CI/CD 要把 plan、review、apply、<a href="/blog/ci/knowledge-cards/infrastructure-drift/" data-link-title="Infrastructure Drift" data-link-desc="說明真實基礎設施狀態與 IaC 宣告分叉時的偵測、判讀與修復責任">Infrastructure Drift</a> 與 recovery 分成明確 gate。</p>
<h2 id="流程定位">流程定位</h2>
<p>IaC 的風險集中在共享狀態與不可逆資源。應用部署失敗常可回退 artifact；基礎設施變更可能刪除資料、替換節點、改掉 IAM 權限或讓 state 與真實環境分叉。發布流程應讓 reviewer 在 apply 前看到「將要改什麼」，並讓 apply 後能確認「環境是否真的符合宣告」。</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>責任</th>
          <th>判讀訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Plan</td>
          <td>預覽資源差異與風險</td>
          <td>create / update / replace / destroy</td>
      </tr>
      <tr>
          <td>Review</td>
          <td>審核變更意圖、權限與影響面</td>
          <td>高風險資源、跨環境、資料資源</td>
      </tr>
      <tr>
          <td>Apply</td>
          <td>在鎖定狀態下套用變更</td>
          <td>state lock、timeout、partial apply</td>
      </tr>
      <tr>
          <td>Verify</td>
          <td>確認環境符合預期</td>
          <td>health、policy、smoke、connectivity</td>
      </tr>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/infrastructure-drift/" data-link-title="Infrastructure Drift" data-link-desc="說明真實基礎設施狀態與 IaC 宣告分叉時的偵測、判讀與修復責任">Infrastructure Drift</a></td>
          <td>偵測真實環境與宣告分叉</td>
          <td>手動 hotfix、console edit、外部系統</td>
      </tr>
      <tr>
          <td>Recovery</td>
          <td>回退、補正或 state repair</td>
          <td>是否能安全恢復服務與 state</td>
      </tr>
  </tbody>
</table>
<p>Plan 階段負責產生可審查差異。Plan 是 reviewer 判斷資源替換、權限擴大、資料刪除與網路暴露的主要材料。CI 應保留 plan artifact，讓 apply 使用同一份輸入與版本。</p>
<p>Review 階段負責把風險放到正確 owner。平台、資安、資料庫或服務 owner 應依資源類型參與審核；高風險變更需要額外 gate，例如 maintenance window、人工 approval 或雙人審核。</p>
<p>Apply 階段負責把宣告狀態寫入環境。<a href="/blog/ci/knowledge-cards/state-lock/" data-link-title="State Lock" data-link-desc="說明 IaC apply 如何用狀態鎖避免併發變更覆寫基礎設施狀態">State Lock</a>、credential、workspace 與環境變數都要固定；partial apply 或 timeout 後，要先判斷 state 與真實資源是否一致，再決定下一步。</p>
<p>Verify 階段負責確認平台可用。Apply 成功只代表 provider API 接受變更；仍需要 connectivity test、policy check、service smoke test、DNS / certificate check 或 cluster health，確認服務真的能跑。</p>
<p><a href="/blog/ci/knowledge-cards/infrastructure-drift/" data-link-title="Infrastructure Drift" data-link-desc="說明真實基礎設施狀態與 IaC 宣告分叉時的偵測、判讀與修復責任">Infrastructure Drift</a> 階段負責發現宣告與現況分叉。手動 hotfix、雲端 console 調整、外部 controller 或 provider 預設值都可能造成 drift；drift detection 要定期執行，並把修復責任導回宣告檔。</p>
<p>Recovery 階段負責處理失敗套用。IaC 回復不一定是 <code>git revert</code> 後 apply；可能需要 import、state mv、taint / untaint、手動修復資料資源或 forward fix。流程要先保護資料與服務，再修正宣告與 state。</p>
<h2 id="plan-review-判讀">Plan review 判讀</h2>
<p>Plan review 的責任是讓變更影響在 apply 前被看見。Reviewer 應依資源語意判斷，讓 diff 行數退居輔助訊號。</p>
<table>
  <thead>
      <tr>
          <th>Plan 訊號</th>
          <th>判讀</th>
          <th>下一步</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>destroy</code></td>
          <td>資源將被刪除</td>
          <td>確認資料、依賴與備份</td>
      </tr>
      <tr>
          <td><code>replace</code></td>
          <td>先刪後建或重建資源</td>
          <td>檢查 downtime、IP、DNS、資料</td>
      </tr>
      <tr>
          <td>IAM 權限擴大</td>
          <td>blast radius 增加</td>
          <td>資安或平台 owner 審核</td>
      </tr>
      <tr>
          <td>Network 開放</td>
          <td>暴露面增加</td>
          <td>檢查 security group / firewall</td>
      </tr>
      <tr>
          <td>State 大量漂移</td>
          <td>宣告與現況長期分叉</td>
          <td>先處理 drift，再進 feature change</td>
      </tr>
  </tbody>
</table>
<p>這張表讓 review 從「有人按 approve」變成風險判讀。IaC review 的價值在於提前看見不可逆或高代價變更。</p>
<h2 id="drift-處理路由">Drift 處理路由</h2>
<p>Drift 處理的責任是把現況重新帶回可管理狀態。Drift 發現後不應直接 apply 覆蓋，因為 drift 可能是事故 hotfix、外部系統自動調整或宣告檔過期。</p>
<ol>
<li>確認 drift 來源：人工 hotfix、provider 預設、外部 controller 或宣告過期。</li>
<li>判斷 drift 是否仍需要保留：若是真實修復，應回寫到 IaC。</li>
<li>判斷 apply 是否會破壞服務：特別看 replacement、destroy、權限與 network。</li>
<li>修正宣告或 state：必要時使用 import、state mv 或 provider-specific repair。</li>
<li>重新 plan，確認差異收斂到預期。</li>
</ol>
<p>這個路由讓 drift 修復具備審查性。直接在 console 裡補到看起來正常，會讓下一次 CI apply 把修復覆蓋掉。</p>
<h2 id="常見反模式">常見反模式</h2>
<p>反模式的共同問題是把 IaC 降成指令自動化，忽略它承擔的狀態治理責任。</p>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>風險</th>
          <th>替代做法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>plan 與 apply 使用不同輸入</td>
          <td>review 內容與實際套用內容分叉</td>
          <td>保存 plan artifact 或鎖定版本</td>
      </tr>
      <tr>
          <td>沒有 <a href="/blog/ci/knowledge-cards/state-lock/" data-link-title="State Lock" data-link-desc="說明 IaC apply 如何用狀態鎖避免併發變更覆寫基礎設施狀態">State Lock</a></td>
          <td>併發 apply 覆寫狀態</td>
          <td>使用 remote backend 與 locking</td>
      </tr>
      <tr>
          <td>drift 長期忽略</td>
          <td>宣告失去可信度</td>
          <td>定期 drift detection 與 owner 路由</td>
      </tr>
      <tr>
          <td>高風險資源無額外 gate</td>
          <td>資料或網路變更直接進環境</td>
          <td>environment protection / approval</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>IaC 部署總覽：回 <a href="../">IaC / Platform 部署 CI/CD</a>。</li>
<li>環境保護：讀 <a href="/blog/ci/knowledge-cards/environment-protection/" data-link-title="Environment Protection" data-link-desc="說明目標環境的審核、權限與放行條件如何保護發布">Environment Protection</a>。</li>
<li>Gate 原理：讀 <a href="../../ci-gate-workflow-boundary/">CI gate 與 workflow 邊界</a>。</li>
</ul>
]]></content:encoded></item></channel></rss>