{"componentChunkName":"component---src-templates-blog-template-js","path":"/zh-Hant/blog/introducing-the-psono-terraform-provider","result":{"data":{"markdownRemark":{"html":"<h1>Psono Terraform Provider 介紹</h1>\n<p>我們很高興宣布，Psono Terraform Provider 的測試版現已在公開的\n<a href=\"https://registry.terraform.io/providers/psono/psono/latest\">Terraform Registry</a> 上提供。</p>\n<p>基礎設施團隊現在可以將個別金鑰作為 Terraform 工作流程的一部分，納入預先建立的 Psono 環境變數項目中管理。此 Provider 可以保留現有值、生成新密碼、輪換管理的值、寫入外部提供的值，並通過 Terraform 的臨時資源讀取秘密。</p>\n<h2>秘密不進 Terraform 狀態檔</h2>\n<p>在基礎設施即程式碼（Infrastructure as Code）中處理秘密時需特別小心。將敏感標誌（sensitive flag）標記值僅能防止其顯示於 CLI 輸出，但並不會阻止這個值存進 Terraform 狀態檔。Psono Provider 利用 Terraform 的僅可寫入與臨時資源能力來迴避這個問題，並需要 Terraform 1.11 以上版本。</p>\n<p>Provider 支援三種常見的工作流程：</p>\n<ul>\n<li>在 Psono 中生成一個值，但不通過受管資源返回該值。</li>\n<li>透過僅可寫入（write-only）的參數供應值，使其不會寫進計畫（plan）或狀態檔（state）。</li>\n<li>透過臨時資源讀取現有值，只傳遞給其它臨時或僅可寫入情境。</li>\n</ul>\n<p>如此可以在 Terraform 流程中安全地加入秘密生命週期管理，同時將實際值保存在 Psono 內。</p>\n<h2>限制訪問與本地加解密</h2>\n<p>本 Provider 使用受限的 Psono API 金鑰。你僅需指派 Terraform 所需的環境變數項目，並於所有操作中授予讀取權限。進行建立、更新、輪換、刪除金鑰時需額外給予寫入權限。Provider 並不需要無限制的 API 金鑰，也無法建立保險箱（vault）條目、資料夾或資料存儲（datastore）。</p>\n<p>加密和解密操作皆在 Provider 端本地進行。HTTPS 憑證驗證無法被禁用，可透過 PEM CA 包增補私有憑證授權。正式環境務必使用 HTTPS 的 Psono 服務網址。</p>\n<h2>快速開始</h2>\n<p>需要 Terraform 1.11 或更新版本。於 Terraform 設定檔中加入 Provider：</p>\n<pre><code class=\"language-hcl\">terraform {\n  required_version = \">= 1.11.0\"\n\n  required_providers {\n    psono = {\n      source  = \"psono/psono\"\n      version = \"~> 1.0\"\n    }\n  }\n}\n\nprovider \"psono\" {}\n</code></pre>\n<p>請透過環境變數設定憑證，不要將敏感資料放進 Terraform 設定檔：</p>\n<pre><code class=\"language-bash\">export PSONO_SERVER_URL='https://psono.example.com/server'\nexport PSONO_API_KEY_ID='REPLACE_WITH_API_KEY_ID'\nexport PSONO_API_SECRET_KEY='REPLACE_WITH_API_SECRET_KEY'\n</code></pre>\n<p>然後初始化當前工作目錄：</p>\n<pre><code class=\"language-bash\">terraform init\n</code></pre>\n<p>Terraform 將下載已簽章的 Provider 版本，並驗證其雜湊簽名。</p>\n<h2>生成與輪換密碼</h2>\n<p>以下資源範例用於管理既有 Psono 環境變數項目中的 <code>DB_PASSWORD</code>：</p>\n<pre><code class=\"language-hcl\">resource \"psono_environment_variable\" \"database_password\" {\n  secret_id = var.psono_environment_variables_secret_id\n  name      = \"DB_PASSWORD\"\n\n  length      = 32\n  min_lower   = 4\n  min_upper   = 4\n  min_numeric = 4\n  min_special = 4\n\n  rotation_version = 1\n}\n</code></pre>\n<p>如果金鑰已存在，Provider 會納管（adopt）其現有值，不會改變內容；若不存在，Provider 則會在 Psono 生成一個新值並儲存。所生成的值不會由受管資源返回，也不會寫入 Terraform 狀態檔。</p>\n<p>當你希望 Terraform 生成替換值時，請遞增 <code>rotation_version</code>。這也會置換原本納管或匯入的值，因此進行輪換變更前請仔細審查。</p>\n<h2>寫入外部提供的值</h2>\n<p>可用於臨時密碼等，從其他 Provider 取得值並以 <code>value_wo</code> 寫入 Psono：</p>\n<pre><code class=\"language-hcl\">ephemeral \"random_password\" \"database\" {\n  length = 32\n}\n\nresource \"psono_environment_variable\" \"database_password\" {\n  secret_id        = var.psono_environment_variables_secret_id\n  name             = \"DB_PASSWORD\"\n  value_wo         = ephemeral.random_password.database.result\n  value_wo_version = 1\n}\n</code></pre>\n<p>該值僅於 Terraform 操作期間可用，不會寫進 Plan 或狀態檔。欲讓 Terraform 覆寫新值，請遞增 <code>value_wo_version</code>。</p>\n<h2>預設安全保留</h2>\n<p>銷毀（destroy）受管資源時，預設會保留其在 Psono 的金鑰，以保護 Terraform 僅納管（adopt）但未建立的值。僅於確定要從 Psono 移除金鑰（例如資源銷毀或替換時），才需設定 <code>deletion_policy = \"Delete\"</code>。</p>\n<h2>現已開放</h2>\n<p>本 Provider 為開源專案且現已可用：</p>\n<ul>\n<li><a href=\"https://registry.terraform.io/providers/psono/psono/latest\">從 Terraform Registry 安裝 Provider</a></li>\n<li><a href=\"https://doc.psono.com/user/developer/terraform-provider.html\">閱讀 Psono Terraform Provider 使用指南</a></li>\n<li><a href=\"https://gitlab.com/esaqa/psono/psono-terraform-provider\">在 GitLab 上瀏覽原始碼</a></li>\n</ul>\n<p>這個測試版專注於環境變數項目與受限的 API 金鑰，使權限控制精準、避免無限制的保險箱存取，並為 Terraform 安全納管營運秘密奠定實用基礎。</p>","frontmatter":{"date":"August 22, 2026","slug":"introducing-the-psono-terraform-provider","title":"Psono Terraform Provider 介紹","description":"直接從 Terraform 管理在 Psono 中生成、僅可寫入和臨時性的值，無需將秘密儲存在 Terraform 狀態中。","author":"Sascha Pfeiffer","featuredImage":null}}},"pageContext":{"slug":"introducing-the-psono-terraform-provider","lang":"zh-Hant","langPathPrefix":"/zh-Hant"}},"staticQueryHashes":["2149092236","3128451518","3192060438"]}