Skip to content

Commit 38290d5

Browse files
authored
Merge branch 'main' into 4211/fix/setting-correct-exit-code-for-validate
2 parents 1a9fb1d + 594134b commit 38290d5

File tree

15 files changed

+273
-27
lines changed

15 files changed

+273
-27
lines changed

.github/cloud-nuke/config.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
s3:
2+
timeout: 10m
3+
include:
4+
names_regex:
5+
- "^terragrunt-test-bucket-[a-zA-Z0-9]{6}.*"

.github/workflows/cloud-nuke.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Daily Cloud Nuke
2+
on:
3+
schedule:
4+
- cron: "0 0 * * *" # Runs every day at midnight UTC
5+
workflow_dispatch:
6+
7+
8+
permissions:
9+
id-token: write
10+
contents: read
11+
12+
jobs:
13+
run_cloud_nuke:
14+
name: Nuke
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Install cloud-nuke
21+
run: |
22+
wget -O /usr/local/bin/cloud-nuke \
23+
--header="Authorization: Bearer ${GITHUB_TOKEN}" \
24+
"https://github.com/gruntwork-io/cloud-nuke/releases/download/v${VERSION}/cloud-nuke_linux_amd64"
25+
26+
chmod +x /usr/local/bin/cloud-nuke
27+
env:
28+
# Authenticate to reduce the likelihood of hitting rate limit issues.
29+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
VERSION: 0.40.0
31+
32+
- name: Authenticate to AWS
33+
uses: aws-actions/configure-aws-credentials@v4
34+
with:
35+
role-to-assume: ${{ secrets.CLOUD_NUKE_ROLE }}
36+
aws-region: us-east-1
37+
38+
- name: Run cloud-nuke
39+
run: |
40+
cloud-nuke aws \
41+
--force \
42+
--log-level debug \
43+
--resource-type s3 \
44+
--region us-east-1 \
45+
--region us-west-2 \
46+
--older-than 24h \
47+
--config .github/cloud-nuke/config.yml

.github/workflows/markdownlint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
uses: actions/checkout@v4
1717

1818
- name: Run markdownlint
19-
uses: DavidAnson/markdownlint-cli2-action@v19
19+
uses: DavidAnson/markdownlint-cli2-action@v20
2020
with:
2121
globs: |
2222
docs/**/*.md

.github/workflows/pages.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- name: Checkout
2929
uses: actions/checkout@v4
3030
- name: Setup Ruby
31-
uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.0
31+
uses: ruby/setup-ruby@cb0fda56a307b8c78d38320cd40d9eb22a3bf04e # v1.242.0
3232
with:
3333
ruby-version: '3.3'
3434
bundler-cache: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ mocks/
1818
.terragrunt-stack
1919
.devcontainer.json
2020
.cursor/
21+
.env

.markdownlint-cli2.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ config:
44

55
# Disable multiple headers with the same content
66
MD024: false
7+
8+
# Disable requirement for descriptive links (e.g. allow click [here]())
9+
MD059: false

cli/commands/run/cli.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22
package run
33

44
import (
5+
"context"
6+
"path/filepath"
57
"strings"
68

79
"github.com/gruntwork-io/go-commons/collections"
810
"github.com/gruntwork-io/terragrunt/cli/commands/common/graph"
911
"github.com/gruntwork-io/terragrunt/cli/commands/common/runall"
12+
"github.com/gruntwork-io/terragrunt/config"
1013
"github.com/gruntwork-io/terragrunt/internal/cli"
14+
"github.com/gruntwork-io/terragrunt/internal/errors"
1115
"github.com/gruntwork-io/terragrunt/options"
16+
"github.com/gruntwork-io/terragrunt/telemetry"
1217
"github.com/gruntwork-io/terragrunt/tf"
1318
)
1419

