Skip to content

Commit fd12ff5

Browse files
authored
Merge pull request #117 from gruntwork-io/update-source
Add a --terragrunt-source-update flag
2 parents 4fbb152 + 1bf8ed3 commit fd12ff5

6 files changed

Lines changed: 44 additions & 10 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,8 @@ prefix `--terragrunt-`. The currently available options are:
828828
Terraform in that temporary folder. May also be specified via the `TERRAGRUNT_SOURCE` environment variable. The
829829
source should use the same syntax as the [Terraform module source](https://www.terraform.io/docs/modules/sources.html)
830830
parameter.
831+
* `--terragrunt-source-update`: Delete the contents of the temporary folder before downloading Terraform source code
832+
into it.
831833

832834
## Developing terragrunt
833835

cli/args.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ func parseTerragruntOptionsFromArgs(args []string) (*options.TerragruntOptions,
6060
return nil, err
6161
}
6262

63+
sourceUpdate := parseBooleanArg(args, OPT_TERRAGRUNT_SOURCE_UPDATE, false)
64+
6365
return &options.TerragruntOptions{
6466
TerragruntConfigPath: filepath.ToSlash(terragruntConfigPath),
6567
TerraformPath: filepath.ToSlash(terraformPath),
@@ -69,6 +71,7 @@ func parseTerragruntOptionsFromArgs(args []string) (*options.TerragruntOptions,
6971
Logger: util.CreateLogger(""),
7072
RunTerragrunt: runTerragrunt,
7173
Source: terraformSource,
74+
SourceUpdate: sourceUpdate,
7275
Env: parseEnvironmentVariables(os.Environ()),
7376
}, nil
7477
}

cli/cli_app.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ const OPT_TERRAGRUNT_TFPATH = "terragrunt-tfpath"
2020
const OPT_NON_INTERACTIVE = "terragrunt-non-interactive"
2121
const OPT_WORKING_DIR = "terragrunt-working-dir"
2222
const OPT_TERRAGRUNT_SOURCE = "terragrunt-source"
23-
var ALL_TERRAGRUNT_BOOLEAN_OPTS = []string{OPT_NON_INTERACTIVE}
23+
const OPT_TERRAGRUNT_SOURCE_UPDATE = "terragrunt-source-update"
24+
var ALL_TERRAGRUNT_BOOLEAN_OPTS = []string{OPT_NON_INTERACTIVE, OPT_TERRAGRUNT_SOURCE_UPDATE}
2425
var ALL_TERRAGRUNT_STRING_OPTS = []string{OPT_TERRAGRUNT_CONFIG, OPT_TERRAGRUNT_TFPATH, OPT_WORKING_DIR, OPT_TERRAGRUNT_SOURCE}
2526

2627
const CMD_ACQUIRE_LOCK = "acquire-lock"
@@ -56,6 +57,7 @@ GLOBAL OPTIONS:
5657
terragrunt-non-interactive Assume "yes" for all prompts.
5758
terragrunt-working-dir The path to the Terraform templates. Default is current directory.
5859
terragrunt-source Download Terraform configurations from the specified source into a temporary folder, and run Terraform in that temporary folder
60+
terragrunt-source-update Delete the contents of the temporary folder to clear out any old, cached source code before downloading new source code into it
5961
6062
VERSION:
6163
{{.Version}}{{if len .Authors}}

cli/download_source.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ func downloadTerraformSource(source string, terragruntOptions *options.Terragrun
5959

6060
// Download the specified TerraformSource if the latest code hasn't already been downloaded.
6161
func downloadTerraformSourceIfNecessary(terraformSource *TerraformSource, terragruntOptions *options.TerragruntOptions) error {
62+
if terragruntOptions.SourceUpdate {
63+
terragruntOptions.Logger.Printf("The --%s flag is set, so deleting the temporary folder %s before downloading source.", OPT_TERRAGRUNT_SOURCE_UPDATE, terraformSource.DownloadDir)
64+
if err := os.RemoveAll(terraformSource.DownloadDir); err != nil {
65+
return errors.WithStackTrace(err)
66+
}
67+
}
68+
6269
alreadyLatest, err := alreadyHaveLatestCode(terraformSource)
6370
if err != nil {
6471
return err

cli/download_source_test.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func TestDownloadTerraformSourceIfNecessaryLocalDirToEmptyDir(t *testing.T) {
7373
downloadDir := tmpDir(t)
7474
defer os.Remove(downloadDir)
7575

76-
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, "# Hello, World")
76+
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, false, "# Hello, World")
7777
}
7878

7979
func TestDownloadTerraformSourceIfNecessaryLocalDirToAlreadyDownloadedDir(t *testing.T) {
@@ -85,7 +85,7 @@ func TestDownloadTerraformSourceIfNecessaryLocalDirToAlreadyDownloadedDir(t *tes
8585

8686
copyFolder(t, "../test/fixture-download-source/hello-world-2", downloadDir)
8787

88-
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, "# Hello, World")
88+
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, false, "# Hello, World")
8989
}
9090

9191
func TestDownloadTerraformSourceIfNecessaryRemoteUrlToEmptyDir(t *testing.T) {
@@ -95,7 +95,7 @@ func TestDownloadTerraformSourceIfNecessaryRemoteUrlToEmptyDir(t *testing.T) {
9595
downloadDir := tmpDir(t)
9696
defer os.Remove(downloadDir)
9797

98-
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, "# Hello, World")
98+
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, false, "# Hello, World")
9999
}
100100

