Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Deprecating terragrunt.hcl as root #3588

Merged
merged 38 commits into from
Dec 18, 2024

Conversation

yhakbar
Copy link
Collaborator

@yhakbar yhakbar commented Nov 21, 2024

Description

Making it so that usage of a root terragrunt.hcl throws a warning for users, and gives them guidance to move to a differently named root configuration file.

TODOs

Read the Gruntwork contribution guidelines.

  • Update the docs.
  • Run the relevant tests successfully, including pre-commit checks.
  • Ensure any 3rd party code adheres with our license policy or delete this line if its not applicable.
  • Include release notes. If this PR is backward incompatible, include a migration guide.

Release Notes (draft)

Updated strict package.
Updated config package.
Updated scaffold command.
Updated catalog command.

Migration Guide

Current idiomatic usage of Terragrunt involves using a root configuration file named terragrunt.hcl.

This causes a lot of confusion for users, and potential errors. With this change, the new recommendation of naming it anything else will be enforced via the strict package.

It will likely take a very long time before this functionality can be removed, so we should start updating our documentation to reflect this change and throw warnings that users are using less reliable configurations.

@yhakbar yhakbar force-pushed the feat/deprecate-terragrunt-hcl-as-root branch 2 times, most recently from b25c288 to 4d12fbe Compare December 2, 2024 23:16
@yhakbar yhakbar force-pushed the feat/deprecate-terragrunt-hcl-as-root branch from e003d54 to 4ab39f9 Compare December 3, 2024 22:19
@yhakbar yhakbar requested a review from levkohimins as a code owner December 5, 2024 15:10
denis256
denis256 previously approved these changes Dec 6, 2024
project := os.Getenv("GOOGLE_CLOUD_PROJECT")
gcsBucketName := "terragrunt-test-bucket-" + strings.ToLower(helpers.UniqueID())
tmpTerragruntGCSConfigPath := createTmpTerragruntGCSConfig(t, testFixtureGcsParallelStateInit, project, terraformRemoteStateGcpRegion, gcsBucketName, config.DefaultTerragruntConfigPath)
tmpTerragruntGCSConfigPath := createTmpTerragruntGCSConfig(t, testFixtureGcsParallelStateInit, project, terraformRemoteStateGcpRegion, gcsBucketName, "root.hcl")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can config.RecommendedParentConfigName be used?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, but it's a pain to update them all, and I don't think it's that important. I'll look to use that constant more consistently in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Copy link
Contributor

@levkohimins levkohimins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't really need the Name field in strict.Control.

