Skip to content

Commit

Permalink
add stack values generation
Browse files Browse the repository at this point in the history
  • Loading branch information
denis256 committed Feb 21, 2025
1 parent f1fd908 commit 2e9d80d
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 21 deletions.
8 changes: 7 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ const (
MetadataErrors = "errors"
MetadataRetry = "retry"
MetadataIgnore = "ignore"
MetadataUnit = "unit"
MetadataValues = "values"
)

Expand Down Expand Up @@ -895,6 +894,13 @@ func ParseConfig(ctx *ParsingContext, file *hclparse.File, includeFromChild *Inc
return nil, err
}

// read unit files and add to context
unitValues, err := ReadUnitValues(ctx.Context, ctx.TerragruntOptions, filepath.Dir(file.ConfigPath))
if err != nil {
return nil, err
}
ctx = ctx.WithValues(unitValues)

// Decode just the Base blocks. See the function docs for DecodeBaseBlocks for more info on what base blocks are.
baseBlocks, err := DecodeBaseBlocks(ctx, file, includeFromChild)
if err != nil {
Expand Down
13 changes: 4 additions & 9 deletions config/config_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ func createTerragruntEvalContext(ctx *ParsingContext, configPath string) (*hcl.E
evalCtx.Variables[MetadataFeatureFlag] = *ctx.Features
}

if ctx.Values != nil {
evalCtx.Variables[MetadataValues] = *ctx.Values
}

if ctx.DecodedDependencies != nil {
evalCtx.Variables[MetadataDependency] = *ctx.DecodedDependencies
}
Expand All @@ -225,15 +229,6 @@ func createTerragruntEvalContext(ctx *ParsingContext, configPath string) (*hcl.E
evalCtx.Variables[MetadataInclude] = exposedInclude
}

// read unit files and add to context
unitValues, err := ReadUnitValues(ctx.Context, ctx.TerragruntOptions, filepath.Dir(configPath))
if err != nil {
return evalCtx, err
}
if unitValues != nil {
evalCtx.Variables[MetadataValues] = cty.ObjectVal(unitValues)
}

return evalCtx, nil
}

Expand Down
7 changes: 7 additions & 0 deletions config/config_partial.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,13 @@ func PartialParseConfigString(ctx *ParsingContext, configPath, configString stri
func PartialParseConfig(ctx *ParsingContext, file *hclparse.File, includeFromChild *IncludeConfig) (*TerragruntConfig, error) {
ctx = ctx.WithTrackInclude(nil)

// read unit files and add to context
unitValues, err := ReadUnitValues(ctx.Context, ctx.TerragruntOptions, filepath.Dir(file.ConfigPath))
if err != nil {
return nil, err
}
ctx = ctx.WithValues(unitValues)

// Decode just the Base blocks. See the function docs for DecodeBaseBlocks for more info on what base blocks are.
// Initialize evaluation ctx extensions from base blocks.
baseBlocks, err := DecodeBaseBlocks(ctx, file, includeFromChild)
Expand Down
4 changes: 2 additions & 2 deletions config/locals.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ func canEvaluateLocals(expression hcl.Expression, evaluatedLocals map[string]cty
case rootName == MetadataFeatureFlag:
// If the variable is `feature`

case rootName == MetadataUnit:
// If the variable is `unit`
case rootName == MetadataValues:
// If the variable is `values`

case rootName != "local":
// We can't evaluate any variable other than `local`
Expand Down
8 changes: 8 additions & 0 deletions config/parsing_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ type ParsingContext struct {
// Features are the feature flags that are enabled for the current terragrunt config.
Features *cty.Value

// Values of the unit
Values *cty.Value

// DecodedDependencies are references of other terragrunt config. This contains the following attributes that map to
// various fields related to that config:
// - outputs: The map of outputs from the terraform state obtained by running `terragrunt output` on that target config.
Expand Down Expand Up @@ -72,6 +75,11 @@ func (ctx ParsingContext) WithLocals(locals *cty.Value) *ParsingContext {
return &ctx
}

func (ctx ParsingContext) WithValues(values *cty.Value) *ParsingContext {
ctx.Values = values
return &ctx
}

// WithFeatures sets the feature flags to be used in evaluation context.
func (ctx ParsingContext) WithFeatures(features *cty.Value) *ParsingContext {
ctx.Features = features
Expand Down
19 changes: 10 additions & 9 deletions config/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strings"

"github.com/gruntwork-io/terragrunt/util"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclwrite"

"github.com/zclconf/go-cty/cty"
Expand Down Expand Up @@ -114,28 +113,30 @@ func WriteUnitValues(opts *options.TerragruntOptions, unit *Unit, unitDirectory
}

// ReadUnitValues reads the unit values from the terragrunt.values.hcl file.
func ReadUnitValues(ctx context.Context, opts *options.TerragruntOptions, unitDirectory string) (map[string]cty.Value, error) {
func ReadUnitValues(ctx context.Context, opts *options.TerragruntOptions, unitDirectory string) (*cty.Value, error) {
filePath := filepath.Join(unitDirectory, unitValuesFile)
if !util.FileNotExists(filePath) {
if util.FileNotExists(filePath) {
return nil, nil
}
opts.Logger.Debugf("Reading Terragrunt stack values file at %s", filePath)

parser := NewParsingContext(ctx, opts)

file, err := hclparse.NewParser(parser.ParserOptions...).ParseFromFile(opts.TerragruntStackConfigPath)
file, err := hclparse.NewParser(parser.ParserOptions...).ParseFromFile(filePath)
if err != nil {
return nil, errors.New(err)
}
// empty eval context to parse values only
evalCtx := &hcl.EvalContext{
Variables: map[string]cty.Value{},
evalParsingContext, err := createTerragruntEvalContext(parser, file.ConfigPath)
if err != nil {
return nil, errors.New(err)
}
// empty eval context to parse values only
values := map[string]cty.Value{}
if err := file.Decode(&values, evalCtx); err != nil {
if err := file.Decode(&values, evalParsingContext); err != nil {
return nil, errors.New(err)
}
return values, nil
result := cty.ObjectVal(values)
return &result, nil
}

// ValidateStackConfig validates a StackConfigFile instance according to the rules:
Expand Down

0 comments on commit 2e9d80d

Please sign in to comment.