iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0

Pre-commit 工具篇介紹

Pre-commit 工具是一種用於代碼版本控制的工具,它的主要作用是在提交代碼到 Git Repository 之前自動運行一系列預先定義的檢查和操作。這些檢查和操作可以包括代碼格式化、靜態代碼分析、單元測試、安全性檢查等等。

使用 pre-commit 工具有許多好處,以下是一些好處:

  • 程式碼質量和一致性:通過在提交之前運行代碼檢查,可以確保代碼符合一致的風格和質量標準。這有助於防止代碼庫中出現格式不一致或低質量的代碼。
  • 自動化檢查:pre-commit 工具自動運行檢查,減少了開發人員手動執行各種檢查的工作量。這可以提高開發效率並減少人為錯誤。
  • 防止不良提交:通過在提交之前運行檢查,可以防止不良代碼提交到 Git Repository 中。這有助於確保代碼庫的穩定性和可維護性。
  • 客製化:您可以根據不同專案定義自己需要的 pre-commit hooks,以滿足特定的代碼檢查和流程要求。
  • 團隊協作:pre-commit 工具有助於確保團隊成員之間的代碼一致性,降低了合並沖突和代碼審查中的問題數量。
  • 安全性:您可以設置 pre-commit hooks 來運行安全性檢查,以檢測潛在的安全漏洞或惡意代碼,這有助於提高程式碼的安全性。

如何安裝 Pre-commit

  1. 打開 Terminal 程式,並輸入以下指令来安装 Pre-commit:
$ brew install pre-commit tflint tfsec checkov
  1. 於 Terraform 專案目錄下建立一 .pre-commit-config.yaml 檔案,並貼上以下內容:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v4.4.0 # Get the latest from: https://github.com/pre-commit/pre-commit-hooks/releases
  hooks:
    - id: check-yaml
    - id: check-merge-conflict
    - id: detect-aws-credentials
    - id: end-of-file-fixer
      exclude: (checkov.outputs/results_cli.txt)
    - id: trailing-whitespace
- repo: https://github.com/gruntwork-io/pre-commit
  rev: v0.1.22 # Get the latest from: https://github.com/gruntwork-io/pre-commit/releases
  hooks:
    - id: tflint
      args:
      - "--module"
      - "--config=.tflint.hcl"
      - "--filter=modules/*"
    - id: terraform-validate
      exclude: 'modules/.*'
    - id: terraform-fmt
- repo: git://github.com/antonbabenko/pre-commit-terraform
  rev: v1.83.4 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases
  hooks:
    - id: terraform_tfsec
      args:
        -  --args=--exclude=__GIT_WORKING_DIR__/modules/.*
    - id: terraform_docs
    - id: terraform_checkov
      args:
        - "--args=--output-file __GIT_WORKING_DIR__/checkov.outputs --skip-path __GIT_WORKING_DIR__/configs --skip-path __GIT_WORKING_DIR__/modules/my_karpenter/cloudformation.yaml --skip-path __GIT_WORKING_DIR__/my-ingress-node-red.yaml"

  1. 於 Terraform 專案目錄下建立一 .tflint.hcl 檔案,並貼上以下內容:
plugin "aws" {
    enabled = true
    version = "0.27.0"
    source  = "github.com/terraform-linters/tflint-ruleset-aws"
}

  1. 於 Terraform 專案目錄下,輸入以下指令来初始化 Pre-commit:
$ pre-commit install
pre-commit installed at .git/hooks/pre-commit

