Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package terragrunt for openSUSE:Factory checked in at 2022-06-23 12:32:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/terragrunt (Old) and /work/SRC/openSUSE:Factory/.terragrunt.new.1548 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "terragrunt" Thu Jun 23 12:32:56 2022 rev:5 rq:984673 version:0.38.1 Changes: -------- --- /work/SRC/openSUSE:Factory/terragrunt/terragrunt.changes 2022-06-10 15:58:03.972859269 +0200 +++ /work/SRC/openSUSE:Factory/.terragrunt.new.1548/terragrunt.changes 2022-06-23 12:32:57.556378479 +0200 @@ -1,0 +2,26 @@ +Wed Jun 22 20:45:14 UTC 2022 - ka...@b1-systems.de + +- Update to version 0.38.1: + * feat: fetch dependency output from state (#2123) + * Add ability to customize SSE settings for the remote state bucket (#2157) + * Add ability to disable auto-approve (#2156) + +------------------------------------------------------------------- +Wed Jun 22 07:54:16 UTC 2022 - ka...@b1-systems.de + +- Update to version 0.38.0: + * Test against terraform 1.2 (#2147) + +------------------------------------------------------------------- +Wed Jun 22 07:50:00 UTC 2022 - ka...@b1-systems.de + +- Update to version 0.37.4: + * Make include_in_copy work for patterns containing parent folders (#2112) + +------------------------------------------------------------------- +Wed Jun 22 07:44:55 UTC 2022 - ka...@b1-systems.de + +- Update to version 0.37.3: + * feat: improve local source code download behaviour (#2006) + +------------------------------------------------------------------- Old: ---- terragrunt-0.37.2.tar.gz New: ---- terragrunt-0.38.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ terragrunt.spec ++++++ --- /var/tmp/diff_new_pack.FiZie8/_old 2022-06-23 12:32:58.404379549 +0200 +++ /var/tmp/diff_new_pack.FiZie8/_new 2022-06-23 12:32:58.408379554 +0200 @@ -19,7 +19,7 @@ %define __arch_install_post export NO_BRP_STRIP_DEBUG=true Name: terragrunt -Version: 0.37.2 +Version: 0.38.1 Release: 0 Summary: Thin wrapper for Terraform for working with multiple Terraform modules License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.FiZie8/_old 2022-06-23 12:32:58.440379595 +0200 +++ /var/tmp/diff_new_pack.FiZie8/_new 2022-06-23 12:32:58.440379595 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/gruntwork-io/terragrunt</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v0.37.2</param> + <param name="revision">v0.38.1</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> @@ -16,7 +16,7 @@ <param name="compression">gz</param> </service> <service name="go_modules" mode="disabled"> - <param name="archive">terragrunt-0.37.2.tar.gz</param> + <param name="archive">terragrunt-0.38.1.tar.gz</param> </service> </services> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.FiZie8/_old 2022-06-23 12:32:58.460379620 +0200 +++ /var/tmp/diff_new_pack.FiZie8/_new 2022-06-23 12:32:58.464379625 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/gruntwork-io/terragrunt</param> - <param name="changesrevision">9bde71bd65f55a95d5fe202b3dcadcc63c864627</param></service></servicedata> + <param name="changesrevision">47f16b7b07359fa0f5d3e511954414932ec646dc</param></service></servicedata> (No newline at EOF) ++++++ terragrunt-0.37.2.tar.gz -> terragrunt-0.38.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/.circleci/config.yml new/terragrunt-0.38.1/.circleci/config.yml --- old/terragrunt-0.37.2/.circleci/config.yml 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/.circleci/config.yml 2022-06-22 21:37:11.000000000 +0200 @@ -4,7 +4,7 @@ defaults: &defaults docker: - - image: 087285199408.dkr.ecr.us-east-1.amazonaws.com/circle-ci-test-image-base:go1.16-tf1.1-tg35.20-pck1.7 + - image: 087285199408.dkr.ecr.us-east-1.amazonaws.com/circle-ci-test-image-base:go1.17-tf1.2-tg37.4-pck1.8 version: 2.1 jobs: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/cli/args.go new/terragrunt-0.38.1/cli/args.go --- old/terragrunt-0.37.2/cli/args.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/cli/args.go 2022-06-22 21:37:11.000000000 +0200 @@ -157,11 +157,21 @@ opts.Debug = true } - envValue, envProvided := os.LookupEnv("TERRAGRUNT_PARALLELISM") - parallelism, err := parseIntArg(args, optTerragruntParallelism, envValue, envProvided, options.DEFAULT_PARALLELISM) - if err != nil { - return nil, err + opts.RunAllAutoApprove = !parseBooleanArg(args, optTerragruntNoAutoApprove, os.Getenv("TERRAGRUNT_AUTO_APPROVE") == "false") + + var parallelism int + if !opts.RunAllAutoApprove { + // When running in no-auto-approve mode, set parallelism to 1 so that interactive prompts work. + parallelism = 1 + } else { + envValue, envProvided := os.LookupEnv("TERRAGRUNT_PARALLELISM") + parsedParallelism, err := parseIntArg(args, optTerragruntParallelism, envValue, envProvided, options.DEFAULT_PARALLELISM) + if err != nil { + return nil, err + } + parallelism = parsedParallelism } + opts.Parallelism = parallelism iamRoleOpts, err := parseIAMRoleOptions(args) if err != nil { @@ -208,10 +218,10 @@ opts.IncludeDirs = includeDirs opts.ModulesThatInclude = modulesThatInclude opts.StrictInclude = strictInclude - opts.Parallelism = parallelism opts.Check = parseBooleanArg(args, optTerragruntCheck, os.Getenv("TERRAGRUNT_CHECK") == "true") opts.HclFile = filepath.ToSlash(terragruntHclFilePath) opts.AwsProviderPatchOverrides = awsProviderPatchOverrides + opts.FetchDependencyOutputFromState = parseBooleanArg(args, optTerragruntFetchDependencyOutputFromState, os.Getenv("TERRAGRUNT_FETCH_DEPENDENCY_OUTPUT_FROM_STATE") == "true") opts.JSONOut, err = parseStringArg(args, optTerragruntJSONOut, "terragrunt_rendered.json") if err != nil { return nil, err diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/cli/cli_app.go new/terragrunt-0.38.1/cli/cli_app.go --- old/terragrunt-0.37.2/cli/cli_app.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/cli/cli_app.go 2022-06-22 21:37:11.000000000 +0200 @@ -27,35 +27,37 @@ ) const ( - optTerragruntConfig = "terragrunt-config" - optTerragruntTFPath = "terragrunt-tfpath" - optTerragruntNoAutoInit = "terragrunt-no-auto-init" - optTerragruntNoAutoRetry = "terragrunt-no-auto-retry" - optNonInteractive = "terragrunt-non-interactive" - optWorkingDir = "terragrunt-working-dir" - optDownloadDir = "terragrunt-download-dir" - optTerragruntSource = "terragrunt-source" - optTerragruntSourceMap = "terragrunt-source-map" - optTerragruntSourceUpdate = "terragrunt-source-update" - optTerragruntIAMRole = "terragrunt-iam-role" - optTerragruntIAMAssumeRoleDuration = "terragrunt-iam-assume-role-duration" - optTerragruntIAMAssumeRoleSessionName = "terragrunt-iam-assume-role-session-name" - optTerragruntIgnoreDependencyErrors = "terragrunt-ignore-dependency-errors" - optTerragruntIgnoreDependencyOrder = "terragrunt-ignore-dependency-order" - optTerragruntIgnoreExternalDependencies = "terragrunt-ignore-external-dependencies" - optTerragruntIncludeExternalDependencies = "terragrunt-include-external-dependencies" - optTerragruntExcludeDir = "terragrunt-exclude-dir" - optTerragruntIncludeDir = "terragrunt-include-dir" - optTerragruntStrictInclude = "terragrunt-strict-include" - optTerragruntParallelism = "terragrunt-parallelism" - optTerragruntCheck = "terragrunt-check" - optTerragruntHCLFmt = "terragrunt-hclfmt-file" - optTerragruntDebug = "terragrunt-debug" - optTerragruntOverrideAttr = "terragrunt-override-attr" - optTerragruntLogLevel = "terragrunt-log-level" - optTerragruntStrictValidate = "terragrunt-strict-validate" - optTerragruntJSONOut = "terragrunt-json-out" - optTerragruntModulesThatInclude = "terragrunt-modules-that-include" + optTerragruntConfig = "terragrunt-config" + optTerragruntTFPath = "terragrunt-tfpath" + optTerragruntNoAutoInit = "terragrunt-no-auto-init" + optTerragruntNoAutoRetry = "terragrunt-no-auto-retry" + optTerragruntNoAutoApprove = "terragrunt-no-auto-approve" + optNonInteractive = "terragrunt-non-interactive" + optWorkingDir = "terragrunt-working-dir" + optDownloadDir = "terragrunt-download-dir" + optTerragruntSource = "terragrunt-source" + optTerragruntSourceMap = "terragrunt-source-map" + optTerragruntSourceUpdate = "terragrunt-source-update" + optTerragruntIAMRole = "terragrunt-iam-role" + optTerragruntIAMAssumeRoleDuration = "terragrunt-iam-assume-role-duration" + optTerragruntIAMAssumeRoleSessionName = "terragrunt-iam-assume-role-session-name" + optTerragruntIgnoreDependencyErrors = "terragrunt-ignore-dependency-errors" + optTerragruntIgnoreDependencyOrder = "terragrunt-ignore-dependency-order" + optTerragruntIgnoreExternalDependencies = "terragrunt-ignore-external-dependencies" + optTerragruntIncludeExternalDependencies = "terragrunt-include-external-dependencies" + optTerragruntExcludeDir = "terragrunt-exclude-dir" + optTerragruntIncludeDir = "terragrunt-include-dir" + optTerragruntStrictInclude = "terragrunt-strict-include" + optTerragruntParallelism = "terragrunt-parallelism" + optTerragruntCheck = "terragrunt-check" + optTerragruntHCLFmt = "terragrunt-hclfmt-file" + optTerragruntDebug = "terragrunt-debug" + optTerragruntOverrideAttr = "terragrunt-override-attr" + optTerragruntLogLevel = "terragrunt-log-level" + optTerragruntStrictValidate = "terragrunt-strict-validate" + optTerragruntJSONOut = "terragrunt-json-out" + optTerragruntModulesThatInclude = "terragrunt-modules-that-include" + optTerragruntFetchDependencyOutputFromState = "terragrunt-fetch-dependency-output-from-state" ) var allTerragruntBooleanOpts = []string{ @@ -67,9 +69,11 @@ optTerragruntIncludeExternalDependencies, optTerragruntNoAutoInit, optTerragruntNoAutoRetry, + optTerragruntNoAutoApprove, optTerragruntCheck, optTerragruntStrictInclude, optTerragruntDebug, + optTerragruntFetchDependencyOutputFromState, } var allTerragruntStringOpts = []string{ optTerragruntConfig, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/cli/download_source.go new/terragrunt-0.38.1/cli/download_source.go --- old/terragrunt-0.37.2/cli/download_source.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/cli/download_source.go 2022-06-22 21:37:11.000000000 +0200 @@ -126,14 +126,11 @@ // Returns true if the specified TerraformSource, of the exact same version, has already been downloaded into the // DownloadFolder. This helps avoid downloading the same code multiple times. Note that if the TerraformSource points -// to a local file path, we assume the user is doing local development and always return false to ensure the latest -// code is downloaded (or rather, copied) every single time. See the ProcessTerraformSource method for more info. +// to a local file path, a hash will be generated from the contents of the source dir. See the ProcessTerraformSource method for more info. func alreadyHaveLatestCode(terraformSource *tfsource.TerraformSource, terragruntOptions *options.TerragruntOptions) (bool, error) { - if tfsource.IsLocalSource(terraformSource.CanonicalSourceURL) || - !util.FileExists(terraformSource.DownloadDir) || + if !util.FileExists(terraformSource.DownloadDir) || !util.FileExists(terraformSource.WorkingDir) || !util.FileExists(terraformSource.VersionFile) { - return false, nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/cli/download_source_test.go new/terragrunt-0.38.1/cli/download_source_test.go --- old/terragrunt-0.37.2/cli/download_source_test.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/cli/download_source_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -21,6 +21,38 @@ "github.com/gruntwork-io/terragrunt/util" ) +func TestAlreadyHaveLatestCodeLocalFilePathWithHashNoChanges(t *testing.T) { + t.Parallel() + + canonicalUrl := fmt.Sprintf("file://%s", absPath(t, "../test/fixture-download-source/hello-world-local-hash")) + downloadDir := tmpDir(t) + defer os.Remove(downloadDir) + + copyFolder(t, "../test/fixture-download-source/download-dir-version-file-local-hash", downloadDir) + testAlreadyHaveLatestCode(t, canonicalUrl, downloadDir, true) +} + +func TestAlreadyHaveLatestCodeLocalFilePathWithHashChanged(t *testing.T) { + t.Parallel() + + canonicalUrl := fmt.Sprintf("file://%s", absPath(t, "../test/fixture-download-source/hello-world-local-hash")) + downloadDir := tmpDir(t) + defer os.Remove(downloadDir) + + copyFolder(t, "../test/fixture-download-source/download-dir-version-file-local-hash", downloadDir) + + f, err := os.OpenFile(downloadDir+"/version-file.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + // Modify content of file to simulate change + fmt.Fprintln(f, "CHANGED") + + testAlreadyHaveLatestCode(t, canonicalUrl, downloadDir, false) +} + func TestAlreadyHaveLatestCodeLocalFilePath(t *testing.T) { t.Parallel() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/cli/tfsource/types.go new/terragrunt-0.38.1/cli/tfsource/types.go --- old/terragrunt-0.37.2/cli/tfsource/types.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/cli/tfsource/types.go 2022-06-22 21:37:11.000000000 +0200 @@ -13,6 +13,8 @@ "github.com/gruntwork-io/terragrunt/errors" "github.com/gruntwork-io/terragrunt/util" + + "golang.org/x/mod/sumdb/dirhash" ) var forcedRegexp = regexp.MustCompile(`^([A-Za-z0-9]+)::(.+)$`) @@ -40,9 +42,17 @@ // string of the source URL, calculate its sha1, and base 64 encode it. For remote URLs (e.g. Git URLs), this is // based on the assumption that the scheme/host/path of the URL (e.g. git::github.com/foo/bar) identifies the module // name and the query string (e.g. ?ref=v0.0.3) identifies the version. For local file paths, there is no query string, -// so the same file path (/foo/bar) is always considered the same version. See also the encodeSourceName and -// ProcessTerraformSource methods. +// so the same file path (/foo/bar) is always considered the same version. To detect changes the file path will be hashed +// and returned as version. In case of hash error the default encoded source version will be returned. +// See also the encodeSourceName and ProcessTerraformSource methods. func (terraformSource TerraformSource) EncodeSourceVersion() string { + if IsLocalSource(terraformSource.CanonicalSourceURL) { + hash, err := dirhash.HashDir(terraformSource.CanonicalSourceURL.Path, "prefix", dirhash.DefaultHash) + if err == nil { + return hash + } + // In case of error return default source version strategy + } return util.EncodeBase64Sha1(terraformSource.CanonicalSourceURL.Query().Encode()) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/config/dependency.go new/terragrunt-0.38.1/config/dependency.go --- old/terragrunt-0.37.2/config/dependency.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/config/dependency.go 2022-06-22 21:37:11.000000000 +0200 @@ -12,6 +12,8 @@ "strings" "sync" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/s3" "github.com/hashicorp/go-getter" "github.com/hashicorp/hcl/v2" "github.com/zclconf/go-cty/cty" @@ -636,7 +638,6 @@ iamRoleOpts options.IAMRoleOptions, ) ([]byte, error) { terragruntOptions.Logger.Debugf("Detected remote state block with generate config. Resolving dependency by pulling remote state.") - // Create working directory where we will run terraform in. We will create the temporary directory in the download // directory for consistency with other file generation capabilities of terragrunt. Make sure it is cleaned up // before the function returns. @@ -655,6 +656,24 @@ return nil, err } + // To speed up dependencies processing it is possible to retrieve its output directly from the backend without init dependencies + if terragruntOptions.FetchDependencyOutputFromState { + switch backend := remoteState.Backend; backend { + case "s3": + jsonBytes, err := getTerragruntOutputJsonFromRemoteStateS3( + targetTGOptions, + remoteState, + ) + if err != nil { + return nil, err + } + terragruntOptions.Logger.Debugf("Retrieved output from %s as json: %s using s3 bucket", targetConfig, jsonBytes) + return jsonBytes, nil + default: + terragruntOptions.Logger.Errorf("FetchDependencyOutputFromState is not supported for backend %s, falling back to normal method", backend) + } + } + // Generate the backend configuration in the working dir. If no generate config is set on the remote state block, // set a temporary generate config so we can generate the backend code. if remoteState.Generate == nil { @@ -681,7 +700,55 @@ jsonString := out.Stdout jsonBytes := []byte(strings.TrimSpace(jsonString)) terragruntOptions.Logger.Debugf("Retrieved output from %s as json: %s", targetConfig, jsonString) + return jsonBytes, nil + +} + +// getTerragruntOutputJsonFromRemoteStateS3 pulls the output directly from an S3 bucket without calling Terraform +func getTerragruntOutputJsonFromRemoteStateS3( + terragruntOptions *options.TerragruntOptions, + remoteState *remote.RemoteState, +) ([]byte, error) { + terragruntOptions.Logger.Debugf("Fetching outputs directly from s3://%s/%s", remoteState.Config["bucket"], remoteState.Config["key"]) + + s3ConfigExtended, err := remote.ParseExtendedS3Config(remoteState.Config) + if err != nil { + return nil, err + } + + sessionConfig := s3ConfigExtended.GetAwsSessionConfig() + + s3Client, err := remote.CreateS3Client(sessionConfig, terragruntOptions) + if err != nil { + return nil, err + } + + result, err := s3Client.GetObject(&s3.GetObjectInput{ + Bucket: aws.String(fmt.Sprintf("%s", remoteState.Config["bucket"])), + Key: aws.String(fmt.Sprintf("%s", remoteState.Config["key"])), + }) + + if err != nil { + return nil, err + } + + defer result.Body.Close() + steateBody, err := ioutil.ReadAll(result.Body) + if err != nil { + return nil, err + } + jsonState := string(steateBody) + jsonMap := make(map[string]interface{}) + err = json.Unmarshal([]byte(jsonState), &jsonMap) + if err != nil { + return nil, err + } + jsonOutputs, err := json.Marshal(jsonMap["outputs"]) + if err != nil { + return nil, err + } + return jsonOutputs, nil } // setupTerragruntOptionsForBareTerraform sets up a new TerragruntOptions struct that can be used to run terraform diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/configstack/stack.go new/terragrunt-0.38.1/configstack/stack.go --- old/terragrunt-0.37.2/configstack/stack.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/configstack/stack.go 2022-06-22 21:37:11.000000000 +0200 @@ -68,14 +68,16 @@ stack.syncTerraformCliArgs(terragruntOptions) } - // For apply and destroy, run with auto-approve due to the co-mingling of the prompts. This is not ideal, but until - // we have a better way of handling interactivity with run-all, we take the evil of having a global prompt (managed - // in cli/cli_app.go) be the gate keeper. + // For apply and destroy, run with auto-approve (unless explicitly disabled) due to the co-mingling of the prompts. + // This is not ideal, but until we have a better way of handling interactivity with run-all, we take the evil of + // having a global prompt (managed in cli/cli_app.go) be the gate keeper. switch stackCmd { case "apply", "destroy": // to support potential positional args in the args list, we append the input=false arg after the first element, // which is the target command. - terragruntOptions.TerraformCliArgs = util.StringListInsert(terragruntOptions.TerraformCliArgs, "-auto-approve", 1) + if terragruntOptions.RunAllAutoApprove { + terragruntOptions.TerraformCliArgs = util.StringListInsert(terragruntOptions.TerraformCliArgs, "-auto-approve", 1) + } stack.syncTerraformCliArgs(terragruntOptions) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/docs/_docs/01_getting-started/supported-terraform-versions.md new/terragrunt-0.38.1/docs/_docs/01_getting-started/supported-terraform-versions.md --- old/terragrunt-0.37.2/docs/_docs/01_getting-started/supported-terraform-versions.md 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/docs/_docs/01_getting-started/supported-terraform-versions.md 2022-06-22 21:37:11.000000000 +0200 @@ -15,6 +15,7 @@ | Terraform Version | Terragrunt Version | |-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1.2.x | >= [0.38.0](https://github.com/gruntwork-io/terragrunt/releases/tag/v0.38.0) | | 1.1.x | >= [0.36.0](https://github.com/gruntwork-io/terragrunt/releases/tag/v0.36.0) | | 1.0.x | >= [0.31.0](https://github.com/gruntwork-io/terragrunt/releases/tag/v0.31.0) | | 0.15.x | >= [0.29.0](https://github.com/gruntwork-io/terragrunt/releases/tag/v0.29.0) | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/docs/_docs/04_reference/cli-options.md new/terragrunt-0.38.1/docs/_docs/04_reference/cli-options.md --- old/terragrunt-0.37.2/docs/_docs/04_reference/cli-options.md 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/docs/_docs/04_reference/cli-options.md 2022-06-22 21:37:11.000000000 +0200 @@ -449,6 +449,7 @@ - [terragrunt-tfpath](#terragrunt-tfpath) - [terragrunt-no-auto-init](#terragrunt-no-auto-init) - [terragrunt-no-auto-retry](#terragrunt-no-auto-retry) +- [terragrunt-no-auto-approve](#terragrunt-no-auto-approve) - [terragrunt-non-interactive](#terragrunt-non-interactive) - [terragrunt-working-dir](#terragrunt-working-dir) - [terragrunt-download-dir](#terragrunt-download-dir) @@ -474,7 +475,7 @@ - [terragrunt-override-attr](#terragrunt-override-attr) - [terragrunt-json-out](#terragrunt-json-out) - [terragrunt-modules-that-include](#terragrunt-modules-that-include) - +- [terragrunt-fetch-dependency-output-from-state](#terragrunt-fetch-dependency-output-from-state) ### terragrunt-config @@ -514,6 +515,18 @@ disabled. See [Auto-Init]({{site.baseurl}}/docs/features/auto-init#auto-init) +### terragrunt-no-auto-approve + +**CLI Arg**: `--terragrunt-no-auto-approve`<br/> +**Environment Variable**: `TERRAGRUNT_AUTO_APPROVE` (set to `false`) +**Commands**: +- [run-all](#run-all) + +When passed in, Terragrunt will no longer automatically append `-auto-approve` to the underlying Terraform commands run +with `run-all`. Note that due to the interactive prompts, this flag will also **automatically assume +`--terragrunt-parallelism 1`**. + + ### terragrunt-no-auto-retry **CLI Arg**: `--terragrunt-no-auto-retry`<br/> @@ -723,7 +736,6 @@ When passed in, limit the number of modules that are run concurrently to this number during *-all commands. - ### terragrunt-debug **CLI Arg**: `--terragrunt-debug`<br/> @@ -858,3 +870,12 @@ NOTE: When using relative paths, the paths are relative to the working directory. This is either the current working directory, or any path passed in to [terragrunt-working-dir](#terragrunt-working-dir). + +### terragrunt-fetch-dependency-output-from-state + +**CLI Arg**: `--terragrunt-fetch-dependency-output-from-state` +**Environment Variable**: `TERRAGRUNT_FETCH_DEPENDENCY_OUTPUT_FROM_STATE` (set to `true`) +When using many dependencies, this option can speed up the dependency processing by fetching dependency output directly +from the state file instead of init dependencies and running terraform on them. +NOTE: This is an experimental feature, use with caution. +Currently only AWS S3 backend is supported. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/docs/_docs/04_reference/config-blocks-and-attributes.md new/terragrunt-0.38.1/docs/_docs/04_reference/config-blocks-and-attributes.md --- old/terragrunt-0.37.2/docs/_docs/04_reference/config-blocks-and-attributes.md 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/docs/_docs/04_reference/config-blocks-and-attributes.md 2022-06-22 21:37:11.000000000 +0200 @@ -201,7 +201,7 @@ ".*", ] } - + # A special after hook to always run after the init-from-module step of the Terragrunt pipeline. In this case, we will # copy the "foo.tf" file located by the parent terragrunt.hcl file to the current working directory. after_hook "init_from_module" { @@ -387,7 +387,7 @@ - `skip_bucket_accesslogging`: _DEPRECATED_ If provided, will be ignored. A log warning will be issued in the console output to notify the user. - `skip_bucket_root_access`: When `true`, the S3 bucket that is created will not be configured with bucket policies that allow access to the root AWS user. - `skip_bucket_enforced_tls`: When `true`, the S3 bucket that is created will not be configured with a bucket policy that enforces access to the bucket via a TLS connection. -- `disable_bucket_update`: When `true`, disable update S3 bucket if not equal configured in config block +- `disable_bucket_update`: When `true`, disable update S3 bucket if not equal configured in config block - `enable_lock_table_ssencryption`: When `true`, the synchronization lock table in DynamoDB used for remote state concurrent access will not be configured with server side encryption. - `s3_bucket_tags`: A map of key value pairs to associate as tags on the created S3 bucket. - `dynamodb_table_tags`: A map of key value pairs to associate as tags on the created DynamoDB remote state lock table. @@ -396,6 +396,8 @@ https://github.com/gruntwork-io/terragrunt/issues/1059. - `accesslogging_bucket_name`: (Optional) When provided as a valid `string`, create an S3 bucket with this name to store the access logs for the S3 bucket used to store Terraform state. If not provided, or string is empty or invalid S3 bucket name, then server access logging for the S3 bucket storing the terraform state will be disabled. - `accesslogging_target_prefix`: (Optional) When provided as a valid `string`, set the `TargetPrefix` for the access log objects in the S3 bucket used to store Terraform state. If set to **empty**`string`, then `TargetPrefix` will be set to **empty** `string`. If attribute is not provided at all, then `TargetPrefix` will be set to **default** value `TFStateLogs/`. This attribute won't take effect if the `accesslogging_bucket_name` attribute is not present. +- `bucket_sse_algorithm`: (Optional) The algorithm to use for server side encryption of the state bucket. Defaults to `aws:kms`. +- `bucket_sse_kms_key_id`: (Optional) The KMS Key to use when the encryption algorithm is `aws:kms`. Defaults to the AWS Managed `aws/s3` key. For the `gcs` backend, the following additional properties are supported in the `config` attribute: @@ -888,16 +890,16 @@ - `mock_outputs_allowed_terraform_commands` (attribute): A list of Terraform commands for which `mock_outputs` are allowed. If a command is used where `mock_outputs` is not allowed, and no outputs are available in the target module, Terragrunt will throw an error when processing this dependency. -- `mock_outputs_merge_with_state` (attribute): DEPRECATED. Use `mock_outputs_merge_strategy_with_state`. When `true`, +- `mock_outputs_merge_with_state` (attribute): DEPRECATED. Use `mock_outputs_merge_strategy_with_state`. When `true`, `mock_outputs` and the state outputs will be merged. That is, the `mock_outputs` will be treated as defaults and the real state outputs will overwrite them if the keys clash. -- `mock_outputs_merge_strategy_with_state` (attribute): Specifies how any existing state should be merged into the +- `mock_outputs_merge_strategy_with_state` (attribute): Specifies how any existing state should be merged into the mocks. Valid values are - - `no_merge` (default) - any existing state will be used as is. If the dependency does not have an existing state (it + - `no_merge` (default) - any existing state will be used as is. If the dependency does not have an existing state (it hasn't been applied yet), then the mocks will be used - - `shallow` - the existing state will be shallow merged into the mocks. Mocks will only be used where the output does + - `shallow` - the existing state will be shallow merged into the mocks. Mocks will only be used where the output does not already exist in the dependency's state - - `deep_map_only` - the existing state will be deeply merged into the mocks. If an output is a map, the mock key + - `deep_map_only` - the existing state will be deeply merged into the mocks. If an output is a map, the mock key will be used where that key does not exist in the state. Lists will not be merged Example: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/go.mod new/terragrunt-0.38.1/go.mod --- old/terragrunt-0.37.2/go.mod 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/go.mod 2022-06-22 21:37:11.000000000 +0200 @@ -54,6 +54,7 @@ github.com/zclconf/go-cty v1.8.3 go.mozilla.org/sops/v3 v3.7.2 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 + golang.org/x/mod v0.5.1 golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/go.sum new/terragrunt-0.38.1/go.sum --- old/terragrunt-0.37.2/go.sum 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/go.sum 2022-06-22 21:37:11.000000000 +0200 @@ -979,6 +979,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/options/options.go new/terragrunt-0.38.1/options/options.go --- old/terragrunt-0.37.2/options/options.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/options/options.go 2022-06-22 21:37:11.000000000 +0200 @@ -71,6 +71,9 @@ // Whether we should automatically run terraform init if necessary when executing other commands AutoInit bool + // Whether we should automatically run terraform with -auto-apply in run-all mode. + RunAllAutoApprove bool + // CLI args that are intended for Terraform (i.e. all the CLI args except the --terragrunt ones) TerraformCliArgs []string @@ -186,6 +189,9 @@ // True if is required to show dependent modules and confirm action CheckDependentModules bool + + // This is an experimental feature, used to speed up dependency processing by getting the output from the state + FetchDependencyOutputFromState bool } // IAMOptions represents options that are used by Terragrunt to assume an IAM role. @@ -229,39 +235,41 @@ } return &TerragruntOptions{ - TerragruntConfigPath: terragruntConfigPath, - TerraformPath: TERRAFORM_DEFAULT_PATH, - OriginalTerraformCommand: "", - TerraformCommand: "", - AutoInit: true, - NonInteractive: false, - TerraformCliArgs: []string{}, - WorkingDir: workingDir, - Logger: logger, - LogLevel: defaultLogLevel, - ValidateStrict: false, - Env: map[string]string{}, - Source: "", - SourceMap: map[string]string{}, - SourceUpdate: false, - DownloadDir: downloadDir, - IgnoreDependencyErrors: false, - IgnoreDependencyOrder: false, - IgnoreExternalDependencies: false, - IncludeExternalDependencies: false, - Writer: os.Stdout, - ErrWriter: os.Stderr, - MaxFoldersToCheck: DEFAULT_MAX_FOLDERS_TO_CHECK, - AutoRetry: true, - RetryMaxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS, - RetrySleepIntervalSec: DEFAULT_RETRY_SLEEP_INTERVAL_SEC, - RetryableErrors: util.CloneStringList(DEFAULT_RETRYABLE_ERRORS), - ExcludeDirs: []string{}, - IncludeDirs: []string{}, - ModulesThatInclude: []string{}, - StrictInclude: false, - Parallelism: DEFAULT_PARALLELISM, - Check: false, + TerragruntConfigPath: terragruntConfigPath, + TerraformPath: TERRAFORM_DEFAULT_PATH, + OriginalTerraformCommand: "", + TerraformCommand: "", + AutoInit: true, + RunAllAutoApprove: true, + NonInteractive: false, + TerraformCliArgs: []string{}, + WorkingDir: workingDir, + Logger: logger, + LogLevel: defaultLogLevel, + ValidateStrict: false, + Env: map[string]string{}, + Source: "", + SourceMap: map[string]string{}, + SourceUpdate: false, + DownloadDir: downloadDir, + IgnoreDependencyErrors: false, + IgnoreDependencyOrder: false, + IgnoreExternalDependencies: false, + IncludeExternalDependencies: false, + Writer: os.Stdout, + ErrWriter: os.Stderr, + MaxFoldersToCheck: DEFAULT_MAX_FOLDERS_TO_CHECK, + AutoRetry: true, + RetryMaxAttempts: DEFAULT_RETRY_MAX_ATTEMPTS, + RetrySleepIntervalSec: DEFAULT_RETRY_SLEEP_INTERVAL_SEC, + RetryableErrors: util.CloneStringList(DEFAULT_RETRYABLE_ERRORS), + ExcludeDirs: []string{}, + IncludeDirs: []string{}, + ModulesThatInclude: []string{}, + StrictInclude: false, + Parallelism: DEFAULT_PARALLELISM, + Check: false, + FetchDependencyOutputFromState: false, RunTerragrunt: func(terragruntOptions *TerragruntOptions) error { return errors.WithStackTrace(RunTerragruntCommandNotSet) }, @@ -311,50 +319,52 @@ // during xxx-all commands (e.g., apply-all, plan-all). See https://github.com/gruntwork-io/terragrunt/issues/367 // for more info. return &TerragruntOptions{ - TerragruntConfigPath: terragruntConfigPath, - OriginalTerragruntConfigPath: terragruntOptions.OriginalTerragruntConfigPath, - TerraformPath: terragruntOptions.TerraformPath, - OriginalTerraformCommand: terragruntOptions.OriginalTerraformCommand, - TerraformCommand: terragruntOptions.TerraformCommand, - TerraformVersion: terragruntOptions.TerraformVersion, - TerragruntVersion: terragruntOptions.TerragruntVersion, - AutoInit: terragruntOptions.AutoInit, - NonInteractive: terragruntOptions.NonInteractive, - TerraformCliArgs: util.CloneStringList(terragruntOptions.TerraformCliArgs), - WorkingDir: workingDir, - Logger: util.CreateLogEntryWithWriter(terragruntOptions.ErrWriter, workingDir, terragruntOptions.LogLevel, terragruntOptions.Logger.Logger.Hooks), - LogLevel: terragruntOptions.LogLevel, - ValidateStrict: terragruntOptions.ValidateStrict, - Env: util.CloneStringMap(terragruntOptions.Env), - Source: terragruntOptions.Source, - SourceMap: terragruntOptions.SourceMap, - SourceUpdate: terragruntOptions.SourceUpdate, - DownloadDir: terragruntOptions.DownloadDir, - Debug: terragruntOptions.Debug, - OriginalIAMRoleOptions: terragruntOptions.OriginalIAMRoleOptions, - IAMRoleOptions: terragruntOptions.IAMRoleOptions, - IgnoreDependencyErrors: terragruntOptions.IgnoreDependencyErrors, - IgnoreDependencyOrder: terragruntOptions.IgnoreDependencyOrder, - IgnoreExternalDependencies: terragruntOptions.IgnoreExternalDependencies, - IncludeExternalDependencies: terragruntOptions.IncludeExternalDependencies, - Writer: terragruntOptions.Writer, - ErrWriter: terragruntOptions.ErrWriter, - MaxFoldersToCheck: terragruntOptions.MaxFoldersToCheck, - AutoRetry: terragruntOptions.AutoRetry, - RetryMaxAttempts: terragruntOptions.RetryMaxAttempts, - RetrySleepIntervalSec: terragruntOptions.RetrySleepIntervalSec, - RetryableErrors: util.CloneStringList(terragruntOptions.RetryableErrors), - ExcludeDirs: terragruntOptions.ExcludeDirs, - IncludeDirs: terragruntOptions.IncludeDirs, - ModulesThatInclude: terragruntOptions.ModulesThatInclude, - Parallelism: terragruntOptions.Parallelism, - StrictInclude: terragruntOptions.StrictInclude, - RunTerragrunt: terragruntOptions.RunTerragrunt, - AwsProviderPatchOverrides: terragruntOptions.AwsProviderPatchOverrides, - HclFile: terragruntOptions.HclFile, - JSONOut: terragruntOptions.JSONOut, - Check: terragruntOptions.Check, - CheckDependentModules: terragruntOptions.CheckDependentModules, + TerragruntConfigPath: terragruntConfigPath, + OriginalTerragruntConfigPath: terragruntOptions.OriginalTerragruntConfigPath, + TerraformPath: terragruntOptions.TerraformPath, + OriginalTerraformCommand: terragruntOptions.OriginalTerraformCommand, + TerraformCommand: terragruntOptions.TerraformCommand, + TerraformVersion: terragruntOptions.TerraformVersion, + TerragruntVersion: terragruntOptions.TerragruntVersion, + AutoInit: terragruntOptions.AutoInit, + RunAllAutoApprove: terragruntOptions.RunAllAutoApprove, + NonInteractive: terragruntOptions.NonInteractive, + TerraformCliArgs: util.CloneStringList(terragruntOptions.TerraformCliArgs), + WorkingDir: workingDir, + Logger: util.CreateLogEntryWithWriter(terragruntOptions.ErrWriter, workingDir, terragruntOptions.LogLevel, terragruntOptions.Logger.Logger.Hooks), + LogLevel: terragruntOptions.LogLevel, + ValidateStrict: terragruntOptions.ValidateStrict, + Env: util.CloneStringMap(terragruntOptions.Env), + Source: terragruntOptions.Source, + SourceMap: terragruntOptions.SourceMap, + SourceUpdate: terragruntOptions.SourceUpdate, + DownloadDir: terragruntOptions.DownloadDir, + Debug: terragruntOptions.Debug, + OriginalIAMRoleOptions: terragruntOptions.OriginalIAMRoleOptions, + IAMRoleOptions: terragruntOptions.IAMRoleOptions, + IgnoreDependencyErrors: terragruntOptions.IgnoreDependencyErrors, + IgnoreDependencyOrder: terragruntOptions.IgnoreDependencyOrder, + IgnoreExternalDependencies: terragruntOptions.IgnoreExternalDependencies, + IncludeExternalDependencies: terragruntOptions.IncludeExternalDependencies, + Writer: terragruntOptions.Writer, + ErrWriter: terragruntOptions.ErrWriter, + MaxFoldersToCheck: terragruntOptions.MaxFoldersToCheck, + AutoRetry: terragruntOptions.AutoRetry, + RetryMaxAttempts: terragruntOptions.RetryMaxAttempts, + RetrySleepIntervalSec: terragruntOptions.RetrySleepIntervalSec, + RetryableErrors: util.CloneStringList(terragruntOptions.RetryableErrors), + ExcludeDirs: terragruntOptions.ExcludeDirs, + IncludeDirs: terragruntOptions.IncludeDirs, + ModulesThatInclude: terragruntOptions.ModulesThatInclude, + Parallelism: terragruntOptions.Parallelism, + StrictInclude: terragruntOptions.StrictInclude, + RunTerragrunt: terragruntOptions.RunTerragrunt, + AwsProviderPatchOverrides: terragruntOptions.AwsProviderPatchOverrides, + HclFile: terragruntOptions.HclFile, + JSONOut: terragruntOptions.JSONOut, + Check: terragruntOptions.Check, + CheckDependentModules: terragruntOptions.CheckDependentModules, + FetchDependencyOutputFromState: terragruntOptions.FetchDependencyOutputFromState, } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/remote/remote_state_s3.go new/terragrunt-0.38.1/remote/remote_state_s3.go --- old/terragrunt-0.37.2/remote/remote_state_s3.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/remote/remote_state_s3.go 2022-06-22 21:37:11.000000000 +0200 @@ -46,6 +46,8 @@ DisableAWSClientChecksums bool `mapstructure:"disable_aws_client_checksums"` AccessLoggingBucketName string `mapstructure:"accesslogging_bucket_name"` AccessLoggingTargetPrefix string `mapstructure:"accesslogging_target_prefix"` + BucketSSEAlgorithm string `mapstructure:"bucket_sse_algorithm"` + BucketSSEKMSKeyID string `mapstructure:"bucket_sse_kms_key_id"` } // These are settings that can appear in the remote_state config that are ONLY used by Terragrunt and NOT forwarded @@ -63,6 +65,8 @@ "disable_aws_client_checksums", "accesslogging_bucket_name", "accesslogging_target_prefix", + "bucket_sse_algorithm", + "bucket_sse_kms_key_id", } // A representation of the configuration options available for S3 remote state @@ -143,7 +147,7 @@ return true, nil } - s3ConfigExtended, err := parseExtendedS3Config(remoteState.Config) + s3ConfigExtended, err := ParseExtendedS3Config(remoteState.Config) if err != nil { return false, err } @@ -235,7 +239,7 @@ // Initialize the remote state S3 bucket specified in the given config. This function will validate the config // parameters, create the S3 bucket if it doesn't already exist, and check that versioning is enabled. func (s3Initializer S3Initializer) Initialize(remoteState *RemoteState, terragruntOptions *options.TerragruntOptions) error { - s3ConfigExtended, err := parseExtendedS3Config(remoteState.Config) + s3ConfigExtended, err := ParseExtendedS3Config(remoteState.Config) if err != nil { return err } @@ -315,7 +319,7 @@ } // Parse the given map into an extended S3 config -func parseExtendedS3Config(config map[string]interface{}) (*ExtendedRemoteStateConfigS3, error) { +func ParseExtendedS3Config(config map[string]interface{}) (*ExtendedRemoteStateConfigS3, error) { var s3Config RemoteStateConfigS3 var extendedConfig ExtendedRemoteStateConfigS3 @@ -1008,16 +1012,25 @@ func EnableSSEForS3BucketWide(s3Client *s3.S3, config *ExtendedRemoteStateConfigS3, terragruntOptions *options.TerragruntOptions) error { terragruntOptions.Logger.Debugf("Enabling bucket-wide SSE on AWS S3 bucket %s", config.remoteStateConfigS3.Bucket) - // Encrypt with KMS by default accountID, err := aws_helper.GetAWSAccountID(config.GetAwsSessionConfig(), terragruntOptions) if err != nil { return errors.WithStackTrace(err) } - kmsKeyID := fmt.Sprintf("arn:aws:kms:%s:%s:alias/aws/s3", config.remoteStateConfigS3.Region, accountID) + // Encrypt with KMS by default + algorithm := s3.ServerSideEncryptionAwsKms + if config.BucketSSEAlgorithm != "" { + algorithm = config.BucketSSEAlgorithm + } + defEnc := &s3.ServerSideEncryptionByDefault{ - SSEAlgorithm: aws.String(s3.ServerSideEncryptionAwsKms), - KMSMasterKeyID: aws.String(kmsKeyID), + SSEAlgorithm: aws.String(algorithm), + } + if algorithm == s3.ServerSideEncryptionAwsKms && config.BucketSSEKMSKeyID != "" { + defEnc.KMSMasterKeyID = aws.String(config.BucketSSEKMSKeyID) + } else if algorithm == s3.ServerSideEncryptionAwsKms { + kmsKeyID := fmt.Sprintf("arn:aws:kms:%s:%s:alias/aws/s3", config.remoteStateConfigS3.Region, accountID) + defEnc.KMSMasterKeyID = aws.String(kmsKeyID) } rule := &s3.ServerSideEncryptionRule{ApplyServerSideEncryptionByDefault: defEnc} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/remote/remote_state_s3_test.go new/terragrunt-0.38.1/remote/remote_state_s3_test.go --- old/terragrunt-0.37.2/remote/remote_state_s3_test.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/remote/remote_state_s3_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -156,7 +156,7 @@ t.Run(testCase.name, func(t *testing.T) { t.Parallel() - s3ConfigExtended, err := parseExtendedS3Config(testCase.config) + s3ConfigExtended, err := ParseExtendedS3Config(testCase.config) require.Nil(t, err, "Unexpected error parsing config for test: %v", err) s3Client, err := CreateS3Client(s3ConfigExtended.GetAwsSessionConfig(), terragruntOptions) @@ -197,7 +197,7 @@ t.Run(testCase.name, func(t *testing.T) { t.Parallel() - s3ConfigExtended, err := parseExtendedS3Config(testCase.config) + s3ConfigExtended, err := ParseExtendedS3Config(testCase.config) require.Nil(t, err, "Unexpected error parsing config for test: %v", err) expected := &aws_helper.AwsSessionConfig{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/shell/ptty_unix.go new/terragrunt-0.38.1/shell/ptty_unix.go --- old/terragrunt-0.37.2/shell/ptty_unix.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/shell/ptty_unix.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package shell diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/shell/ptty_windows.go new/terragrunt-0.38.1/shell/ptty_windows.go --- old/terragrunt-0.37.2/shell/ptty_windows.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/shell/ptty_windows.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build windows // +build windows package shell diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/shell/run_shell_cmd_output_test.go new/terragrunt-0.38.1/shell/run_shell_cmd_output_test.go --- old/terragrunt-0.37.2/shell/run_shell_cmd_output_test.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/shell/run_shell_cmd_output_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build linux || darwin // +build linux darwin package shell diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/shell/run_shell_cmd_unix_test.go new/terragrunt-0.38.1/shell/run_shell_cmd_unix_test.go --- old/terragrunt-0.37.2/shell/run_shell_cmd_unix_test.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/shell/run_shell_cmd_unix_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build linux || darwin // +build linux darwin package shell diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/shell/run_shell_cmd_windows_test.go new/terragrunt-0.38.1/shell/run_shell_cmd_windows_test.go --- old/terragrunt-0.37.2/shell/run_shell_cmd_windows_test.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/shell/run_shell_cmd_windows_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build windows // +build windows package shell diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/shell/signal_unix.go new/terragrunt-0.38.1/shell/signal_unix.go --- old/terragrunt-0.37.2/shell/signal_unix.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/shell/signal_unix.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package shell diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/shell/signal_windows.go new/terragrunt-0.38.1/shell/signal_windows.go --- old/terragrunt-0.37.2/shell/signal_windows.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/shell/signal_windows.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build windows // +build windows package shell diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-download-source/download-dir-version-file-local-hash/main.tf new/terragrunt-0.38.1/test/fixture-download-source/download-dir-version-file-local-hash/main.tf --- old/terragrunt-0.37.2/test/fixture-download-source/download-dir-version-file-local-hash/main.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-download-source/download-dir-version-file-local-hash/main.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1 @@ +# Local file hash test \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-download-source/download-dir-version-file-local-hash/version-file.txt new/terragrunt-0.38.1/test/fixture-download-source/download-dir-version-file-local-hash/version-file.txt --- old/terragrunt-0.37.2/test/fixture-download-source/download-dir-version-file-local-hash/version-file.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-download-source/download-dir-version-file-local-hash/version-file.txt 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1 @@ +h1:iZ9U+r4EPyqBU2l8Ih0StqixGyMnZTNoNqSGeEMT0QI= \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-download-source/hello-world-local-hash/main.tf new/terragrunt-0.38.1/test/fixture-download-source/hello-world-local-hash/main.tf --- old/terragrunt-0.37.2/test/fixture-download-source/hello-world-local-hash/main.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-download-source/hello-world-local-hash/main.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1 @@ +# Local file hash test \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app1/main.tf new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app1/main.tf --- old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app1/main.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app1/main.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,7 @@ +terraform { + backend "s3" {} +} + +output "app1_text" { + value = "app1 output" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app1/terragrunt.hcl new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app1/terragrunt.hcl --- old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app1/terragrunt.hcl 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app1/terragrunt.hcl 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,7 @@ +include { + path = find_in_parent_folders() +} + +dependencies { + paths = ["../app3"] +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app2/main.tf new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app2/main.tf --- old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app2/main.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app2/main.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,15 @@ +terraform { + backend "s3" {} +} + +output "app1_text" { + value = var.app1_text +} + +output "app2_text" { + value = "app2 output" +} + +output "app3_text" { + value = var.app3_text +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app2/terragrunt.hcl new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app2/terragrunt.hcl --- old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app2/terragrunt.hcl 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app2/terragrunt.hcl 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,24 @@ +include { + path = find_in_parent_folders() +} + +dependency "app1" { + config_path = "../app1" + + mock_outputs = { + app1_text = "(known after apply-all)" + } +} + +dependency "app3" { + config_path = "../app3" + + mock_outputs = { + app3_text = "(known after apply-all)" + } +} + +inputs = { + app1_text = dependency.app1.outputs.app1_text + app3_text = dependency.app3.outputs.app3_text +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app2/variables.tf new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app2/variables.tf --- old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app2/variables.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app2/variables.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,7 @@ +variable "app1_text" { + type = string +} + +variable "app3_text" { + type = string +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app3/main.tf new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app3/main.tf --- old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app3/main.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app3/main.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,7 @@ +terraform { + backend "s3" {} +} + +output "app3_text" { + value = "app3 output" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app3/terragrunt.hcl new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app3/terragrunt.hcl --- old/terragrunt-0.37.2/test/fixture-output-from-remote-state/env1/app3/terragrunt.hcl 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-output-from-remote-state/env1/app3/terragrunt.hcl 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,3 @@ +include { + path = find_in_parent_folders() +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-output-from-remote-state/terragrunt.hcl new/terragrunt-0.38.1/test/fixture-output-from-remote-state/terragrunt.hcl --- old/terragrunt-0.37.2/test/fixture-output-from-remote-state/terragrunt.hcl 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-output-from-remote-state/terragrunt.hcl 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,14 @@ +# Configure Terragrunt to automatically store tfstate files in an S3 bucket +remote_state { + backend = "s3" + config = { + encrypt = true + bucket = "__FILL_IN_BUCKET_NAME__" + key = "${path_relative_to_include()}/terraform.tfstate" + region = "us-west-2" + } +} + +inputs = { + terraform_remote_state_s3_bucket = "__FILL_IN_BUCKET_NAME__" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-s3-encryption/custom-key/backend.tf new/terragrunt-0.38.1/test/fixture-s3-encryption/custom-key/backend.tf --- old/terragrunt-0.37.2/test/fixture-s3-encryption/custom-key/backend.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-s3-encryption/custom-key/backend.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,10 @@ +# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa +terraform { + backend "s3" { + bucket = "terragrunt-test-bucket-3zu6lh" + dynamodb_table = "terragrunt-test-locks-9nzzrp" + encrypt = true + key = "terraform.tfstate" + region = "us-west-2" + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-s3-encryption/custom-key/main.tf new/terragrunt-0.38.1/test/fixture-s3-encryption/custom-key/main.tf --- old/terragrunt-0.37.2/test/fixture-s3-encryption/custom-key/main.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-s3-encryption/custom-key/main.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,5 @@ +resource "null_resource" "main" {} + +output "id" { + value = null_resource.main.id +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-s3-encryption/custom-key/terragrunt.hcl new/terragrunt-0.38.1/test/fixture-s3-encryption/custom-key/terragrunt.hcl --- old/terragrunt-0.37.2/test/fixture-s3-encryption/custom-key/terragrunt.hcl 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-s3-encryption/custom-key/terragrunt.hcl 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,17 @@ +# Configure Terragrunt to automatically store tfstate files in an S3 bucket +remote_state { + backend = "s3" + generate = { + path = "backend.tf" + if_exists = "overwrite" + } + config = { + encrypt = true + bucket = "__FILL_IN_BUCKET_NAME__" + key = "terraform.tfstate" + region = "us-west-2" + dynamodb_table = "__FILL_IN_LOCK_TABLE_NAME__" + enable_lock_table_ssencryption = true + bucket_sse_kms_key_id = "alias/dedicated-test-key" + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-s3-encryption/sse-aes/backend.tf new/terragrunt-0.38.1/test/fixture-s3-encryption/sse-aes/backend.tf --- old/terragrunt-0.37.2/test/fixture-s3-encryption/sse-aes/backend.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-s3-encryption/sse-aes/backend.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,10 @@ +# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa +terraform { + backend "s3" { + bucket = "terragrunt-test-bucket-hid5kv" + dynamodb_table = "terragrunt-test-locks-xrkt1b" + encrypt = true + key = "terraform.tfstate" + region = "us-west-2" + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-s3-encryption/sse-aes/main.tf new/terragrunt-0.38.1/test/fixture-s3-encryption/sse-aes/main.tf --- old/terragrunt-0.37.2/test/fixture-s3-encryption/sse-aes/main.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-s3-encryption/sse-aes/main.tf 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,5 @@ +resource "null_resource" "main" {} + +output "id" { + value = null_resource.main.id +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/fixture-s3-encryption/sse-aes/terragrunt.hcl new/terragrunt-0.38.1/test/fixture-s3-encryption/sse-aes/terragrunt.hcl --- old/terragrunt-0.37.2/test/fixture-s3-encryption/sse-aes/terragrunt.hcl 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/fixture-s3-encryption/sse-aes/terragrunt.hcl 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,17 @@ +# Configure Terragrunt to automatically store tfstate files in an S3 bucket +remote_state { + backend = "s3" + generate = { + path = "backend.tf" + if_exists = "overwrite" + } + config = { + encrypt = true + bucket = "__FILL_IN_BUCKET_NAME__" + key = "terraform.tfstate" + region = "us-west-2" + dynamodb_table = "__FILL_IN_LOCK_TABLE_NAME__" + enable_lock_table_ssencryption = true + bucket_sse_algorithm = "AES256" + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/helpers/test_helpers_unix.go new/terragrunt-0.38.1/test/helpers/test_helpers_unix.go --- old/terragrunt-0.37.2/test/helpers/test_helpers_unix.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/test/helpers/test_helpers_unix.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package helpers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/helpers/test_helpers_windows.go new/terragrunt-0.38.1/test/helpers/test_helpers_windows.go --- old/terragrunt-0.37.2/test/helpers/test_helpers_windows.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/test/helpers/test_helpers_windows.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build windows // +build windows package helpers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/integration_s3_encryption_test.go new/terragrunt-0.38.1/test/integration_s3_encryption_test.go --- old/terragrunt-0.37.2/test/integration_s3_encryption_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.38.1/test/integration_s3_encryption_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -0,0 +1,71 @@ +package test + +import ( + "fmt" + "strings" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/s3" + terraws "github.com/gruntwork-io/terratest/modules/aws" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/gruntwork-io/terragrunt/config" +) + +const ( + s3SSEAESFixturePath = "fixture-s3-encryption/sse-aes" + s3SSECustomKeyFixturePath = "fixture-s3-encryption/custom-key" +) + +func TestTerragruntS3SSEAES(t *testing.T) { + t.Parallel() + + cleanupTerraformFolder(t, s3SSEAESFixturePath) + + s3BucketName := fmt.Sprintf("terragrunt-test-bucket-%s", strings.ToLower(uniqueId())) + lockTableName := fmt.Sprintf("terragrunt-test-locks-%s", strings.ToLower(uniqueId())) + + defer deleteS3Bucket(t, TERRAFORM_REMOTE_STATE_S3_REGION, s3BucketName) + defer cleanupTableForTest(t, lockTableName, TERRAFORM_REMOTE_STATE_S3_REGION) + + tmpTerragruntConfigPath := createTmpTerragruntConfig(t, s3SSEAESFixturePath, s3BucketName, lockTableName, config.DefaultTerragruntConfigPath) + + runTerragrunt(t, fmt.Sprintf("terragrunt apply -auto-approve --terragrunt-non-interactive --terragrunt-config %s --terragrunt-working-dir %s", tmpTerragruntConfigPath, s3SSEAESFixturePath)) + + client := terraws.NewS3Client(t, TERRAFORM_REMOTE_STATE_S3_REGION) + resp, err := client.GetBucketEncryption(&s3.GetBucketEncryptionInput{Bucket: aws.String(s3BucketName)}) + require.NoError(t, err) + require.Equal(t, 1, len(resp.ServerSideEncryptionConfiguration.Rules)) + sseRule := resp.ServerSideEncryptionConfiguration.Rules[0].ApplyServerSideEncryptionByDefault + require.NotNil(t, sseRule) + assert.Equal(t, s3.ServerSideEncryptionAes256, aws.StringValue(sseRule.SSEAlgorithm)) + assert.Nil(t, sseRule.KMSMasterKeyID) +} + +func TestTerragruntS3SSECustomKey(t *testing.T) { + t.Parallel() + + cleanupTerraformFolder(t, s3SSECustomKeyFixturePath) + + s3BucketName := fmt.Sprintf("terragrunt-test-bucket-%s", strings.ToLower(uniqueId())) + lockTableName := fmt.Sprintf("terragrunt-test-locks-%s", strings.ToLower(uniqueId())) + + defer deleteS3Bucket(t, TERRAFORM_REMOTE_STATE_S3_REGION, s3BucketName) + defer cleanupTableForTest(t, lockTableName, TERRAFORM_REMOTE_STATE_S3_REGION) + + tmpTerragruntConfigPath := createTmpTerragruntConfig(t, s3SSECustomKeyFixturePath, s3BucketName, lockTableName, config.DefaultTerragruntConfigPath) + + runTerragrunt(t, fmt.Sprintf("terragrunt apply -auto-approve --terragrunt-non-interactive --terragrunt-config %s --terragrunt-working-dir %s", tmpTerragruntConfigPath, s3SSECustomKeyFixturePath)) + + client := terraws.NewS3Client(t, TERRAFORM_REMOTE_STATE_S3_REGION) + resp, err := client.GetBucketEncryption(&s3.GetBucketEncryptionInput{Bucket: aws.String(s3BucketName)}) + require.NoError(t, err) + require.Equal(t, 1, len(resp.ServerSideEncryptionConfiguration.Rules)) + sseRule := resp.ServerSideEncryptionConfiguration.Rules[0].ApplyServerSideEncryptionByDefault + require.NotNil(t, sseRule) + assert.Equal(t, s3.ServerSideEncryptionAwsKms, aws.StringValue(sseRule.SSEAlgorithm)) + assert.True(t, strings.HasSuffix(aws.StringValue(sseRule.KMSMasterKeyID), "alias/dedicated-test-key")) + +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/integration_test.go new/terragrunt-0.38.1/test/integration_test.go --- old/terragrunt-0.37.2/test/integration_test.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/test/integration_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -57,6 +57,7 @@ TEST_FIXTURE_STACK = "fixture-stack/" TEST_FIXTURE_GRAPH_DEPENDENCIES = "fixture-graph-dependencies" TEST_FIXTURE_OUTPUT_ALL = "fixture-output-all" + TEST_FIXTURE_OUTPUT_FROM_REMOTE_STATE = "fixture-output-from-remote-state" TEST_FIXTURE_STDOUT = "fixture-download/stdout-test" TEST_FIXTURE_EXTRA_ARGS_PATH = "fixture-extra-args/" TEST_FIXTURE_ENV_VARS_BLOCK_PATH = "fixture-env-vars-block/" @@ -758,6 +759,41 @@ assert.True(t, (strings.Index(output, "app3 output") < strings.Index(output, "app1 output")) && (strings.Index(output, "app1 output") < strings.Index(output, "app2 output"))) } +func TestTerragruntOutputFromRemoteState(t *testing.T) { + t.Parallel() + + s3BucketName := fmt.Sprintf("terragrunt-test-bucket-%s", strings.ToLower(uniqueId())) + defer deleteS3Bucket(t, TERRAFORM_REMOTE_STATE_S3_REGION, s3BucketName) + + tmpEnvPath := copyEnvironment(t, TEST_FIXTURE_OUTPUT_FROM_REMOTE_STATE) + + rootTerragruntConfigPath := util.JoinPath(tmpEnvPath, TEST_FIXTURE_OUTPUT_FROM_REMOTE_STATE, config.DefaultTerragruntConfigPath) + copyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", "not-used") + + environmentPath := fmt.Sprintf("%s/%s/env1", tmpEnvPath, TEST_FIXTURE_OUTPUT_FROM_REMOTE_STATE) + + runTerragrunt(t, fmt.Sprintf("terragrunt apply --terragrunt-fetch-dependency-output-from-state --auto-approve --terragrunt-non-interactive --terragrunt-working-dir %s/app1", environmentPath)) + runTerragrunt(t, fmt.Sprintf("terragrunt apply --terragrunt-fetch-dependency-output-from-state --auto-approve --terragrunt-non-interactive --terragrunt-working-dir %s/app3", environmentPath)) + // Now delete dependencies cached state + config.ClearOutputCache() + require.NoError(t, os.Remove(filepath.Join(environmentPath, "/app1/.terraform/terraform.tfstate"))) + require.NoError(t, os.RemoveAll(filepath.Join(environmentPath, "/app1/.terraform"))) + require.NoError(t, os.Remove(filepath.Join(environmentPath, "/app3/.terraform/terraform.tfstate"))) + require.NoError(t, os.RemoveAll(filepath.Join(environmentPath, "/app3/.terraform"))) + runTerragrunt(t, fmt.Sprintf("terragrunt apply --terragrunt-fetch-dependency-output-from-state --auto-approve --terragrunt-non-interactive --terragrunt-working-dir %s/app2", environmentPath)) + var ( + stdout bytes.Buffer + stderr bytes.Buffer + ) + runTerragruntRedirectOutput(t, fmt.Sprintf("terragrunt run-all output --terragrunt-fetch-dependency-output-from-state --terragrunt-non-interactive --terragrunt-working-dir %s", environmentPath), &stdout, &stderr) + output := stdout.String() + + assert.True(t, strings.Contains(output, "app1 output")) + assert.True(t, strings.Contains(output, "app2 output")) + assert.True(t, strings.Contains(output, "app3 output")) + + assert.True(t, (strings.Index(output, "app3 output") < strings.Index(output, "app1 output")) && (strings.Index(output, "app1 output") < strings.Index(output, "app2 output"))) +} func TestTerragruntValidateAllCommand(t *testing.T) { t.Parallel() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/integration_unix_test.go new/terragrunt-0.38.1/test/integration_unix_test.go --- old/terragrunt-0.37.2/test/integration_unix_test.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/test/integration_unix_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build linux || darwin // +build linux darwin package test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/test/integration_windows_test.go new/terragrunt-0.38.1/test/integration_windows_test.go --- old/terragrunt-0.37.2/test/integration_windows_test.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/test/integration_windows_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,3 +1,4 @@ +//go:build windows // +build windows package test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/util/file.go new/terragrunt-0.38.1/util/file.go --- old/terragrunt-0.37.2/util/file.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/util/file.go 2022-06-22 21:37:11.000000000 +0200 @@ -170,6 +170,44 @@ return string(bytes), nil } +func listContainsElementWithPrefix(list []string, elementPrefix string) bool { + for _, element := range list { + if strings.HasPrefix(element, elementPrefix) { + return true + } + } + return false +} + +// Takes apbsolute glob path and returns an array of expanded relative paths +func expandGlobPath(source, absoluteGlobPath string) ([]string, error) { + includeExpandedGlobs := []string{} + absoluteExpandGlob, err := zglob.Glob(absoluteGlobPath) + if err != nil && err != os.ErrNotExist { + // we ignore not exist error as we only care about the globs that exist in the src dir + return nil, errors.WithStackTrace(err) + } + for _, absoluteExpandGlobPath := range absoluteExpandGlob { + if strings.Contains(absoluteExpandGlobPath, ".terragrunt-cache") { + continue + } + relativeExpandGlobPath, err := GetPathRelativeTo(absoluteExpandGlobPath, source) + if err != nil { + return nil, err + } + includeExpandedGlobs = append(includeExpandedGlobs, relativeExpandGlobPath) + + if IsDir(absoluteExpandGlobPath) { + dirExpandGlob, err := expandGlobPath(source, fmt.Sprintf("%s/*", absoluteExpandGlobPath)) + if err != nil { + return nil, errors.WithStackTrace(err) + } + includeExpandedGlobs = append(includeExpandedGlobs, dirExpandGlob...) + } + } + return includeExpandedGlobs, nil +} + // Copy the files and folders within the source folder into the destination folder. Note that hidden files and folders // (those starting with a dot) will be skipped. Will create a specified manifest file that contains paths of all copied files. func CopyFolderContents(source, destination, manifestFile string, includeInCopy []string) error { @@ -178,36 +216,26 @@ includeExpandedGlobs := []string{} for _, includeGlob := range includeInCopy { globPath := filepath.Join(source, includeGlob) - expandGlob, err := zglob.Glob(globPath) - if err == os.ErrNotExist { - // we ignore not exist error as we only care about the globs that exist in the src dir - continue - } else if err != nil { + expandGlob, err := expandGlobPath(source, globPath) + if err != nil { return errors.WithStackTrace(err) } - for _, expandGlobPath := range expandGlob { - if filepath.IsAbs(expandGlobPath) { - expandGlobPath, err = GetPathRelativeTo(expandGlobPath, source) - if err != nil { - return err - } - } - includeExpandedGlobs = append(includeExpandedGlobs, expandGlobPath) - } + includeExpandedGlobs = append(includeExpandedGlobs, expandGlob...) } - return CopyFolderContentsWithFilter(source, destination, manifestFile, func(path string) bool { - if ListContainsElement(includeExpandedGlobs, path) { + return CopyFolderContentsWithFilter(source, destination, manifestFile, func(absolutePath string) bool { + relativePath, err := GetPathRelativeTo(absolutePath, source) + if err == nil && listContainsElementWithPrefix(includeExpandedGlobs, relativePath) { return true } - return !TerragruntExcludes(path) + return !TerragruntExcludes(filepath.FromSlash(relativePath)) }) } // Copy the files and folders within the source folder into the destination folder. Pass each file and folder through // the given filter function and only copy it if the filter returns true. Will create a specified manifest file // that contains paths of all copied files. -func CopyFolderContentsWithFilter(source, destination, manifestFile string, filter func(path string) bool) error { +func CopyFolderContentsWithFilter(source, destination, manifestFile string, filter func(absolutePath string) bool) error { if err := os.MkdirAll(destination, 0700); err != nil { return errors.WithStackTrace(err) } @@ -234,7 +262,7 @@ return err } - if !filter(fileRelativePath) { + if !filter(file) { continue } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.37.2/util/file_test.go new/terragrunt-0.38.1/util/file_test.go --- old/terragrunt-0.37.2/util/file_test.go 2022-06-08 16:22:22.000000000 +0200 +++ new/terragrunt-0.38.1/util/file_test.go 2022-06-22 21:37:11.000000000 +0200 @@ -1,7 +1,9 @@ package util import ( + "errors" "io/ioutil" + "os" "path" "path/filepath" "testing" @@ -206,6 +208,7 @@ assert.Equal(t, testCase.expected, actual, "For path %s and subpath %s", testCase.path, testCase.subpath) } } + func TestHasPathPrefix(t *testing.T) { t.Parallel() @@ -234,3 +237,43 @@ assert.Equal(t, testCase.expected, actual, "For path %s and prefix %s", testCase.path, testCase.prefix) } } + +func TestIncludeInCopy(t *testing.T) { + includeInCopy := []string{"_module/.region2", "**/app2", "**/.include-me-too"} + + testCases := []struct { + path string + copyExpected bool + }{ + {"/app/terragrunt.hcl", true}, + {"/_module/main.tf", true}, + {"/_module/.region1/info.txt", false}, + {"/_module/.region3/project3-1/f1-2-levels.txt", false}, + {"/_module/.region3/project3-1/app1/.include-me-too/file.txt", true}, + {"/_module/.region3/project3-2/.f0/f0-3-levels.txt", false}, + {"/_module/.region2/.project2-1/app2/f2-dot-f2.txt", true}, + {"/_module/.region2/.project2-1/readme.txt", true}, + {"/_module/.region2/project2-2/f2-dot-f0.txt", true}, + } + + tempDir := t.TempDir() + source := filepath.Join(tempDir, "source") + destination := filepath.Join(tempDir, "destination") + + fileContent := []byte("source file") + for _, testCase := range testCases { + path := filepath.Join(source, testCase.path) + require.NoError(t, os.MkdirAll(filepath.Dir(path), os.ModePerm)) + require.NoError(t, os.WriteFile(path, fileContent, 0644)) + } + + require.NoError(t, CopyFolderContents(source, destination, ".terragrunt-test", includeInCopy)) + + for _, testCase := range testCases { + _, err := os.Stat(filepath.Join(destination, testCase.path)) + assert.True(t, + testCase.copyExpected && err == nil || + !testCase.copyExpected && errors.Is(err, os.ErrNotExist), + "Unexpected copy result for file '%s' (should be copied: '%t') - got error: %s", testCase.path, testCase.copyExpected, err) + } +} ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/terragrunt/vendor.tar.gz /work/SRC/openSUSE:Factory/.terragrunt.new.1548/vendor.tar.gz differ: char 4, line 1