atmos icon indicating copy to clipboard operation
atmos copied to clipboard

Add test to show random struct key sorting in backend config

Open joe-niland opened this issue 3 years ago • 4 comments

what

  • adding a (rough) test that demonstrates randomly changing terraform.backend.s3 key order in backend config file generation

why

  • We’ve noticed that backend.tf.json constantly changes the order of the keys within the s3 element. From what I can tell it’s due to go iterating over struct keys using a random order.

references

  • N/A

test output

❯ make testacc TEST=github.com/cloudposse/atmos/pkg/utils
go get
go test github.com/cloudposse/atmos/pkg/utils -v  -timeout 2m
=== RUN   TestBackendConfig
    json_utils_test.go:65: 
                Error Trace:    /Users/joe/git-proj/cloudposse/atmos/pkg/utils/json_utils_test.go:65
                Error:          Not equal: 
                                expected: "{\"terraform\":{\"backend\":{\"s3\":{\"encrypt\":true,\"key\":\"terraform.tfstate\",\"region\":\"us-east-1\",\"role_arn\":null,\"workspace_key_prefix\":\"app\",\"acl\":\"bucket-owner-full-control\",\"bucket\":\"sts-gbl-tfstate-backend\",\"dynamodb_table\":\"sts-gbl-tfstate-backend-lock\"}}}}"
                                actual  : "{\"terraform\":{\"backend\":{\"s3\":{\"dynamodb_table\":\"cp-ue2-root-tfstate-lock\",\"profile\":\"cp-gb2-root-tfstate\",\"role_arn\":null,\"workspace_key_prefix\":\"test-test-component\",\"region\":\"us-east-2\",\"acl\":\"bucket-owner-full-control\",\"bucket\":\"cp-ue2-root-tfstate\",\"encrypt\":true,\"key\":\"terraform.tfstate\"}}}}"
                            
                                Diff:
                                --- Expected
                                +++ Actual
                                @@ -1 +1 @@
                                -{"terraform":{"backend":{"s3":{"encrypt":true,"key":"terraform.tfstate","region":"us-east-1","role_arn":null,"workspace_key_prefix":"app","acl":"bucket-owner-full-control","bucket":"sts-gbl-tfstate-backend","dynamodb_table":"sts-gbl-tfstate-backend-lock"}}}}
                                +{"terraform":{"backend":{"s3":{"dynamodb_table":"cp-ue2-root-tfstate-lock","profile":"cp-gb2-root-tfstate","role_arn":null,"workspace_key_prefix":"test-test-component","region":"us-east-2","acl":"bucket-owner-full-control","bucket":"cp-ue2-root-tfstate","encrypt":true,"key":"terraform.tfstate"}}}}
                Test:           TestBackendConfig
--- FAIL: TestBackendConfig (0.06s)
FAIL
FAIL    github.com/cloudposse/atmos/pkg/utils   0.404s
FAIL
make: *** [testacc] Error 1

❯ make testacc TEST=github.com/cloudposse/atmos/pkg/utils
go get
go test github.com/cloudposse/atmos/pkg/utils -v  -timeout 2m
=== RUN   TestBackendConfig
    json_utils_test.go:65: 
                Error Trace:    /Users/joe/git-proj/cloudposse/atmos/pkg/utils/json_utils_test.go:65
                Error:          Not equal: 
                                expected: "{\"terraform\":{\"backend\":{\"s3\":{\"encrypt\":true,\"key\":\"terraform.tfstate\",\"region\":\"us-east-1\",\"role_arn\":null,\"workspace_key_prefix\":\"app\",\"acl\":\"bucket-owner-full-control\",\"bucket\":\"sts-gbl-tfstate-backend\",\"dynamodb_table\":\"sts-gbl-tfstate-backend-lock\"}}}}"
                                actual  : "{\"terraform\":{\"backend\":{\"s3\":{\"workspace_key_prefix\":\"test-test-component\",\"encrypt\":true,\"role_arn\":null,\"dynamodb_table\":\"cp-ue2-root-tfstate-lock\",\"key\":\"terraform.tfstate\",\"profile\":\"cp-gb2-root-tfstate\",\"region\":\"us-east-2\",\"acl\":\"bucket-owner-full-control\",\"bucket\":\"cp-ue2-root-tfstate\"}}}}"
                            
                                Diff:
                                --- Expected
                                +++ Actual
                                @@ -1 +1 @@
                                -{"terraform":{"backend":{"s3":{"encrypt":true,"key":"terraform.tfstate","region":"us-east-1","role_arn":null,"workspace_key_prefix":"app","acl":"bucket-owner-full-control","bucket":"sts-gbl-tfstate-backend","dynamodb_table":"sts-gbl-tfstate-backend-lock"}}}}
                                +{"terraform":{"backend":{"s3":{"workspace_key_prefix":"test-test-component","encrypt":true,"role_arn":null,"dynamodb_table":"cp-ue2-root-tfstate-lock","key":"terraform.tfstate","profile":"cp-gb2-root-tfstate","region":"us-east-2","acl":"bucket-owner-full-control","bucket":"cp-ue2-root-tfstate"}}}}
                Test:           TestBackendConfig
--- FAIL: TestBackendConfig (0.04s)
FAIL
FAIL    github.com/cloudposse/atmos/pkg/utils   0.241s
FAIL
make: *** [testacc] Error 1

joe-niland avatar Jul 07 '22 23:07 joe-niland

We discussed this in the sweetops slack community (thread)

Here are the current options to solve this issue for you

  1. We make backend.tf.json generation deterministic in atmos
  2. Workaround: You can add backend.tf.json to a .gitignore and allow atmos to do its thing (provided no one needs to run terraform without atmos)
  3. Workaround: You can hard code the backend for all terraform modules and disable atmos from generating the backend.tf.json

For option 1, to make this deterministic, we have some more options

  1. Use a library (see thread https://github.com/golang/go/issues/27179)
    • https://github.com/tidwall/gjson
    • https://github.com/ake-persson/mapslice-json
  2. Use a custom json Marshaller
  3. Sort the keys manually and then write them to a file

nitrocode avatar Jul 08 '22 00:07 nitrocode

@nitrocode thanks for the great summary! Closing.

joe-niland avatar Jul 17 '22 01:07 joe-niland

It would be nice to keep this open or at least create an issue to track this so we can fix it in the future

nitrocode avatar Jul 17 '22 01:07 nitrocode

@nitrocode that's true. I'll rewrite it to describe the issue a bit better.

joe-niland avatar Jul 17 '22 01:07 joe-niland

@joe-niland this was fixed in the last merged PR, atmos release 1.5.0

https://github.com/cloudposse/atmos/pull/189/files#diff-873ae70d0bd7f36db36e19041297b6a195f93676374b57ac1687eeba4b043cffR24

I'll close this PR for now, please reopen if any issues

aknysh avatar Sep 07 '22 17:09 aknysh

@joe-niland this was fixed in the last merged PR, atmos release 1.5.0

Thanks for letting me know @aknysh ! Glad you found a solution.

joe-niland avatar Sep 07 '22 20:09 joe-niland