常用的 Pre-commit 工具 for Terraform 專案

  1. check-yaml: 用於檢查 YAML 文件的語法和格式是否正確。它會幫助您捕獲並防止在提交之前包含無效的 YAML 文件,這有助於確保配置文件等 YAML 文件的正確性。
  2. check-merge-conflict: 用於檢查是否存在沖突的合並標記(merge conflict markers)。沖突標記通常出現在合並程式碼時,表示兩個不同的分支在同一區域內發生了沖突。這個鉤子的作用是確保在提交之前沒有未解決的合並沖突,以維護程式碼資料庫的一致性和乾淨性。
  3. detect-aws-credentials: 用於檢測程式碼中是否包含 AWS Credentials,例如 Access Key 和 Secret Key。它可以幫助防止在程式碼中意外泄露敏感的 AWS Credentials 資訊,進而而提高程式的安全性。
  4. end-of-file-fixer: 用於確保源程式碼檔案的結尾處包含了換行符(newline character),有助於保持源程式碼檔案的一致性,並確保它們符合通常的檔案結尾規範。
  5. trailing-whitespace: 用於檢測程式碼檔案末尾是否包含了多餘的空格或Tab,它有助於確保程式碼的格式一致性,防止不必要的空白字符干擾程式碼的可讀性和版本控制。
  6. tflint: 用於運行 TFLint,它是一個用於檢查 Terraform 程式碼的靜態分析工具。TFLint 可以捕獲潛在的問題和錯誤,例如資源配置錯誤、不安全的配置等,通過在提交之前運行它,可以提高 Terraform 程式碼的質量和安全性。
  7. terraform-validate: 用於運行 Terraform 的 validate 命令,檢查 Terraform 配置文件的語法和有效性,這有助於確保 Terraform 程式碼符合正確的語法和規範。
  8. terraform_tfsec: 用於運行 tfsec,它是一個用於檢查 Terraform 程式碼的安全性的工具。tfsec 可以識別和警告潛在的安全風險和漏洞,例如不安全的訪問控制規則或未加密的敏感資料,這有助於確保 Terraform 配置的安全性。
  9. terraform_docs: 用於自動生成 Terraform 文件檔,以確保 Terraform 模組和資源的文件檔是最新和一致的,這有助於改善 Terraform 程式碼的可讀性和可維護性,並為其他開發人員提供了有關如何使用 Terraform 代碼的信息。
  10. checkov: 用於運行 Checkov,這是一個用於檢查基礎設施即程式碼(IaC)的安全性和合規性的工具。Checkov 可以識別和修復雲基礎設施中的安全漏洞和合規性問題,通過在提交之前運行 Checkov,可以提高 IaC 代碼的安全性和合規性。
    • 設定中將會把 Checkov 的結果輸出到目錄 checkov.outputs 可以方便查找。
    - repo: git://github.com/antonbabenko/pre-commit-terraform
    hooks:
    ...
    - id: checkov
      args: [--output-file, 'checkov.outputs', --skip-path, 'configs']
  • 如果發生出現 Checkov FAILED 的以下錯誤訊息,確認之後可以暫時忽略這個檢查,於程式碼中加上 checkov:skip= 設定。
    錯誤訊息輸出
  Check: CKV_AWS_38: "Ensure Amazon EKS public endpoint not accessible to 0.0.0.0/0"
        FAILED for resource: module.eks.aws_eks_cluster.eks_cluster
        File: /modules/my_eks/eks_cluster.tf:1-24
        Calling File: /main.tf:289-363
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/aws-policies/aws-kubernetes-policies/bc-aws-kubernetes-1.html

                1  | resource "aws_eks_cluster" "eks_cluster" {
                2  |   # checkov:skip=CKV_AWS_39: "Ensure Amazon EKS public endpoint disabled"
                3  |   # checkov:skip=CKV_AWS_81: "Ensure MSK Cluster encryption in rest and transit is enabled"
                4  | 
                5  |   name                      = var.cluster_name
                6  |   enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
                7  |   role_arn                  = var.cluster_role_arn
                8  | 
                9  |   vpc_config {
                10 |     endpoint_private_access = var.endpoint_private_access
                11 |     public_access_cidrs     = var.public_access_cidrs
                12 |     subnet_ids              = concat(var.public_subnets, var.private_subnets)
                13 |   }
                14 | 
                15 |   version = var.eks_version
                16 | 
                17 |   tags = {
                18 |     Name = var.cluster_name
                19 |   }
                20 | 
                21 |   depends_on = [
                22 |     var.cluster_role_arn
                23 |   ]
                24 | }

加上忽略檢查設定

  resource "aws_eks_cluster" "eks_cluster" {
  # checkov:skip=CKV_AWS_38: "Ensure Amazon EKS public endpoint not accessible to 0.0.0.0/0"
  # checkov:skip=CKV_AWS_39: "Ensure Amazon EKS public endpoint disabled"
  # checkov:skip=CKV_AWS_81: "Ensure MSK Cluster encryption in rest and transit is enabled"

  name                      = var.cluster_name
  enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
  role_arn                  = var.cluster_role_arn

  vpc_config {
    endpoint_private_access = var.endpoint_private_access
    public_access_cidrs     = var.public_access_cidrs
    subnet_ids              = concat(var.public_subnets, var.private_subnets)
  }

  version = var.eks_version

  tags = {
    Name = var.cluster_name
  }

  depends_on = [
    var.cluster_role_arn
  ]
}

data "tls_certificate" "certificate" {
  url = aws_eks_cluster.eks_cluster.identity[0].oidc[0].issuer
}

resource "aws_iam_openid_connect_provider" "oidc_provider" {
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = [data.tls_certificate.certificate.certificates[0].sha1_fingerprint]
  url             = aws_eks_cluster.eks_cluster.identity[0].oidc[0].issuer
}

下一篇將介紹如何 Code Review for Terrafor 執行計畫 by Atlantis。


上一篇
實作 AWS 常用服務之 Terraform 模組系列 - Route53 篇
下一篇
如何 Code Review for Terraform 執行計畫 by Atlantis
系列文
大家都在用 Terraform 實作 IaC 為什麼不將程式寫得更簡潔易讀呢?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言