Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[Bug] 0-bootstrap: essentialcontacts.managed.allowedContactDomains parameters are double-encoded (organization.tf jsonencode()s the JSON string from platform_policy.yaml) — the post-migration apply fails

クローズ 初心者向け
#256 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 3 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
88/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
google-cloud, terraform

調査の方向性

fast/stages-aw/0-bootstrap/organization.tf:139 と fast/stages-aw/0-bootstrap/data/custom-org-policies/platform_policy.yaml:101 のパラメータ値から始め、Stage の custom-org-policies パスを modules/organization-se/organization-policies.tf:72-74 と比較します。docs/ddg.md にある 2 回目の Stage 0 の apply で再現し、terraform plan に二重エンコードが表示されなくなり、essentialcontacts.managed.allowedContactDomains の apply が成功することを確認します。

索引モデルが issue の本文から書いたものです。

説明

Bug Level of Effort - Low Priority - High

Bug Description

Since PR #210 (7a326393, first shipped in v4.0.0) the managed constraint's parameters in fast/stages-aw/0-bootstrap/data/custom-org-policies/platform_policy.yaml:101 are written as a JSON string:

essentialcontacts.managed.allowedContactDomains:
  rules:
  - enforce: true
    parameters: '{"allowedDomains":["@${domain_name}"]}'

The stage renders that file with templatefile and formalizes each rule in 0-bootstrap/organization.tf:139:

parameters = try(jsonencode(r.parameters), null)

jsonencode of a value that is already a JSON string produces a JSON string literal — "{\"allowedDomains\":[\"@example.com\"]}" — not the object. The provider's google_org_policy_policy validates spec.rules.parameters as JSON (a string literal is valid JSON), so terraform plan accepts it, and the apply fails when the provider unmarshals the value into a map:

Error: json: cannot unmarshal string into Go value of type map[string]interface {}

  with module.organization.google_org_policy_policy.default["essentialcontacts.managed.allowedContactDomains"],
  on ../../../modules/organization-se/organization-policies.tf line 105, in resource "google_org_policy_policy" "default":

Because organization.tf:325 applies org policies only once bootstrap_user is unset (org_policies = var.bootstrap_user != null ? null : local.org_policies), the failure lands on the second Stage 0 apply — the one docs/ddg.md runs after the state migration and import.sh — on every deployment that follows the guide. Where the policy already exists (an organization redeployed under a new prefix), terraform plan shows it "updated in-place" from the object to the string literal, which is the clearest way to see the double encoding:

~ parameters = jsonencode(
      {
        - allowedDomains = [
            - "@example.com",
          ]
      }
  ) -> "\"{\\\"allowedDomains\\\":[\\\"@example.com\\\"]}\""

The module's own factory path (modules/organization-se/organization-policies.tf:72-74) passes templatestring(r.parameters, …) through untouched; only the stage's custom-org-policies path applies jsonencode. The essential-contacts policy is the only entry in the tree with a parameters key, so nothing else is affected.

Environment and Deployment Context

  • Stellar Engine Version/Commit: v4.0.0 (6d7d08c0); the same two lines on main (20830097, 2026-09-18). Introduced by PR #210 (2026-08-31). Provider hashicorp/google v6.50.0.
  • Deployment Type:
    • US Region Restricted (e.g., Access Policy constraint)
    • FedRAMP Moderate
    • FedRAMP High
    • DoD IL4
    • DoD IL5
    • Stand-alone / Custom
  • FAST Stage (if applicable):
    • Stage 0 (Bootstrap)
    • Stage 1 (Resource Management)
    • Stage 2 (Networking)
    • Stage 3 (Security)

Steps to Reproduce

  1. Follow docs/ddg.md through Stage 0: the first terraform apply -var bootstrap_user=…, the state migration, ./import.sh.
  2. terraform apply (the "one more time" apply of the guide).
  3. Observe the error above on google_org_policy_policy.default["essentialcontacts.managed.allowedContactDomains"]. In an organization where the policy already exists, terraform plan first shows the in-place update from the object to the string literal.

Expected Behavior

The second Stage 0 apply completes, and the policy is set with parameters = {"allowedDomains": ["@<domain>"]} — the outcome PR #210 intended for #108.

Actual Behavior

The apply fails; the policy is not set (fresh organization) or is left as it was (redeployment). The rest of the stage's org policies apply.

Relevant Logs and Errors

See above.

Additional Context

  • Fix, either form (one line): organization.tf:139 → parameters = try(r.parameters, null); or keep the jsonencode and write the YAML value as a map, parameters: {allowedDomains: ["@${domain_name}"]}, which is presumably what the jsonencode was written for. The first form was verified on a live deployment: terraform plan then reports no change to the policy.
  • Related: #108 / PR #210 (the parameters were added to fix contacts being blocked org-wide); this report is about how they are encoded, not whether they are present.
主要言語
HCL
スター
55
フォーク
21
平均マージ
1日 22時間
マージ済み PR(30日)
24

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

google/stellar-engine のほかの issue

google/stellar-engine の issue をすべて見る

似ている issue

Cloud の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。