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

Stack: clean #3871

Merged
merged 8 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions cli/commands/stack/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package stack

import (
"context"
"os"
"path/filepath"

runall "github.com/gruntwork-io/terragrunt/cli/commands/run-all"
Expand All @@ -21,17 +22,17 @@ const (

// RunGenerate runs the stack command.
func RunGenerate(ctx context.Context, opts *options.TerragruntOptions) error {
if !opts.Experiments.Evaluate(experiment.Stacks) {
return cli.NewExitError(errors.New("stacks experiment is not enabled use --experiment stacks to enable it"), cli.ExitCodeGeneralError)
if err := checkStackExperiment(opts); err != nil {
return err
}

return generateStack(ctx, opts)
}

// Run execute stack command.
func Run(ctx context.Context, opts *options.TerragruntOptions) error {
if !opts.Experiments.Evaluate(experiment.Stacks) {
return cli.NewExitError(errors.New("stacks experiment is not enabled use --experiment stacks to enable it"), cli.ExitCodeGeneralError)
if err := checkStackExperiment(opts); err != nil {
return err
}

if err := RunGenerate(ctx, opts); err != nil {
Expand All @@ -45,8 +46,8 @@ func Run(ctx context.Context, opts *options.TerragruntOptions) error {

// RunOutput stack output.
func RunOutput(ctx context.Context, opts *options.TerragruntOptions, index string) error {
if !opts.Experiments.Evaluate(experiment.Stacks) {
return cli.NewExitError(errors.New("stacks experiment is not enabled use --experiment stacks to enable it"), cli.ExitCodeGeneralError)
if err := checkStackExperiment(opts); err != nil {
return err
}

// collect outputs
Expand Down Expand Up @@ -77,3 +78,28 @@ func RunOutput(ctx context.Context, opts *options.TerragruntOptions, index strin

return nil
}

// RunClean cleans the stack directory
func RunClean(_ context.Context, opts *options.TerragruntOptions) error {
if err := checkStackExperiment(opts); err != nil {
return err
}

baseDir := filepath.Join(opts.WorkingDir, stackDir)
opts.Logger.Debugf("Cleaning stack directory: %s", baseDir)
err := os.RemoveAll(baseDir)

if err != nil {
return errors.Errorf("failed to clean stack directory: %s %w", baseDir, err)
}

return nil
}

func checkStackExperiment(opts *options.TerragruntOptions) error {
if !opts.Experiments.Evaluate(experiment.Stacks) {
return cli.NewExitError(errors.New("stacks experiment is not enabled use --experiment stacks to enable it"), cli.ExitCodeGeneralError)
}

return nil
}
20 changes: 14 additions & 6 deletions cli/commands/stack/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ const (
JSONFormatFlagName = "json"
RawFormatFlagName = "raw"

generate = "generate"
run = "run"
output = "output"
generateCommandName = "generate"
runCommandName = "run"
outputCommandName = "output"
cleanCommandName = "clean"

rawOutputFormat = "raw"
jsonOutputFormat = "json"
Expand Down Expand Up @@ -61,22 +62,22 @@ func NewCommand(opts *options.TerragruntOptions) *cli.Command {
Flags: NewFlags(opts, nil).Sort(),
Subcommands: cli.Commands{
&cli.Command{
Name: generate,
Name: generateCommandName,
Usage: "Generate a stack from a terragrunt.stack.hcl file",
Action: func(ctx *cli.Context) error {
return RunGenerate(ctx.Context, opts.OptionsFromContext(ctx))

},
},
&cli.Command{
Name: run,
Name: runCommandName,
Usage: "Run a command on the stack generated from the current directory",
Action: func(ctx *cli.Context) error {
return Run(ctx.Context, opts.OptionsFromContext(ctx))
},
},
&cli.Command{
Name: output,
Name: outputCommandName,
Usage: "Run fetch stack output",
Action: func(ctx *cli.Context) error {
index := ""
Expand All @@ -86,6 +87,13 @@ func NewCommand(opts *options.TerragruntOptions) *cli.Command {
return RunOutput(ctx.Context, opts.OptionsFromContext(ctx), index)
},
},
&cli.Command{
Name: cleanCommandName,
Usage: "Clean the stack generated from the current directory",
Action: func(ctx *cli.Context) error {
return RunClean(ctx.Context, opts.OptionsFromContext(ctx))
},
},
},
Action: cli.ShowCommandHelp,
}
Expand Down
7 changes: 6 additions & 1 deletion docs/_docs/04_reference/02-cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ Before executing the specified command, the `terragrunt stack run *` command wil
the `.terragrunt-stack` directory using the `terragrunt.stack.hcl` configuration file.
This ensures that all units are up-to-date before running the requested operation.

#### output
#### stack output

The `terragrunt stack output` command allows users to retrieve and interact with outputs from multiple units within a Terragrunt stack.
This feature simplifies handling infrastructure outputs by consolidating them into a single view.
Expand Down Expand Up @@ -494,6 +494,11 @@ $ terragrunt stack output --format raw project1_app2.data
app2
```

#### stack clean

Running `terragrunt stack clean` removes the `.terragrunt-stack` directory, which is generated by the `terragrunt stack generate`
or `terragrunt stack run` commands. This can be useful when you need to remove generated configurations or troubleshoot issues.

### info

Emits limited terragrunt information to stdout in JSON format.
Expand Down
17 changes: 17 additions & 0 deletions test/integration_stacks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,23 @@ func TestStacksApplyRemote(t *testing.T) {
validateStackDir(t, path)
}

func TestStacksApplyClean(t *testing.T) {
t.Parallel()

helpers.CleanupTerraformFolder(t, testFixtureStacksInputs)
tmpEnvPath := helpers.CopyEnvironment(t, testFixtureStacksInputs)
rootPath := util.JoinPath(tmpEnvPath, testFixtureStacksInputs)

helpers.RunTerragrunt(t, "terragrunt stack run apply --experiment stacks --terragrunt-non-interactive --terragrunt-working-dir "+rootPath)
path := util.JoinPath(rootPath, ".terragrunt-stack")
// check that path exists
assert.DirExists(t, path)

helpers.RunTerragrunt(t, "terragrunt stack clean --experiment stacks --terragrunt-working-dir "+rootPath)
// check that path don't exist
assert.NoDirExists(t, path)
}

func TestStacksDestroy(t *testing.T) {
t.Parallel()

Expand Down