--- a/internal/strict/strict.go
+++ b/internal/strict/strict.go
@@ -21,8 +21,6 @@ import (
 // Control represents a control that can be enabled or disabled in strict mode.
 // When the control is enabled, Terragrunt will behave in a way that is not backwards compatible.
 type Control struct {
-	// Name is the name of the strict control.
-	Name string
 	// Error is the error that will be returned when the control is enabled.
 	Error error
 	// Warning is a warning that will be logged when the control is not enabled.
@@ -57,7 +55,7 @@ const (
 )
 
 // GetStrictControl returns the strict control with the given name.
-func GetStrictControl(name string) (Control, bool) {
+func GetStrictControl(name string) (*Control, bool) {
 	control, ok := StrictControls[name]
 
 	return control, ok
@@ -65,8 +63,8 @@ func GetStrictControl(name string) (Control, bool) {
 
 // Evaluate returns a warning if the control is not enabled, an indication of whether the control has already been triggered,
 // and an error if the control is enabled.
-func (control Control) Evaluate(opts *options.TerragruntOptions) (string, bool, error) {
-	_, triggered := TriggeredControls.LoadAndStore(control.Name, true)
+func (control *Control) Evaluate(opts *options.TerragruntOptions) (string, bool, error) {
+	_, triggered := TriggeredControls.LoadAndStore(control, true)
 
 	if opts.StrictMode {
 		return "", triggered, control.Error
@@ -88,73 +86,61 @@ func (control Control) Evaluate(opts *options.TerragruntOptions) (string, bool,
 	return control.Warning, triggered, nil
 }
 
-type Controls map[string]Control
+type Controls map[string]*Control
 
 //nolint:lll,gochecknoglobals,stylecheck,revive
 var StrictControls = Controls{
 	SpinUp: {
-		Name:    SpinUp,
 		Error:   errors.Errorf("The `%s` command is no longer supported. Use `terragrunt run-all apply` instead.", SpinUp),
 		Warning: fmt.Sprintf("The `%s` command is deprecated and will be removed in a future version. Use `terragrunt run-all apply` instead.", SpinUp),
 	},
 	TearDown: {
-		Name:    TearDown,
 		Error:   errors.Errorf("The `%s` command is no longer supported. Use `terragrunt run-all destroy` instead.", TearDown),
 		Warning: fmt.Sprintf("The `%s` command is deprecated and will be removed in a future version. Use `terragrunt run-all destroy` instead.", TearDown),
 	},
 	PlanAll: {
-		Name:    PlanAll,
 		Error:   errors.Errorf("The `%s` command is no longer supported. Use `terragrunt run-all plan` instead.", PlanAll),
 		Warning: fmt.Sprintf("The `%s` command is deprecated and will be removed in a future version. Use `terragrunt run-all plan` instead.", PlanAll),
 	},
 	ApplyAll: {
-		Name:    ApplyAll,
 		Error:   errors.Errorf("The `%s` command is no longer supported. Use `terragrunt run-all apply` instead.", ApplyAll),
 		Warning: fmt.Sprintf("The `%s` command is deprecated and will be removed in a future version. Use `terragrunt run-all apply` instead.", ApplyAll),
 	},
 	DestroyAll: {
-		Name:    DestroyAll,
 		Error:   errors.Errorf("The `%s` command is no longer supported. Use `terragrunt run-all destroy` instead.", DestroyAll),
 		Warning: fmt.Sprintf("The `%s` command is deprecated and will be removed in a future version. Use `terragrunt run-all destroy` instead.", DestroyAll),
 	},
 	OutputAll: {
-		Name:    OutputAll,
 		Error:   errors.Errorf("The `%s` command is no longer supported. Use `terragrunt run-all output` instead.", OutputAll),
 		Warning: fmt.Sprintf("The `%s` command is deprecated and will be removed in a future version. Use `terragrunt run-all output` instead.", OutputAll),
 	},
 	ValidateAll: {
-		Name:    ValidateAll,
 		Error:   errors.Errorf("The `%s` command is no longer supported. Use `terragrunt run-all validate` instead.", ValidateAll),
 		Warning: fmt.Sprintf("The `%s` command is deprecated and will be removed in a future version. Use `terragrunt run-all validate` instead.", ValidateAll),
 	},
 	SkipDependenciesInputs: {
-		Name:    SkipDependenciesInputs,
 		Error:   errors.Errorf("The `%s` option is deprecated. Reading inputs from dependencies has been deprecated and will be removed in a future version of Terragrunt. To continue using inputs from dependencies, forward them as outputs.", SkipDependenciesInputs),
 		Warning: fmt.Sprintf("The `%s` option is deprecated and will be removed in a future version of Terragrunt. Reading inputs from dependencies has been deprecated. To continue using inputs from dependencies, forward them as outputs.", SkipDependenciesInputs),
 	},
 	DisableLogFormatting: {
-		Name:    DisableLogFormatting,
 		Error:   errors.Errorf("The `--%s` flag is no longer supported. Use `--terragrunt-log-format=key-value` instead.", DisableLogFormatting),
 		Warning: fmt.Sprintf("The `--%s` flag is deprecated and will be removed in a future version. Use `--terragrunt-log-format=key-value` instead.", DisableLogFormatting),
 	},
 	JSONLog: {
-		Name:    JSONLog,
 		Error:   errors.Errorf("The `--%s` flag is no longer supported. Use `--terragrunt-log-format=json` instead.", JSONLog),
 		Warning: fmt.Sprintf("The `--%s` flag is deprecated and will be removed in a future version. Use `--terragrunt-log-format=json` instead.", JSONLog),
 	},
 	TfLogJSON: {
-		Name:    TfLogJSON,
 		Error:   errors.Errorf("The `--%s` flag is no longer supported. Use `--terragrunt-log-format=json` instead.", TfLogJSON),
 		Warning: fmt.Sprintf("The `--%s` flag is deprecated and will be removed in a future version. Use `--terragrunt-log-format=json` instead.", TfLogJSON),
 	},
 	RootTerragruntHCL: {
-		Name:    RootTerragruntHCL,
 		Error:   errors.Errorf("Using `terragrunt.hcl` as the root of Terragrunt configurations is an anti-pattern, and no longer supported. Use a differently named file like `root.hcl` instead. For more information, see https://terragrunt.gruntwork.io/docs/migrate/migrating-from-root-terragrunt-hcl"),
 		Warning: "Using `terragrunt.hcl` as the root of Terragrunt configurations is an anti-pattern, and no longer recommended. In a future version of Terragrunt, this will result in an error. You are advised to use a differently named file like `root.hcl` instead. For more information, see https://terragrunt.gruntwork.io/docs/migrate/migrating-from-root-terragrunt-hcl",
 	},
 }
 
-var TriggeredControls = xsync.NewMapOf[string, bool]()
+var TriggeredControls = xsync.NewMapOf[*Control, bool]()
 
 // Names returns the names of all strict controls.
 func (controls Controls) Names() []string {

@yhakbar yhakbar marked this pull request as draft December 9, 2024 21:10
@yhakbar
Copy link
Collaborator Author

yhakbar commented Dec 9, 2024

I'm moving this into draft status, as we are discussing internally on the best way to roll this out and communicate what's going to happen to Terragrunt as a consequence of this.

@yhakbar
Copy link
Collaborator Author

yhakbar commented Dec 9, 2024

You don't really need the Name field in strict.Control.

I considered this, but I wonder if it's actually better. I don't like Golang pointers as it's easy to create nil pointer exceptions, and I wouldn't want to put the whole struct in the triggered map.

Is it that bad to duplicate the name of the control in the value found by the key?

@levkohimins
Copy link
Contributor

You don't really need the Name field in strict.Control.

I considered this, but I wonder if it's actually better. I don't like Golang pointers as it's easy to create nil pointer exceptions, and I wouldn't want to put the whole struct in the triggered map.

Is it that bad to duplicate the name of the control in the value found by the key?

Not sure if it's a good idea to duplicate the same string data in the map key and field structure, I see two options:

  1. What I already suggested (I don't see anything wrong with using a pointer).
  2. Remake StrictControls from map to slice.

@yhakbar yhakbar marked this pull request as ready for review December 16, 2024 23:02
@yhakbar yhakbar requested a review from levkohimins December 16, 2024 23:45
Copy link
Contributor

@levkohimins levkohimins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some recommendations for the code.

internal/strict/strict.go Outdated Show resolved Hide resolved
cli/commands/catalog/tui/tui.go Outdated Show resolved Hide resolved
cli/commands/scaffold/action.go Outdated Show resolved Hide resolved
cli/commands/scaffold/action.go Outdated Show resolved Hide resolved
Copy link
Contributor

@levkohimins levkohimins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job!

@yhakbar yhakbar merged commit 5eba8e1 into main Dec 18, 2024
5 of 6 checks passed
@yhakbar yhakbar deleted the feat/deprecate-terragrunt-hcl-as-root branch December 18, 2024 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants