Skip to content

Commit 6759544

Browse files
committed
fix: Adding support for no-shell and no-hooks
1 parent 6cd3ce1 commit 6759544

File tree

14 files changed

+172
-5
lines changed

14 files changed

+172
-5
lines changed

cli/commands/catalog/cli.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ func NewFlags(opts *options.TerragruntOptions, prefix flags.Prefix) cli.Flags {
1818
return scaffold.NewFlags(opts, prefix).Filter(
1919
scaffold.RootFileNameFlagName,
2020
scaffold.NoIncludeRootFlagName,
21+
scaffold.NoShellFlagName,
22+
scaffold.NoHooksFlagName,
2123
)
2224
}
2325

cli/commands/scaffold/cli.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const (
2424
VarFlagName = "var"
2525
VarFileFlagName = "var-file"
2626
NoDependencyPrompt = "no-dependency-prompt"
27+
NoShellFlagName = "no-shell"
28+
NoHooksFlagName = "no-hooks"
2729
)
2830

2931
func NewFlags(opts *options.TerragruntOptions, prefix flags.Prefix) cli.Flags {
@@ -87,6 +89,20 @@ func NewFlags(opts *options.TerragruntOptions, prefix flags.Prefix) cli.Flags {
8789
Destination: &opts.NoDependencyPrompt,
8890
Usage: "Do not prompt for confirmation to include dependencies.",
8991
}),
92+
93+
flags.NewFlag(&cli.BoolFlag{
94+
Name: NoShellFlagName,
95+
EnvVars: tgPrefix.EnvVars(NoShellFlagName),
96+
Destination: &opts.NoShell,
97+
Usage: "Disable shell commands when using boilerplate templates.",
98+
}),
99+
100+
flags.NewFlag(&cli.BoolFlag{
101+
Name: NoHooksFlagName,
102+
EnvVars: tgPrefix.EnvVars(NoHooksFlagName),
103+
Destination: &opts.NoHooks,
104+
Usage: "Disable hooks when using boilerplate templates.",
105+
}),
90106
}
91107
}
92108

cli/commands/scaffold/scaffold.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ const (
107107
)
108108