101101
func TestDownloadTerraformSourceIfNecessaryRemoteUrlToAlreadyDownloadedDir(t *testing.T) {
@@ -107,7 +107,7 @@ func TestDownloadTerraformSourceIfNecessaryRemoteUrlToAlreadyDownloadedDir(t *te
107107

108108
copyFolder(t, "../test/fixture-download-source/hello-world-2", downloadDir)
109109

110-
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, "# Hello, World 2")
110+
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, false, "# Hello, World 2")
111111
}
112112

113113
func TestDownloadTerraformSourceIfNecessaryRemoteUrlToAlreadyDownloadedDirDifferentVersion(t *testing.T) {
@@ -119,7 +119,7 @@ func TestDownloadTerraformSourceIfNecessaryRemoteUrlToAlreadyDownloadedDirDiffer
119119

120120
copyFolder(t, "../test/fixture-download-source/hello-world-2", downloadDir)
121121

122-
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, "# Hello, World")
122+
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, false, "# Hello, World")
123123
}
124124

125125
func TestDownloadTerraformSourceIfNecessaryRemoteUrlToAlreadyDownloadedDirSameVersion(t *testing.T) {
@@ -131,17 +131,32 @@ func TestDownloadTerraformSourceIfNecessaryRemoteUrlToAlreadyDownloadedDirSameVe
131131

132132
copyFolder(t, "../test/fixture-download-source/hello-world-version-remote", downloadDir)
133133

134-
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, "# Hello, World version remote")
134+
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, false, "# Hello, World version remote")
135135
}
136136

137-
func testDownloadTerraformSourceIfNecessary(t *testing.T, canonicalUrl string, downloadDir string, expectedFileContents string) {
137+
func TestDownloadTerraformSourceIfNecessaryRemoteUrlOverrideSource(t *testing.T) {
138+
t.Parallel()
139+
140+
canonicalUrl := "github.com/gruntwork-io/terragrunt//test/fixture-download-source/hello-world?ref=v0.9.7"
141+
downloadDir := tmpDir(t)
142+
defer os.Remove(downloadDir)
143+
144+
copyFolder(t, "../test/fixture-download-source/hello-world-version-remote", downloadDir)
145+
146+
testDownloadTerraformSourceIfNecessary(t, canonicalUrl, downloadDir, true, "# Hello, World")
147+
}
148+
149+
func testDownloadTerraformSourceIfNecessary(t *testing.T, canonicalUrl string, downloadDir string, sourceUpdate bool, expectedFileContents string) {
138150
terraformSource := &TerraformSource{
139151
CanonicalSourceURL: parseUrl(t, canonicalUrl),
140152
DownloadDir: downloadDir,
141153
VersionFile: filepath.Join(downloadDir, "version-file.txt"),
142154
}
143155

144-
err := downloadTerraformSourceIfNecessary(terraformSource, options.NewTerragruntOptionsForTest("./should-not-be-used"))
156+
terragruntOptions := options.NewTerragruntOptionsForTest("./should-not-be-used")
157+
terragruntOptions.SourceUpdate = sourceUpdate
158+
159+
err := downloadTerraformSourceIfNecessary(terraformSource, terragruntOptions)
145160
assert.Nil(t, err, "For terraform source %v: %v", terraformSource, err)
146161

147162
expectedFilePath := filepath.Join(downloadDir, "main.tf")

options/options.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@ type TerragruntOptions struct {
3535
// Terraform in that temporary folder
3636
Source string
3737

38+
// If set to true, delete the contents of the temporary folder before downloading Terraform source code into it
39+
SourceUpdate bool
40+
3841
// A command that can be used to run Terragrunt with the given options. This is useful for running Terragrunt
3942
// multiple times (e.g. when spinning up a stack of Terraform modules). The actual command is normally defined
4043
// in the cli package, which depends on almost all other packages, so we declare it here so that other
4144
// packages can use the command without a direct reference back to the cli package (which would create a
4245
// circular dependency).
43-
RunTerragrunt func(*TerragruntOptions) error
46+
RunTerragrunt func(*TerragruntOptions) error
4447
}
4548

4649
// Create a new TerragruntOptions object with reasonable defaults for real usage
@@ -56,6 +59,7 @@ func NewTerragruntOptions(terragruntConfigPath string) *TerragruntOptions {
5659
Logger: util.CreateLogger(""),
5760
Env: map[string]string{},
5861
Source: "",
62+
SourceUpdate: false,
5963
RunTerragrunt: func(terragruntOptions *TerragruntOptions) error {
6064
return errors.WithStackTrace(RunTerragruntCommandNotSet)
6165
},
@@ -85,6 +89,7 @@ func (terragruntOptions *TerragruntOptions) Clone(terragruntConfigPath string) *
8589
Logger: util.CreateLogger(workingDir),
8690
Env: terragruntOptions.Env,
8791
Source: terragruntOptions.Source,
92+
SourceUpdate: terragruntOptions.SourceUpdate,
8893
RunTerragrunt: terragruntOptions.RunTerragrunt,
8994
}
9095
}

0 commit comments

Comments
 (0)