hashicorp / hashicorp/nomad

Render JSON String Diffs as JSON

Open
#18,103 12 comments 0 reactions 0 assignees Claimed by @vipulbhasin23 View on GitHub
stage/accepted type/enhancement
Dominant language
Go
Stars
17k
Forks
2.1k
Avg merge
1d 9h
Merged PRs (30d)
105

Description

### Proposal
In Terraform `plan` and `apply` diff output, when [a string evaluated looks like JSON](https://github.com/hashicorp/terraform/blob/4b2b34929de1f93f02804fddf2432984c62d1514/internal/command/jsonformat/computed/renderers/string.go#L32-L40), the [renderer calls a function `renderStringDiffAsJson` which pretty-prints the output](https://github.com/hashicorp/terraform/blob/4b2b34929de1f93f02804fddf2432984c62d1514/internal/command/jsonformat/computed/renderers/primitive.go#L189).

It would be lovely to have available to Nomad the same capability for understanding diffs of pre-rendered JSON blocks, for when rendering via `jsonencode` is impractical. This would serve to reduce human errors when evaluating the correctness of `plan` outputs.

### Use-cases
Job specifications which render out JSON can be difficult to evaluate in a `plan`. Take for example this change, which changes a setting `maxConnectionAge` from `60s` to `30s` in an inline JSON template:

```
+/- Job: "boulder-nonce"
+/- Task Group: "nonce" (1 canary, 1 ignore)
+/- Task: "boulder-nonce" (forces create/destroy update)
+/- Template {
ChangeMode: "restart"
ChangeSignal: ""
DestPath: "${NOMAD_TASK_DIR}/nonce.json"
+/- EmbeddedTmpl: "{\n \"NonceService\": {\n \"maxUsed\": {{ key \"service/nonce/maxUsed\" | parseInt }},\n \"noncePrefix\": \"{{ slice (env \"NOMAD_ADDR_grpc\" | sha256Hex) 0 4 | toUpper }}\",\n \"debugAddr\": \"{{ env \"NOMAD_ADDR_debug\" }}\",\n \"grpc\": {\n \"address\": \"{{ env \"NOMAD_ADDR_grpc\" }}\",\n \"maxConnectionAge\": \"60s\",\n \"services\": {\n \"nonce.NonceService\": {\n \"clientNames\": {{ key \"service/nonce/clientNames\" }}\n },\n \"grpc.health.v1.Health\": {\n \"clientNames\": [\n \"ifn-worker.{{ env \"meta.le_env_service\" }}\"\n ]\n }\n }\n },\n \"tls\": {\n \"caCertFile\": \"secrets/nonce/ca-cert.pem\",\n \"certFile\": \"secrets/nonce/cert.pem\",\n \"keyFile\": \"secrets/nonce/key.pem\"\n },\n \"syslog\": {{ keyOrDefault \"service/nonce/syslog\" \"{}\" }}\n }\n}\n" => "{\n \"NonceService\": {\n \"maxUsed\": {{ key \"service/nonce/maxUsed\" | parseInt }},\n \"noncePrefix\": \"{{ slice (env \"NOMAD_ADDR_grpc\" | sha256Hex) 0 4 | toUpper }}\",\n \"debugAddr\": \"{{ env \"NOMAD_ADDR_debug\" }}\",\n \"grpc\": {\n \"address\": \"{{ env \"NOMAD_ADDR_grpc\" }}\",\n \"maxConnectionAge\": \"30s\",\n \"services\": {\n \"nonce.NonceService\": {\n \"clientNames\": {{ key \"service/nonce/clientNames\" }}\n },\n \"grpc.health.v1.Health\": {\n \"clientNames\": [\n \"ifn-worker.{{ env \"meta.le_env_service\" }}\"\n ]\n }\n }\n },\n \"tls\": {\n \"caCertFile\": \"secrets/nonce/ca-cert.pem\",\n \"certFile\": \"secrets/nonce/cert.pem\",\n \"keyFile\": \"secrets/nonce/key.pem\"\n },\n \"syslog\": {{ keyOrDefault \"service/nonce/syslog\" \"{}\" }}\n }\n}\n"
Envvars: "false"
ErrMissingKey: "false"
LeftDelim: "{{"
Perms: "0644"
RightDelim: "}}"
SourcePath: ""
Splay: "30000000000"
VaultGrace: "0"
}
Task: "generate-shutdown-helper"

```

### Attempted Solutions

It's possible to externally decode the `A => B` syntax into a diff, though complicated by embedded consul template statements. By comparison, Terraform's rendering makes such a diff immediately human-readable.

An optimal solution is to not inline JSON, but rather use native HCL structures and the `jsonencode` tool. However, that can be difficult when still relying on runtime lookups or consul templates. So for codebases that are still migrating, JSON rendering would reduce human errors while validating `plan` output.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reviewing Terraform's referenced internal/command/jsonformat/computed/renderers/string.go and primitive.go implementations, then trace Nomad's plan and apply diff output entry points. Done means pre-rendered JSON strings produce human-readable structured diffs without breaking embedded Consul template statements; linked pull request 28298 indicates work is already underway.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.