diff --git a/internal/terraform/plan.go b/internal/terraform/plan.go index 68cce4b..7edfc65 100644 --- a/internal/terraform/plan.go +++ b/internal/terraform/plan.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "io" + "strings" "text/template" tfjson "github.com/hashicorp/terraform-json" @@ -57,15 +58,18 @@ func (r ResourceChangeData) GetUnifiedDiffString() (string, error) { if err != nil { return "", fmt.Errorf("invalid resource changes (after) : %w", err) } + // Try to parse JSON string in values + replacer := strings.NewReplacer(`\n`, "\n ", `\"`, "\"") diff := difflib.UnifiedDiff{ - A: difflib.SplitLines(string(before)), - B: difflib.SplitLines(string(after)), + A: difflib.SplitLines(replacer.Replace(string(before))), + B: difflib.SplitLines(replacer.Replace(string(after))), Context: 3, } diffText, err := difflib.GetUnifiedDiffString(diff) if err != nil { return "", fmt.Errorf("failed to create diff: %w", err) } + return diffText, nil } diff --git a/internal/terraform/plan_test.go b/internal/terraform/plan_test.go index 5d16e2c..f663ceb 100644 --- a/internal/terraform/plan_test.go +++ b/internal/terraform/plan_test.go @@ -23,6 +23,7 @@ func Test_newPlanData(t *testing.T) { {name: "single_replace", wantErr: false}, {name: "all_types_mixed", wantErr: false}, {name: "aws_sample", wantErr: false}, + {name: "iam_policy", wantErr: false}, {name: "invalid_json", wantErr: true}, {name: "not_json", wantErr: true}, } @@ -56,6 +57,7 @@ func Test_render(t *testing.T) { {name: "single_replace", wantErr: false}, {name: "all_types_mixed", wantErr: false}, {name: "aws_sample", wantErr: false}, + {name: "iam_policy", wantErr: false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/test/testdata/iam_policy/expected.md b/test/testdata/iam_policy/expected.md new file mode 100644 index 0000000..6eac833 --- /dev/null +++ b/test/testdata/iam_policy/expected.md @@ -0,0 +1,20 @@ +### 0 to add, 1 to change, 0 to destroy, 0 to replace. +- change + - aws_iam_policy.test_policy +
Change details + +```diff +# aws_iam_policy.test_policy will be updated in-place +@@ -12,7 +12,8 @@ + "Action": [ + "autoscaling:Describe*", + "ec2:Describe*", +- "elasticloadbalancing:Describe*" ++ "elasticloadbalancing:Describe*", ++ "health:Describe*" + ], + "Resource": "*" + } +``` + +
diff --git a/test/testdata/iam_policy/show.json b/test/testdata/iam_policy/show.json new file mode 100644 index 0000000..54493d9 --- /dev/null +++ b/test/testdata/iam_policy/show.json @@ -0,0 +1 @@ +{"format_version":"1.0","terraform_version":"1.1.8","planned_values":{"root_module":{"resources":[{"address":"aws_iam_policy.test_policy","mode":"managed","type":"aws_iam_policy","name":"test_policy","provider_name":"registry.terraform.io/hashicorp/aws","schema_version":0,"values":{"arn":"arn:aws:iam::363188159740:policy/test_policy","description":"","id":"arn:aws:iam::363188159740:policy/test_policy","name":"test_policy","name_prefix":null,"path":"/","policy":"{\n \"Version\": \"2012-10-17\",\n \"Statement\": {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"autoscaling:Describe*\",\n \"ec2:Describe*\",\n \"elasticloadbalancing:Describe*\",\n \"health:Describe*\"\n ],\n \"Resource\": \"*\"\n }\n}\n"},"sensitive_values":{}}]}},"resource_changes":[{"address":"aws_iam_policy.test_policy","mode":"managed","type":"aws_iam_policy","name":"test_policy","provider_name":"registry.terraform.io/hashicorp/aws","change":{"actions":["update"],"before":{"arn":"arn:aws:iam::363188159740:policy/test_policy","description":"","id":"arn:aws:iam::363188159740:policy/test_policy","name":"test_policy","name_prefix":null,"path":"/","policy":"{\n \"Version\": \"2012-10-17\",\n \"Statement\": {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"autoscaling:Describe*\",\n \"ec2:Describe*\",\n \"elasticloadbalancing:Describe*\"\n ],\n \"Resource\": \"*\"\n }\n}\n"},"after":{"arn":"arn:aws:iam::363188159740:policy/test_policy","description":"","id":"arn:aws:iam::363188159740:policy/test_policy","name":"test_policy","name_prefix":null,"path":"/","policy":"{\n \"Version\": \"2012-10-17\",\n \"Statement\": {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"autoscaling:Describe*\",\n \"ec2:Describe*\",\n \"elasticloadbalancing:Describe*\",\n \"health:Describe*\"\n ],\n \"Resource\": \"*\"\n }\n}\n"},"after_unknown":{},"before_sensitive":{},"after_sensitive":{}}}],"prior_state":{"format_version":"1.0","terraform_version":"1.1.8","values":{"root_module":{"resources":[{"address":"aws_iam_policy.test_policy","mode":"managed","type":"aws_iam_policy","name":"test_policy","provider_name":"registry.terraform.io/hashicorp/aws","schema_version":0,"values":{"arn":"arn:aws:iam::363188159740:policy/test_policy","description":"","id":"arn:aws:iam::363188159740:policy/test_policy","name":"test_policy","name_prefix":null,"path":"/","policy":"{\n \"Version\": \"2012-10-17\",\n \"Statement\": {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"autoscaling:Describe*\",\n \"ec2:Describe*\",\n \"elasticloadbalancing:Describe*\"\n ],\n \"Resource\": \"*\"\n }\n}\n"},"sensitive_values":{}}]}}},"configuration":{"provider_config":{"aws":{"name":"aws","expressions":{"region":{"constant_value":"ap-northeast-1"}}}},"root_module":{"resources":[{"address":"aws_iam_policy.test_policy","mode":"managed","type":"aws_iam_policy","name":"test_policy","provider_config_key":"aws","expressions":{"name":{"constant_value":"test_policy"},"policy":{"constant_value":"{\n \"Version\": \"2012-10-17\",\n \"Statement\": {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"autoscaling:Describe*\",\n \"ec2:Describe*\",\n \"elasticloadbalancing:Describe*\",\n \"health:Describe*\"\n ],\n \"Resource\": \"*\"\n }\n}\n"}},"schema_version":0}]}}}