109109
func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOptions, moduleURL, templateURL string) error {
110+
// Apply catalog configuration settings, with CLI flags taking precedence
111+
applyCatalogConfigToScaffold(ctx, l, opts)
112+
110113
// download remote repo to local
111114
var dirsToClean []string
112115
// clean all temp dirs
@@ -201,8 +204,8 @@ func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOptions, mod
201204
OnMissingKey: boilerplate_options.DefaultMissingKeyAction,
202205
OnMissingConfig: boilerplate_options.DefaultMissingConfigAction,
203206
Vars: vars,
204-
NoShell: true,
205-
NoHooks: true,
207+
NoShell: opts.NoShell,
208+
NoHooks: opts.NoHooks,
206209
NonInteractive: opts.NonInteractive,
207210
DisableDependencyPrompt: opts.NoDependencyPrompt,
208211
TemplateFolder: boilerplateDir,
@@ -224,6 +227,36 @@ func Run(ctx context.Context, l log.Logger, opts *options.TerragruntOptions, mod
224227
return nil
225228
}
226229

230+
// applyCatalogConfigToScaffold applies catalog configuration settings to scaffold options.
231+
// CLI flags take precedence over config file settings.
232+
func applyCatalogConfigToScaffold(ctx context.Context, l log.Logger, opts *options.TerragruntOptions) {
233+
catalogCfg, err := config.ReadCatalogConfig(ctx, l, opts)
234+
if err != nil {
235+
// Don't fail if catalog config can't be read - it's optional
236+
l.Debugf("Could not read catalog config for scaffold: %v", err)
237+
return
238+
}
239+
240+
if catalogCfg == nil {
241+
return
242+
}
243+
244+
// Apply config settings only if CLI flags weren't explicitly set
245+
// Since both NoShell and NoHooks default to false, we apply the config value
246+
// only if it's true (enabling the restriction)
247+
if catalogCfg.NoShell != nil && *catalogCfg.NoShell && !opts.NoShell {
248+
l.Debugf("Applying catalog config: no_shell = true")
249+
250+
opts.NoShell = true
251+
}
252+
253+
if catalogCfg.NoHooks != nil && *catalogCfg.NoHooks && !opts.NoHooks {
254+
l.Debugf("Applying catalog config: no_hooks = true")
255+
256+
opts.NoHooks = true
257+
}
258+
}
259+
227260
// generateDefaultTemplate - write default template to provided dir
228261
func generateDefaultTemplate(boilerplateDir string) (string, error) {
229262
const ownerWriteGlobalReadPerms = 0644

cli/commands/scaffold/scaffold_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ func TestDefaultTemplateVariables(t *testing.T) {
6767
OnMissingKey: boilerplateoptions.DefaultMissingKeyAction,
6868
OnMissingConfig: boilerplateoptions.DefaultMissingConfigAction,
6969
Vars: vars,
70-
DisableShell: true,
71-
DisableHooks: true,
70+
NoShell: true,
71+
NoHooks: true,
7272
NonInteractive: true,
7373
DisableDependencyPrompt: false,
7474
TemplateFolder: templateDir,

config/catalog.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@ var (
3939
)
4040

4141
type CatalogConfig struct {
42+
NoShell *bool `hcl:"no_shell,optional" cty:"no_shell"`
43+
NoHooks *bool `hcl:"no_hooks,optional" cty:"no_hooks"`
4244
DefaultTemplate string `hcl:"default_template,optional" cty:"default_template"`
4345
URLs []string `hcl:"urls,attr" cty:"urls"`
4446
}
4547

4648
func (cfg *CatalogConfig) String() string {
47-
return fmt.Sprintf("Catalog{URLs = %v, DefaultTemplate = %v}", cfg.URLs, cfg.DefaultTemplate)
49+
return fmt.Sprintf("Catalog{URLs = %v, DefaultTemplate = %v, NoShell = %v, NoHooks = %v}", cfg.URLs, cfg.DefaultTemplate, cfg.NoShell, cfg.NoHooks)
4850
}
4951

5052
func (cfg *CatalogConfig) normalize(configPath string) {

config/config.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,14 @@ func (cfg *TerragruntConfig) WriteTo(w io.Writer) (int64, error) {
578578
catalogBody.SetAttributeValue("urls", catalogAsCty.GetAttr("urls"))
579579
}
580580

581+
if cfg.Catalog.NoShell != nil {
582+
catalogBody.SetAttributeValue("no_shell", catalogAsCty.GetAttr("no_shell"))
583+
}
584+
585+
if cfg.Catalog.NoHooks != nil {
586+
catalogBody.SetAttributeValue("no_hooks", catalogAsCty.GetAttr("no_hooks"))
587+
}
588+
581589
rootBody.AppendBlock(catalogBlock)
582590
}
583591

docs-starlight/src/content/docs/03-features/06-catalog.md renamed to docs-starlight/src/content/docs/03-features/06-catalog.mdx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ sidebar:
66
order: 6
77
---
88

9+
import { Aside } from '@astrojs/starlight/components';
10+
911
Launch the user interface for searching and managing your module catalog.
1012

1113
```bash
@@ -31,6 +33,8 @@ catalog {
3133
"github.com/gruntwork-io/terraform-aws-lambda", # url to remote repository
3234
"http://github.com/gruntwork-io/terraform-aws-lambda", # same as above
3335
]
36+
no_shell = true # Optional: disable shell commands in boilerplate templates for security
37+
no_hooks = true # Optional: disable hooks in boilerplate templates for security
3438
}
3539
```
3640

@@ -41,6 +45,30 @@ This will recursively search for OpenTofu/Terraform modules in the root of the r
4145
1. See the docs for a selected module: `ENTER`.
4246
1. Use [`terragrunt scaffold`](/docs/features/scaffold/) to render a `terragrunt.hcl` for using the module: `S`.
4347

48+
## Security Configuration
49+
50+
The `catalog` block supports security-related configuration options:
51+
52+
- `no_shell` (bool): When set to `true`, disables shell command execution in boilerplate templates during scaffolding. This is useful for organizations that want to prevent the use of shell commands in templates for security reasons.
53+
- `no_hooks` (bool): When set to `true`, disables hook execution in boilerplate templates during scaffolding. This is useful for organizations that want to prevent the use of hooks in templates for security reasons.
54+
55+
<Aside type="caution">
56+
57+
Do not use catalog/scaffold to scaffold untrusted templates. IaC configurations are inherently powerful, as they
58+
can run arbitrary code on your system, so make sure to only use trusted templates you have reviewed and approved.
59+
60+
</Aside>
61+
62+
These configuration values can be overridden by their corresponding CLI flags:
63+
64+
```bash
65+
terragrunt catalog --no-shell --no-hooks
66+
67+
terragrunt scaffold module-url --no-shell
68+
```
69+
70+
**Priority order**: CLI flags > catalog configuration > defaults (both default to `false`, allowing `shell` and `hooks` to be used by default)
71+
4472
## Custom templates for scaffolding
4573

4674
Terragrunt has a basic template built-in for rendering `terragrunt.hcl` files, but you can provide your own templates to customize how code is generated! Scaffolding is done via [boilerplate](https://github.com/gruntwork-io/boilerplate), and Terragrunt allows you to specify custom boilerplate templates via two mechanisms while using catalog:

docs-starlight/src/data/commands/catalog.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ examples:
1717
flags:
1818
- catalog-no-include-root
1919
- catalog-root-file-name
20+
- catalog-no-shell
21+
- catalog-no-hooks
2022
---
2123

2224
```bash

docs-starlight/src/data/commands/scaffold.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ flags:
1212
- scaffold-root-file-name
1313
- scaffold-var
1414
- scaffold-var-file
15+
- scaffold-no-shell
16+
- scaffold-no-hooks
1517
examples:
1618
- description: Scaffold a standard MySQL database module as a new unit.
1719
code: |
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
name: no-hooks
3+
description: "Disable hooks when using boilerplate templates in the catalog."
4+
type: bool
5+
env:
6+
- TG_NO_HOOKS
7+
---
8+
9+
When enabled, Terragrunt will disable hooks when processing boilerplate templates during catalog operations.
10+
11+
This is useful for security reasons when you want to prevent templates from executing arbitrary hooks on your system.
12+
13+
Examples:
14+
15+
```bash
16+
terragrunt catalog --no-hooks
17+
```

0 commit comments

Comments
 (0)