Sentinel 策略即程式碼(PaC)與 Terraform 基礎設施即程式碼(IaC)的結合,是現代雲端基礎設施安全管理的關鍵。本文從 Sentinel 的基本用法開始,逐步探討其在 Terraform 中的應用,涵蓋了策略執行層級、進階函式應用以及除錯技巧等實務經驗。透過整合 Sentinel 和 Terraform,可以有效地自動化基礎設施安全策略的驗證和執行,確保雲端環境的合規性和安全性。實務上,我們可以利用 Sentinel CLI 模擬和測試策略,並結合 Terraform Cloud(TFC)管理 IaC 工件,實作更完善的自動化流程。此外,理解 Sentinel 策略的執行層級,並善用進階函式,可以更精細地控制策略行為,提升 IaC 安全管理的效率。
Policy 1: policy.sentinel (advisory)
Result: true Print messages: Hello World policy.sentinel:9:1 - Rule “main” Value: true
#### 內容解密:
- **執行結果**:Sentinel 結果為 `true`,表示所有策略透過,允許受保護的行為。
- **輸出資訊**:輸出顯示了 `main` 規則的傳回值以及 `print` 陳述式的結果,即 "Hello World"。
### Sentinel CLI 的使用
除了 Sentinel Playground,HashiCorp 也提供了 Sentinel CLI(之前稱為 Sentinel Simulator)來本地應用和測試 Sentinel 策略。使用以下命令可以應用 Hello World 策略:
```bash
# sentinel cli apply command
$ sentinel apply hello-world.sentinel
Pass - hello-world.sentinel
內容解密:
- 命令執行:使用 sentinel apply命令來應用策略檔案hello-world.sentinel。
- 輸出結果:輸出表明策略透過,但未提供詳細資訊。
若要獲得類別似於 Sentinel Playground 的詳細輸出,可以使用 -trace 引數,並結合 -json 引數以 JSON 格式輸出:
{
    "error": null,
    "policies": [
        {
            "error": null,
            "policy": {
                "enforcement_level": "advisory",
                "name": "hello-world.sentinel"
            },
            "result": true,
            "trace": {
                "description": "",
                "error": null,
                "print": "Hello World\n",
                "result": true,
                "rules": {
                    "main": {
                        "desc": "",
                        "ident": "main",
                        "position": {
                            "filename": "hello-world.sentinel",
                            "offset": 64,
                            "line": 9,
                            "column": 1
                        },
                        "value": true
                    }
                }
            }
        }
    ],
    "result": true
}
內容解密:
- 詳細資訊:透過 -trace和-json引數,輸出了詳細的策略評估結果,包括規則名稱、位置和傳回值。
- 強制級別:策略的強制級別被設定為 advisory,表示該控制不是強制性的。
探索 Terraform IaC 工件
在瞭解 Sentinel 的基本用法後,我們需要進一步探索日常用於管理基礎設施的 Terraform IaC 工件。接下來,我們將討論如何利用 Sentinel 對 Terraform 的計劃輸出進行驗證。
使用 Sentinel 驗證 Terraform 計劃
Terraform 在執行計劃時會產生 JSON 格式的輸出,這些輸出可以用於 Sentinel 的策略評估。Sentinel 支援對 Terraform 計劃的 JSON 輸出進行驗證,以確保基礎設施組態符合組織的安全和合規要求。
範例:驗證 Terraform 計劃
假設我們有一個 Terraform 計劃輸出檔案 tfplan.json,我們可以編寫 Sentinel 策略來驗證其中的資源組態。例如,檢查是否所有 S3 儲存桶都已啟用版本控制:
# s3_versioning.sentinel
import "terraform"
main = rule {
    all tfplan.resources.aws_s3_bucket else true {
        it.versioning.enabled == true
    }
}
內容解密:
- 匯入 Terraform 模組:Sentinel 策略匯入了 Terraform 模組,以便存取 Terraform 計劃中的資源資訊。
- 主規則:定義了 main規則,該規則檢查所有aws_s3_bucket資源是否啟用了版本控制。如果所有儲存桶都啟用了版本控制,則規則傳回true。
執行上述策略對 tfplan.json 進行驗證,可以確保 Terraform 組態符合組織的安全要求。
隨著雲端運算和基礎設施即程式碼(IaC)的快速發展,策略即程式碼(PaC)在確保基礎設施安全性和合規性方面的作用日益重要。未來,我們可以預見更多創新的 PaC 工具和技術的出現,這些工具和技術將進一步簡化 IaC 的驗證和管理流程,提升企業的運作效率和安全性。
透過持續學習和實踐最新的 PaC 和 IaC 技術,企業可以更好地應對日益複雜的雲端環境挑戰,實作更加安全、高效和自動化的基礎設施管理。
使用Terraform Cloud進行基礎設施即程式碼管理的最佳實踐
隨著雲端運算的普及,基礎設施即程式碼(IaC)已成為現代IT架構的核心。Terraform作為領先的IaC工具,不僅提供CLI模式,更進階的Terraform Cloud(TFC)則提供了更多企業級功能。本文將探討如何使用TFC進行IaC管理,並著重於其與Sentinel政策即程式碼(PaC)的整合。
Terraform Cloud的重要工件
在使用TFC進行IaC管理時,我們需要了解四個關鍵的工件:
- tfplan:二進位檔案,包含Terraform維護狀態的計劃(建立、讀取、更新或刪除目標環境中的IaC資源)
- tfconfig:包含專案中所有.tf檔案的資料(提供者、資源、資料來源、模組和變數)
- tfstate:Terraform維護和讀取的基礎設施狀態記錄(在事件發生後記錄,如Terraform應用)
- tfrun:包含在TFC中或連線到TFC的Terraform執行的執行資料(包含後設資料和環境資訊)
這些工件對於瞭解Terraform的操作至關重要,同時也是Sentinel PaC驗證的基礎。
模擬資料的重要性
在開發和測試Sentinel政策時,我們需要模擬真實的Terraform工件資料。手動建立模擬資料容易出錯且耗時,因此我們需要自動化的方式來產生模擬資料。
使用TFC產生模擬資料的步驟:
- 將初始化的Terraform專案儲存在GitHub帳戶中
- 建立TFC帳戶並連線到GitHub專案
- 在TFC中建立工作區並組態環境變數
- 執行「Plan only」執行以產生規格計劃
- 從執行詳情中下載Sentinel模擬資料
程式碼範例:下載Sentinel模擬資料後的專案結構
$ tree
.
├── eks.sentinel
├── mocks
│ ├── mock-tfconfig-v2.sentinel
│ ├── mock-tfconfig.sentinel
│ ├── mock-tfplan-v2.sentinel
│ ├── mock-tfplan.sentinel
│ ├── mock-tfrun.sentinel
│ ├── mock-tfstate-v2.sentinel
│ └── mock-tfstate.sentinel
├── sentinel.hcl
sentinel.hcl組態範例
mock "tfplan/v2" {
  module {
    source = "./mocks/mock-tfplan-v2.sentinel"
  }
}
policy "eks" {
  source = "./eks.sentinel"
  enforcement_level = "hard-mandatory"
  params = {
    "p_eks_version" = ["1.23"],
    "p_region" = "us-east-1",
    "p_tf_version" = "1.5.5"
  }
}
#### 內容解密:
此sentinel.hcl組態檔案定義了兩個主要部分:模擬資料和策略組態。
- mock "tfplan/v2"部分指定了模擬資料的來源路徑,用於在測試Sentinel策略時提供模擬的Terraform計劃資料。
- policy "eks"部分定義了一個名為- eks的Sentinel策略,包括其來原始檔路徑、強制執行級別以及執行時所需的引數。
 這些組態確保了Sentinel能夠正確載入模擬資料並執行指定的策略,從而實作對Terraform工件的有效驗證。
安全最佳實踐
- 使用動態提供者憑證而非靜態憑證以降低安全風險
- 在將模擬資料存入程式碼倉函式庫前進行敏感資料清理
- 妥善管理TFC工作區對雲端服務供應商的存取許可權
Sentinel策略與Terraform IaC的整合應用
Sentinel策略執行層級的解析與實踐
根據Sentinel官方檔案的描述,Sentinel提供了三種不同的策略執行層級,分別為Advisory(建議)、Soft mandatory(軟強制)以及Mandatory(強制)。這些執行層級的選擇取決於所實施控制措施的重要程度。
- 
Advisory(建議):策略允許失敗,但會向使用者顯示警告或記錄日誌。這是預設的執行層級。 - 適用於非關鍵性檢查
- 可用於提醒使用者潛在問題
 
- 
Soft mandatory(軟強制):除非指定覆寫,否則策略必須透過。 - 適用於重要但允許特例的檢查
- 需要在特定情況下進行人工審核
 
- 
Mandatory(強制):無論如何,策略都必須透過。 - 適用於關鍵性檢查
- 確保基礎架構組態的嚴格合規
 
程式碼示例:Sentinel策略基礎結構
# Sentinel策略基本結構
import "tfplan/v2" as tfplan
# 引數定義
param p_eks_version default ["1.26","1.27"]
param p_region default ["us-east-1","us-west-2"]
param p_tf_version default "1.5.5"
# 列印引數資訊
print("引數:\np_eks_version =", p_eks_version)
print("p_region =", p_region)
print("p_tf_version =", p_tf_version)
# 驗證規則定義
var_eks_version = rule {
    tfplan.variables.cluster_version.value in p_eks_version
}
var_region = rule {
    tfplan.variables.region.value in p_region
}
tf_version = rule {
    tfplan.terraform_version == p_tf_version
}
內容解密:
- 程式碼首先匯入了tfplan/v2模組,用於存取Terraform計劃的詳細資訊。
- 定義了三個引數:p_eks_version、p_region和p_tf_version,分別用於指定EKS叢集版本、區域和Terraform版本。
- 使用print陳述式輸出這些引數的值,用於除錯和驗證。
- 定義了三個驗證規則:var_eks_version、var_region和tf_version,用於檢查Terraform計劃中的相應值是否符合預期。
Sentinel策略進階應用:使用函式增強檢查能力
在編寫Sentinel策略時,除了基本的規則外,還可以使用函式來實作更複雜的邏輯。
程式碼示例:使用函式驗證EKS叢集版本
# 使用函式驗證EKS叢集版本
invalid_eks_versions = func() {
    bads = []
    eks_clusters = filter tfplan.resource_changes as _, resource_changes {
        resource_changes.type is "aws_eks_cluster" and
        resource_changes.mode is "managed" and
        (resource_changes.change.actions contains "create" or
        resource_changes.change.actions is ["update"])
    }
    
    for eks_clusters as address, e {
        if e.change.after.version not in p_eks_version {
            print("EKS叢集", address, "版本無效:", e.change.after.version)
            append(bads, address)
        }
    }
    return bads
}
main = rule {
    length(invalid_eks_versions()) is 0 and
    var_eks_version and
    var_region and
    tf_version
}
內容解密:
- 定義了一個名為invalid_eks_versions的函式,用於檢查所有受管理的EKS叢集資源。
- 使用filter表示式篩選出型別為aws_eks_cluster且處於受管理狀態的資源變更。
- 遍歷篩選出的EKS叢集資源,檢查其版本是否在允許的版本列表中。
- 如果發現版本無效的叢集,則列印警告訊息並將其地址加入到bads列表中。
- main規則檢查- invalid_eks_versions()傳回的列表是否為空,以及其他驗證規則是否透過。
Sentinel策略執行與除錯
執行Sentinel策略可以使用以下命令:
# 基本執行
$ sentinel apply
# 使用-trace引數取得詳細資訊
$ sentinel apply -trace
# 使用-json引數取得機器可讀的輸出
$ sentinel apply -json
圖表說明:Sentinel策略執行流程
  graph LR
    C[C]
    A[開始] --> B[sentinel apply]
    B --> C{是否有-trace引數?}
    C -->|是| D[輸出詳細資訊]
    C -->|否| E{是否有-json引數?}
    E -->|是| F[輸出JSON格式]
    E -->|否| G[標準輸出]
    D --> H[結束]
    F --> H
    G --> H
圖表翻譯:
此圖展示了Sentinel策略的執行流程。首先執行sentinel apply命令,然後根據是否有-trace或-json引數來決定輸出的格式。如果有-trace引數,則輸出詳細資訊;如果有-json引數,則輸出JSON格式;否則進行標準輸出。最終流程結束。
 
            