Skip to content

Commit

Permalink
Adds support for Terragrunt JSON configuration files
Browse files Browse the repository at this point in the history
  • Loading branch information
jakauppila committed Nov 13, 2019
1 parent d31069b commit 4ddb17b
Show file tree
Hide file tree
Showing 32 changed files with 590 additions and 15 deletions.
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ for a quick introduction to Terragrunt.
downloading the binary for your OS, renaming it to `terragrunt`, and adding it to your PATH.
* See the [Install Terragrunt](#install-terragrunt) docs for other installation options.

1. Go into a folder with your Terraform configurations (`.tf` files) and create a `terragrunt.hcl` file that contains
the configuration for Terragrunt (Terragrunt configuration uses the exact language, HCL, as Terraform). Here's an
example of using Terragrunt to keep your Terraform backend configuration DRY (check out the [Use cases](#use-cases)
1. Go into a folder with your Terraform configurations (`.tf` files) and create a `terragrunt.hcl` or `terragrunt.hcl.json` file that contains
the configuration for Terragrunt (Terragrunt configuration uses the exact language, HCL, as Terraform. [JSON configuration syntax](https://www.terraform.io/docs/configuration/syntax-json.html) is also supported.). Here's an
example of using Terragrunt to keep your Terraform backend configuration DRY (check out the [Use cases](#use-cases)
section for other types of configuration Terragrunt supports):

```hcl
Expand All @@ -35,6 +35,22 @@ for a quick introduction to Terragrunt.
region = "us-east-1"
encrypt = true
dynamodb_table = "my-lock-table"
}
}
```
```json
# terragrunt.hcl.json example
{
"remote_state":{
"backend": "s3",
"config":{
"bucket" : "my-terraform-state",
"key" : "${path_relative_to_include()}/terraform.tfstate",
"region" : "us-east-1",
"encrypt" : true,
"dynamodb_table" : "my-lock-table"
}
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion cli/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func parseTerragruntOptionsFromArgs(args []string, writer, errWriter io.Writer)
return nil, err
}
if terragruntConfigPath == "" {
terragruntConfigPath = config.DefaultConfigPath(workingDir)
terragruntConfigPath = config.GetDefaultConfigPath(workingDir)
}

terraformPath, err := parseStringArg(args, OPT_TERRAGRUNT_TFPATH, os.Getenv("TERRAGRUNT_TFPATH"))
Expand Down
32 changes: 28 additions & 4 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
)

const DefaultTerragruntConfigPath = "terragrunt.hcl"
const DefaultTerragruntJsonConfigPath = "terragrunt.hcl.json"

// TerragruntConfig represents a parsed and expanded configuration
type TerragruntConfig struct {
Expand Down Expand Up @@ -186,11 +187,25 @@ func (conf *TerraformExtraArguments) String() string {
conf.EnvVars)
}

// Return the default path to use for the Terragrunt configuration file in the given directory
// Return the default hcl path to use for the Terragrunt configuration file in the given directory
func DefaultConfigPath(workingDir string) string {
return util.JoinPath(workingDir, DefaultTerragruntConfigPath)
}

// Return the default path to use for the Terragrunt Json configuration file in the given directory
func DefaultJsonConfigPath(workingDir string) string {
return util.JoinPath(workingDir, DefaultTerragruntJsonConfigPath)
}

// Return the default path to use for the Terragrunt configuration that exists within the path giving preference to `terragrunt.hcl`
func GetDefaultConfigPath(workingDir string) string {
if util.FileNotExists(DefaultConfigPath(workingDir)) && util.FileExists(DefaultJsonConfigPath(workingDir)) {
return DefaultJsonConfigPath(workingDir)
}

return DefaultConfigPath(workingDir)
}

// Returns a list of all Terragrunt config files in the given path or any subfolder of the path. A file is a Terragrunt
// config file if it has a name as returned by the DefaultConfigPath method
func FindConfigFilesInPath(rootPath string, terragruntOptions *options.TerragruntOptions) ([]string, error) {
Expand All @@ -207,7 +222,7 @@ func FindConfigFilesInPath(rootPath string, terragruntOptions *options.Terragrun
}

if isTerragruntModule {
configFiles = append(configFiles, DefaultConfigPath(path))
configFiles = append(configFiles, GetDefaultConfigPath(path))
}

return nil
Expand All @@ -217,7 +232,7 @@ func FindConfigFilesInPath(rootPath string, terragruntOptions *options.Terragrun
}

// Returns true if the given path with the given FileInfo contains a Terragrunt module and false otherwise. A path
// contains a Terragrunt module if it contains a Terragrunt configuration file (terragrunt.hcl) and is not a cache
// contains a Terragrunt module if it contains a Terragrunt configuration file (terragrunt.hcl, terragrunt.hcl.json) and is not a cache
// or download dir.
func containsTerragruntModule(path string, info os.FileInfo, terragruntOptions *options.TerragruntOptions) (bool, error) {
if !info.IsDir() {
Expand All @@ -244,7 +259,7 @@ func containsTerragruntModule(path string, info os.FileInfo, terragruntOptions *
return false, err
}

return util.FileExists(DefaultConfigPath(path)), nil
return util.FileExists(GetDefaultConfigPath(path)), nil
}

// Read the Terragrunt config file from its default location
Expand Down Expand Up @@ -417,6 +432,15 @@ func parseHcl(parser *hclparse.Parser, hcl string, filename string) (file *hcl.F
}
}()

if filepath.Ext(filename) == ".json" {
file, parseDiagnostics := parser.ParseJSON([]byte(hcl), filename)
if parseDiagnostics != nil && parseDiagnostics.HasErrors() {
return nil, parseDiagnostics
}

return file, nil
}

file, parseDiagnostics := parser.ParseHCL([]byte(hcl), filename)
if parseDiagnostics != nil && parseDiagnostics.HasErrors() {
return nil, parseDiagnostics
Expand Down
2 changes: 1 addition & 1 deletion config/config_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ func findInParentFolders(params []string, include *IncludeConfig, terragruntOpti
return "", errors.WithStackTrace(ParentFileNotFound{Path: terragruntOptions.TerragruntConfigPath, File: fileToFindStr, Cause: "Traversed all the way to the root"})
}

fileToFind := DefaultConfigPath(currentDir)
fileToFind := GetDefaultConfigPath(currentDir)
if fileToFindParam != "" {
fileToFind = util.JoinPath(currentDir, fileToFindParam)
}
Expand Down
Loading

0 comments on commit 4ddb17b

Please sign in to comment.