-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* WIP - feat: Adding strict package * feat: Adding strict package * feat: Removing default on/off control. It just complicates things. * feat: Documenting Strict Mode * fix: Addressing markdownlint errors * fix: Addressing lints * fix: Blindly do what Levko says to do * fix: Incorporate review feedback * fix: Fixing docs for redesigned implementation * fix: Fixing bug in implementation. * fix: Cleaning up strict implementation * fix: Markdown linting * fix: Revert change to README * fix: Adding integration tests
- Loading branch information
Showing
9 changed files
with
454 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
--- | ||
layout: collection-browser-doc | ||
title: Strict Mode | ||
category: reference | ||
categories_url: reference | ||
excerpt: >- | ||
Opt-in to strict mode to avoid deprecated features and ensure your code is future-proof. | ||
tags: ["CLI"] | ||
order: 404 | ||
nav_title: Documentation | ||
nav_title_link: /docs/ | ||
--- | ||
|
||
Terragrunt supports operating in a mode referred to as "Strict Mode". | ||
|
||
Strict Mode is a set of controls that can be enabled to ensure that your Terragrunt usage is future-proof | ||
by making deprecated features throw errors instead of warnings. This can be useful when you want to ensure | ||
that your Terragrunt code is up-to-date with the latest conventions to avoid breaking changes in | ||
future versions of Terragrunt. | ||
|
||
Whenever possible, Terragrunt will initially provide you with a warning when you use a deprecated feature, without throwing an error. | ||
However, in Strict Mode, these warnings will be converted to errors, which will cause the Terragrunt command to fail. | ||
|
||
## Controlling Strict Mode | ||
|
||
The simplest way to enable strict mode is to set the `TERRAGRUNT_STRICT_MODE` environment variable to `true`. | ||
|
||
This will enable strict mode for all Terragrunt commands, for all strict mode controls. | ||
|
||
```bash | ||
$ terragrunt plan-all | ||
15:26:08.585 WARN The `plan-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all plan` instead. | ||
``` | ||
|
||
```bash | ||
$ TERRAGRUNT_STRICT_MODE='true' tg plan-all | ||
15:26:23.685 ERROR The `plan-all` command is no longer supported. Use `terragrunt run-all plan` instead. | ||
``` | ||
|
||
Instead of setting this environment variable, you can also enable strict mode for specific controls by setting the `TERRAGRUNT_STRICT_CONTROL` | ||
environment variable to a value that's specific to a particular strict control. | ||
This can allow you to gradually increase your confidence in the future compatibility of your Terragrunt usage. | ||
|
||
```bash | ||
$ TERRAGRUNT_STRICT_CONTROL='apply-all' terragrunt plan-all | ||
15:26:08.585 WARN The `plan-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all plan` instead. | ||
``` | ||
|
||
```bash | ||
$ TERRAGRUNT_STRICT_CONTROL='plan-all' terragrunt plan-all | ||
15:26:23.685 ERROR The `plan-all` command is no longer supported. Use `terragrunt run-all plan` instead. | ||
``` | ||
|
||
You can also enable multiple strict controls at once with a comma delimited list. | ||
|
||
```bash | ||
$ TERRAGRUNT_STRICT_CONTROL='plan-all,apply-all' bash -c 'terragrunt plan-all; terragrunt apply-all' | ||
15:26:46.521 ERROR The `plan-all` command is no longer supported. Use `terragrunt run-all plan` instead. | ||
15:26:46.521 ERROR Unable to determine underlying exit code, so Terragrunt will exit with error code 1 | ||
15:26:46.564 ERROR The `apply-all` command is no longer supported. Use `terragrunt run-all apply` instead. | ||
15:26:46.564 ERROR Unable to determine underlying exit code, so Terragrunt will exit with error code 1 | ||
``` | ||
|
||
## Strict Mode Controls | ||
|
||
The following strict mode controls are available: | ||
|
||
- [spin-up](#spin-up) | ||
- [tear-down](#tear-down) | ||
- [plan-all](#plan-all) | ||
- [apply-all](#apply-all) | ||
- [destroy-all](#destroy-all) | ||
- [output-all](#output-all) | ||
- [validate-all](#validate-all) | ||
|
||
### spin-up | ||
|
||
Throw an error when using the `spin-up` command. | ||
|
||
**Reason**: The `spin-up` command is deprecated and will be removed in a future version. Use `terragrunt run-all apply` instead. | ||
|
||
### tear-down | ||
|
||
Throw an error when using the `tear-down` command. | ||
|
||
**Reason**: The `tear-down` command is deprecated and will be removed in a future version. Use `terragrunt run-all destroy` instead. | ||
|
||
### plan-all | ||
|
||
Throw an error when using the `plan-all` command. | ||
|
||
**Reason**: The `plan-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all plan` instead. | ||
|
||
### apply-all | ||
|
||
Throw an error when using the `apply-all` command. | ||
|
||
**Reason**: The `apply-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all apply` instead. | ||
|
||
### destroy-all | ||
|
||
Throw an error when using the `destroy-all` command. | ||
|
||
**Reason**: The `destroy-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all destroy` instead. | ||
|
||
### output-all | ||
|
||
Throw an error when using the `output-all` command. | ||
|
||
**Reason**: The `output-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all output` instead. | ||
|
||
### validate-all | ||
|
||
Throw an error when using the `validate-all` command. | ||
|
||
**Reason**: The `validate-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all validate` instead. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// Package strict provides utilities used by Terragrunt to support a "strict" mode. | ||
// By default strict mode is disabled, but when enabled, any breaking changes | ||
// to Terragrunt behavior that is not backwards compatible will result in an error. | ||
// | ||
// Note that any behavior outlined here should be documented in /docs/_docs/04_reference/strict-mode.md | ||
// | ||
// That is how users will know what to expect when they enable strict mode, and how to customize it. | ||
package strict | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
|
||
"github.com/gruntwork-io/terragrunt/options" | ||
) | ||
|
||
// 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 { | ||
// 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. | ||
Warning string | ||
} | ||
|
||
const ( | ||
// SpinUp is the control that prevents the deprecated `spin-up` command from being used. | ||
SpinUp = "spin-up" | ||
// TearDown is the control that prevents the deprecated `tear-down` command from being used. | ||
TearDown = "tear-down" | ||
// PlanAll is the control that prevents the deprecated `plan-all` command from being used. | ||
PlanAll = "plan-all" | ||
// ApplyAll is the control that prevents the deprecated `apply-all` command from being used. | ||
ApplyAll = "apply-all" | ||
// DestroyAll is the control that prevents the deprecated `destroy-all` command from being used. | ||
DestroyAll = "destroy-all" | ||
// OutputAll is the control that prevents the deprecated `output-all` command from being used. | ||
OutputAll = "output-all" | ||
// ValidateAll is the control that prevents the deprecated `validate-all` command from being used. | ||
ValidateAll = "validate-all" | ||
) | ||
|
||
// GetStrictControl returns the strict control with the given name. | ||
func GetStrictControl(name string) (Control, bool) { | ||
control, ok := StrictControls[name] | ||
|
||
return control, ok | ||
} | ||
|
||
// Evaluate returns a warning if the control is not enabled, and an error if the control is enabled. | ||
func (control Control) Evaluate(opts *options.TerragruntOptions) (string, error) { | ||
if opts.StrictMode { | ||
return "", control.Error | ||
} | ||
|
||
for _, controlName := range opts.StrictControls { | ||
strictControl, ok := StrictControls[controlName] | ||
if !ok { | ||
// This should never happen, but if it does, it's a bug in Terragrunt. | ||
// The slice of StrictControls should be validated before they're used. | ||
return "", errors.New("Invalid strict control: " + controlName) | ||
} | ||
|
||
if strictControl == control { | ||
return "", control.Error | ||
} | ||
} | ||
|
||
return control.Warning, nil | ||
} | ||
|
||
type Controls map[string]Control | ||
|
||
//nolint:lll,gochecknoglobals,stylecheck | ||
var StrictControls = Controls{ | ||
SpinUp: { | ||
Error: errors.New("The `spin-up` command is no longer supported. Use `terragrunt run-all apply` instead."), | ||
Warning: "The `spin-up` command is deprecated and will be removed in a future version. Use `terragrunt run-all apply` instead.", | ||
}, | ||
TearDown: { | ||
Error: errors.New("The `tear-down` command is no longer supported. Use `terragrunt run-all destroy` instead."), | ||
Warning: "The `tear-down` command is deprecated and will be removed in a future version. Use `terragrunt run-all destroy` instead.", | ||
}, | ||
PlanAll: { | ||
Error: errors.New("The `plan-all` command is no longer supported. Use `terragrunt run-all plan` instead."), | ||
Warning: "The `plan-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all plan` instead.", | ||
}, | ||
ApplyAll: { | ||
Error: errors.New("The `apply-all` command is no longer supported. Use `terragrunt run-all apply` instead."), | ||
Warning: "The `apply-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all apply` instead.", | ||
}, | ||
DestroyAll: { | ||
Error: errors.New("The `destroy-all` command is no longer supported. Use `terragrunt run-all destroy` instead."), | ||
Warning: "The `destroy-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all destroy` instead.", | ||
}, | ||
OutputAll: { | ||
Error: errors.New("The `output-all` command is no longer supported. Use `terragrunt run-all output` instead."), | ||
Warning: "The `output-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all output` instead.", | ||
}, | ||
ValidateAll: { | ||
Error: errors.New("The `validate-all` command is no longer supported. Use `terragrunt run-all validate` instead."), | ||
Warning: "The `validate-all` command is deprecated and will be removed in a future version. Use `terragrunt run-all validate` instead.", | ||
}, | ||
} | ||
|
||
func (controls Controls) ValidateControlNames(strictControlNames []string) error { | ||
invalidControls := []string{} | ||
|
||
for _, controlName := range strictControlNames { | ||
_, ok := controls[controlName] | ||
if !ok { | ||
invalidControls = append(invalidControls, controlName) | ||
} | ||
} | ||
|
||
if len(invalidControls) > 0 { | ||
return errors.New("Invalid strict controls: " + strings.Join(invalidControls, ", ")) | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.