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 PlaygroundHashiCorp 也提供了 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
    }
}

內容解密:

  1. 匯入 Terraform 模組:Sentinel 策略匯入了 Terraform 模組,以便存取 Terraform 計劃中的資源資訊。
  2. 主規則:定義了 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管理時,我們需要了解四個關鍵的工件:

  1. tfplan:二進位檔案,包含Terraform維護狀態的計劃(建立、讀取、更新或刪除目標環境中的IaC資源)
  2. tfconfig:包含專案中所有.tf檔案的資料(提供者、資源、資料來源、模組和變數)
  3. tfstate:Terraform維護和讀取的基礎設施狀態記錄(在事件發生後記錄,如Terraform應用)
  4. tfrun:包含在TFC中或連線到TFC的Terraform執行的執行資料(包含後設資料和環境資訊)

這些工件對於瞭解Terraform的操作至關重要,同時也是Sentinel PaC驗證的基礎。

模擬資料的重要性

在開發和測試Sentinel政策時,我們需要模擬真實的Terraform工件資料。手動建立模擬資料容易出錯且耗時,因此我們需要自動化的方式來產生模擬資料。

使用TFC產生模擬資料的步驟:

  1. 將初始化的Terraform專案儲存在GitHub帳戶中
  2. 建立TFC帳戶並連線到GitHub專案
  3. 在TFC中建立工作區並組態環境變數
  4. 執行「Plan only」執行以產生規格計劃
  5. 從執行詳情中下載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組態檔案定義了兩個主要部分:模擬資料和策略組態。

  1. mock "tfplan/v2"部分指定了模擬資料的來源路徑,用於在測試Sentinel策略時提供模擬的Terraform計劃資料。
  2. policy "eks"部分定義了一個名為eks的Sentinel策略,包括其來原始檔路徑、強制執行級別以及執行時所需的引數。
    這些組態確保了Sentinel能夠正確載入模擬資料並執行指定的策略,從而實作對Terraform工件的有效驗證。

安全最佳實踐

  1. 使用動態提供者憑證而非靜態憑證以降低安全風險
  2. 在將模擬資料存入程式碼倉函式庫前進行敏感資料清理
  3. 妥善管理TFC工作區對雲端服務供應商的存取許可權

Sentinel策略與Terraform IaC的整合應用

Sentinel策略執行層級的解析與實踐

根據Sentinel官方檔案的描述,Sentinel提供了三種不同的策略執行層級,分別為Advisory(建議)、Soft mandatory(軟強制)以及Mandatory(強制)。這些執行層級的選擇取決於所實施控制措施的重要程度。

  1. Advisory(建議):策略允許失敗,但會向使用者顯示警告或記錄日誌。這是預設的執行層級。

    • 適用於非關鍵性檢查
    • 可用於提醒使用者潛在問題
  2. Soft mandatory(軟強制):除非指定覆寫,否則策略必須透過。

    • 適用於重要但允許特例的檢查
    • 需要在特定情況下進行人工審核
  3. 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
}

內容解密:

  1. 程式碼首先匯入了tfplan/v2模組,用於存取Terraform計劃的詳細資訊。
  2. 定義了三個引數:p_eks_versionp_regionp_tf_version,分別用於指定EKS叢集版本、區域和Terraform版本。
  3. 使用print陳述式輸出這些引數的值,用於除錯和驗證。
  4. 定義了三個驗證規則:var_eks_versionvar_regiontf_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
}

內容解密:

  1. 定義了一個名為invalid_eks_versions的函式,用於檢查所有受管理的EKS叢集資源。
  2. 使用filter表示式篩選出型別為aws_eks_cluster且處於受管理狀態的資源變更。
  3. 遍歷篩選出的EKS叢集資源,檢查其版本是否在允許的版本列表中。
  4. 如果發現版本無效的叢集,則列印警告訊息並將其地址加入到bads列表中。
  5. 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格式;否則進行標準輸出。最終流程結束。