@@ -42,6 +47,7 @@ func NewCommand(opts *options.TerragruntOptions) *cli.Command {
4247

4348
cmd = runall.WrapCommand(opts, cmd, Run)
4449
cmd = graph.WrapCommand(opts, cmd, Run)
50+
cmd = wrapWithStackGenerate(opts, cmd)
4551

4652
return cmd
4753
}
@@ -96,3 +102,42 @@ func validateCommand(opts *options.TerragruntOptions) error {
96102
func isTerraformPath(opts *options.TerragruntOptions) bool {
97103
return strings.HasSuffix(opts.TerraformPath, options.TerraformDefaultPath)
98104
}
105+
106+
// wrapWithStackGenerate wraps a CLI command to handle automatic stack generation.
107+
// It generates a stack configuration file when running terragrunt with --all or --graph flags,
108+
// unless explicitly disabled with --no-stack-generate.
109+
func wrapWithStackGenerate(opts *options.TerragruntOptions, cmd *cli.Command) *cli.Command {
110+
// Wrap the command's action to inject stack generation logic
111+
cmd = cmd.WrapAction(func(ctx *cli.Context, action cli.ActionFunc) error {
112+
// Determine if stack generation should occur based on command flags
113+
// Stack generation is triggered by --all or --graph flags, unless --no-stack-generate is set
114+
shouldGenerateStack := (opts.RunAll || opts.Graph) && !opts.NoStackGenerate
115+
116+
// Skip stack generation if not needed
117+
if !shouldGenerateStack {
118+
opts.Logger.Debugf("Skipping stack generation in %s", opts.WorkingDir)
119+
return action(ctx)
120+
}
121+
122+
// Set the stack config path to the default location in the working directory
123+
opts.TerragruntStackConfigPath = filepath.Join(opts.WorkingDir, config.DefaultStackFile)
124+
125+
// Generate the stack configuration with telemetry tracking
126+
err := telemetry.TelemeterFromContext(ctx).Collect(ctx, "stack_generate", map[string]any{
127+
"stack_config_path": opts.TerragruntStackConfigPath,
128+
"working_dir": opts.WorkingDir,
129+
}, func(ctx context.Context) error {
130+
return config.GenerateStacks(ctx, opts)
131+
})
132+
133+
// Handle any errors during stack generation
134+
if err != nil {
135+
return errors.Errorf("failed to generate stack file: %w", err)
136+
}
137+
138+
// Execute the original command action after successful stack generation
139+
return action(ctx)
140+
})
141+
142+
return cmd
143+
}

cli/commands/run/flags.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const (
3838
SourceMapFlagName = "source-map"
3939
SourceUpdateFlagName = "source-update"
4040

41+
NoStackGenerate = "no-stack-generate"
42+
4143
// Assume IAM Role flags.
4244

4345
IAMAssumeRoleFlagName = "iam-assume-role"
@@ -119,6 +121,15 @@ func NewFlags(opts *options.TerragruntOptions, prefix flags.Prefix) cli.Flags {
119121
},
120122
flags.WithDeprecatedName(terragruntPrefix.FlagName("graph-root"), terragruntPrefixControl)),
121123

124+
// `--all` and `--graph` related flags.
125+
126+
flags.NewFlag(&cli.BoolFlag{
127+
Name: NoStackGenerate,
128+
EnvVars: tgPrefix.EnvVars(NoStackGenerate),
129+
Destination: &opts.NoStackGenerate,
130+
Usage: "Disable automatic stack regeneration before running the command.",
131+
}),
132+
122133
// Backward compatibility with `terragrunt-` prefix flags.
123134

124135
flags.NewFlag(&cli.GenericFlag[string]{

cli/commands/stack/cli.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,6 @@ func defaultFlags(opts *options.TerragruntOptions, prefix flags.Prefix) cli.Flag
7676
tgPrefix := prefix.Prepend(flags.TgPrefix)
7777

7878
flags := cli.Flags{
79-
flags.NewFlag(&cli.BoolFlag{
80-
Name: NoStackGenerate,
81-
EnvVars: tgPrefix.EnvVars(NoStackGenerate),
82-
Destination: &opts.NoStackGenerate,
83-
Usage: "Disable automatic stack regeneration before running the command.",
84-
}),
8579
flags.NewFlag(&cli.BoolFlag{
8680
Name: NoStackValidate,
8781
EnvVars: tgPrefix.EnvVars(NoStackValidate),

docs-starlight/src/styles/global.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@
3434
--color-gray-900: var(--color-zinc-900);
3535
--color-gray-950: var(--color-zinc-950);
3636
}
37+
38+
:root {
39+
--sl-nav-height: 5rem;
40+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ require (
2626
github.com/gruntwork-io/boilerplate v0.6.1
2727
github.com/gruntwork-io/go-commons v0.17.2
2828
github.com/gruntwork-io/terragrunt-engine-go v0.0.14
29-
github.com/gruntwork-io/terratest v0.48.2
29+
github.com/gruntwork-io/terratest v0.49.0
3030
github.com/hashicorp/go-cleanhttp v0.5.2
3131
github.com/hashicorp/go-getter v1.7.8
3232
github.com/hashicorp/go-getter/v2 v2.2.3

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,8 +1235,8 @@ github.com/gruntwork-io/go-commons v0.17.2 h1:14dsCJ7M5Vv2X3BIPKeG9Kdy6vTMGhM8L4
12351235
github.com/gruntwork-io/go-commons v0.17.2/go.mod h1:zs7Q2AbUKuTarBPy19CIxJVUX/rBamfW8IwuWKniWkE=
12361236
github.com/gruntwork-io/terragrunt-engine-go v0.0.14 h1:8sdQNufNTlqNr+LFsBV7y6YqIFioHj/cQjgro8uqZLE=
12371237
github.com/gruntwork-io/terragrunt-engine-go v0.0.14/go.mod h1:jkMUtnJlr/BUUnU+pEjQL+uIzX9P0ui2WfUaldwo2mY=
1238-
github.com/gruntwork-io/terratest v0.48.2 h1:+VwfODchq8jxZZWD+s8gBlhD1z6/C4bFLNrhpm9ONrs=
1239-
github.com/gruntwork-io/terratest v0.48.2/go.mod h1:Y5ETyD4ZQ2MZhasPno272fWuCpKwvTPYDi8Y0tIMqTE=
1238+
github.com/gruntwork-io/terratest v0.49.0 h1:GurfpHEOEr8vntB77QcxDh+P7aiQRUgPFdgb6q9PuWI=
1239+
github.com/gruntwork-io/terratest v0.49.0/go.mod h1:/+dfGio9NqUpvvukuPo29B8zy6U5FYJn9PdmvwztK4A=
12401240
github.com/hashicorp/aws-sdk-go-base v0.6.0/go.mod h1:2fRjWDv3jJBeN6mVWFHV6hFTNeFBx2gpDLQaZNxUVAY=
12411241
github.com/hashicorp/consul v0.0.0-20171026175957-610f3c86a089/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
12421242
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=

test/fixtures/download/remote-relative-with-slash/terragrunt.hcl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ inputs = {
33
}
44

55
terraform {
6-
source = "github.com/gruntwork-io/terragrunt.git?ref=v0.77.22//test/fixtures/download/relative"
6+
source = "github.com/gruntwork-io/terragrunt.git?ref=v0.78.4//test/fixtures/download/relative"
77
}

test/integration_docs_aws_test.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ func TestAwsDocsOverview(t *testing.T) {
3333
tmpEnvPath := helpers.CopyEnvironment(t, stepPath)
3434
rootPath := util.JoinPath(tmpEnvPath, stepPath)
3535

36-
defer helpers.DeleteS3Bucket(t, region, s3BucketName)
37-
defer func() {
36+
t.Cleanup(func() {
37+
helpers.DeleteS3Bucket(t, region, s3BucketName)
38+
})
39+
t.Cleanup(func() {
3840
_, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt destroy -auto-approve --non-interactive --working-dir "+rootPath)
3941
require.NoError(t, err)
40-
}()
42+
})
4143

4244
rootTerragruntConfigPath := util.JoinPath(rootPath, config.DefaultTerragruntConfigPath)
4345
helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region)
@@ -57,11 +59,13 @@ func TestAwsDocsOverview(t *testing.T) {
5759
tmpEnvPath := helpers.CopyEnvironment(t, stepPath)
5860
rootPath := util.JoinPath(tmpEnvPath, stepPath)
5961

60-
defer helpers.DeleteS3Bucket(t, region, s3BucketName)
61-
defer func() {
62+
t.Cleanup(func() {
63+
helpers.DeleteS3Bucket(t, region, s3BucketName)
64+
})
65+
t.Cleanup(func() {
6266
_, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all --non-interactive --working-dir "+rootPath+" -- destroy -auto-approve")
6367
require.NoError(t, err)
64-
}()
68+
})
6569

6670
rootTerragruntConfigPath := util.JoinPath(rootPath, "root.hcl")
6771
helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region)
@@ -81,11 +85,13 @@ func TestAwsDocsOverview(t *testing.T) {
8185
tmpEnvPath := helpers.CopyEnvironment(t, stepPath)
8286
rootPath := util.JoinPath(tmpEnvPath, stepPath)
8387

84-
defer helpers.DeleteS3Bucket(t, region, s3BucketName)
85-
defer func() {
88+
t.Cleanup(func() {
89+
helpers.DeleteS3Bucket(t, region, s3BucketName)
90+
})
91+
t.Cleanup(func() {
8692
_, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all --non-interactive --working-dir "+rootPath+" -- destroy -auto-approve")
8793
require.NoError(t, err)
88-
}()
94+
})
8995

9096
rootTerragruntConfigPath := util.JoinPath(rootPath, "root.hcl")
9197
helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region)
@@ -105,11 +111,13 @@ func TestAwsDocsOverview(t *testing.T) {
105111
tmpEnvPath := helpers.CopyEnvironment(t, stepPath)
106112
rootPath := util.JoinPath(tmpEnvPath, stepPath)
107113

108-
defer helpers.DeleteS3Bucket(t, region, s3BucketName)
109-
defer func() {
114+
t.Cleanup(func() {
115+
helpers.DeleteS3Bucket(t, region, s3BucketName)
116+
})
117+
t.Cleanup(func() {
110118
_, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all --non-interactive --working-dir "+rootPath+" -- destroy -auto-approve")
111119
require.NoError(t, err)
112-
}()
120+
})
113121

114122
rootTerragruntConfigPath := util.JoinPath(rootPath, "root.hcl")
115123
helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region)
@@ -129,11 +137,13 @@ func TestAwsDocsOverview(t *testing.T) {
129137
tmpEnvPath := helpers.CopyEnvironment(t, stepPath)
130138
rootPath := util.JoinPath(tmpEnvPath, stepPath)
131139

132-
defer helpers.DeleteS3Bucket(t, region, s3BucketName)
133-
defer func() {
140+
t.Cleanup(func() {
141+
helpers.DeleteS3Bucket(t, region, s3BucketName)
142+
})
143+
t.Cleanup(func() {
134144
_, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all --non-interactive --working-dir "+rootPath+" -- destroy -auto-approve")
135145
require.NoError(t, err)
136-
}()
146+
})
137147

138148
rootTerragruntConfigPath := util.JoinPath(rootPath, "root.hcl")
139149
helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region)

0 commit comments

Comments
 (0)