Skip to content

Commit 65b1016

Browse files
authored
Fixed auto-detect read_terragrunt_config dependencies in locals blocks. (#2295)
Signed-off-by: Lorenzo Buitizon <[email protected]>
1 parent d86d480 commit 65b1016

File tree

4 files changed

+122
-2
lines changed

4 files changed

+122
-2
lines changed

go.work.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
950950
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
951951
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
952952
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
953+
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
953954
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
954955
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:1iy2qD6JEhHKKhUOA9IWs7mjco7lnw2qx8FsRI2wirE=
955956
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
@@ -1104,6 +1105,7 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY
11041105
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
11051106
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
11061107
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
1108+
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
11071109
github.com/googleapis/cloud-bigtable-clients-test v0.0.2 h1:S+sCHWAiAc+urcEnvg5JYJUOdlQEm/SEzQ/c/IdAH5M=
11081110
github.com/googleapis/cloud-bigtable-clients-test v0.0.2/go.mod h1:mk3CrkrouRgtnhID6UZQDK3DrFFa7cYCAJcEmNsHYrY=
11091111
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
@@ -1471,6 +1473,7 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
14711473
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
14721474
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
14731475
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
1476+
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
14741477
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig=
14751478
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
14761479
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=

libs/digger_config/terragrunt/tac/parse_locals.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/hashicorp/hcl/v2/hclparse"
1414
"github.com/zclconf/go-cty/cty"
1515
"log/slog"
16+
"regexp"
1617

1718
"path/filepath"
1819
)
@@ -41,6 +42,24 @@ type ResolvedLocals struct {
4142
markedProject *bool
4243
}
4344

45+
// detectReadTerragruntConfigDependencies scans HCL content for read_terragrunt_config calls
46+
// and extracts file paths from find_in_parent_folders() function calls
47+
func detectReadTerragruntConfigDependencies(hclContent string) []string {
48+
var dependencies []string
49+
50+
// Pattern to match read_terragrunt_config(find_in_parent_folders("filename"))
51+
readTerragruntConfigPattern := regexp.MustCompile(`read_terragrunt_config\s*\(\s*find_in_parent_folders\s*\(\s*["\']([^"\']+)["\']\s*\)\s*\)`)
52+
53+
matches := readTerragruntConfigPattern.FindAllStringSubmatch(hclContent, -1)
54+
for _, match := range matches {
55+
if len(match) > 1 {
56+
dependencies = append(dependencies, match[1])
57+
}
58+
}
59+
60+
return dependencies
61+
}
62+
4463
// parseHcl uses the HCL2 parser to parse the given string into an HCL file body.
4564
func parseHcl(parser *hclparse.Parser, hcl string, filename string) (file *hcl.File, err error) {
4665

@@ -123,6 +142,9 @@ func parseLocals(path string, terragruntOptions *options.TerragruntOptions, incl
123142
localsAsCty := extensions.Locals
124143
trackInclude := extensions.TrackInclude
125144

145+
// Detect read_terragrunt_config dependencies from raw HCL content
146+
autoDetectedDependencies := detectReadTerragruntConfigDependencies(configString)
147+
126148
// Recurse on the parent to merge in the locals from that file
127149
mergedParentLocals := ResolvedLocals{}
128150
if trackInclude != nil && includeFromChild == nil {
@@ -131,12 +153,12 @@ func parseLocals(path string, terragruntOptions *options.TerragruntOptions, incl
131153
mergedParentLocals = mergeResolvedLocals(mergedParentLocals, parentLocals)
132154
}
133155
}
134-
childLocals := resolveLocals(*localsAsCty)
156+
childLocals := resolveLocals(*localsAsCty, autoDetectedDependencies)
135157

136158
return mergeResolvedLocals(mergedParentLocals, childLocals), nil
137159
}
138160

139-
func resolveLocals(localsAsCty cty.Value) ResolvedLocals {
161+
func resolveLocals(localsAsCty cty.Value, autoDetectedDependencies []string) ResolvedLocals {
140162
resolved := ResolvedLocals{}
141163

142164
// Return an empty set of locals if no `locals` block was present
@@ -195,5 +217,13 @@ func resolveLocals(localsAsCty cty.Value) ResolvedLocals {
195217
}
196218
}
197219

220+
// Add auto-detected dependencies from read_terragrunt_config calls
221+
for _, dep := range autoDetectedDependencies {
222+
resolved.ExtraDiggerDependencies = append(
223+
resolved.ExtraDiggerDependencies,
224+
filepath.ToSlash(dep),
225+
)
226+
}
227+
198228
return resolved
199229
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package tac
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestDetectReadTerragruntConfigDependencies(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
hclContent string
11+
expected []string
12+
}{
13+
{
14+
name: "single read_terragrunt_config call",
15+
hclContent: `
16+
locals {
17+
project_vars = read_terragrunt_config(find_in_parent_folders("region.hcl"))
18+
staff_vars = read_terragrunt_config(find_in_parent_folders("data/staff.hcl"))
19+
}`,
20+
expected: []string{"region.hcl", "data/staff.hcl"},
21+
},
22+
{
23+
name: "mixed with other locals",
24+
hclContent: `
25+
locals {
26+
project_vars = read_terragrunt_config(find_in_parent_folders("region.hcl"))
27+
environment = "dev"
28+
staff_vars = read_terragrunt_config(find_in_parent_folders("data/staff.hcl"))
29+
}`,
30+
expected: []string{"region.hcl", "data/staff.hcl"},
31+
},
32+
{
33+
name: "no read_terragrunt_config calls",
34+
hclContent: `
35+
locals {
36+
environment = "dev"
37+
region = "us-east-1"
38+
}`,
39+
expected: []string{},
40+
},
41+
{
42+
name: "with extra_digger_dependencies",
43+
hclContent: `
44+
locals {
45+
extra_digger_dependencies = [
46+
"some-file.hcl"
47+
]
48+
project_vars = read_terragrunt_config(find_in_parent_folders("region.hcl"))
49+
}`,
50+
expected: []string{"region.hcl"},
51+
},
52+
}
53+
54+
for _, tt := range tests {
55+
t.Run(tt.name, func(t *testing.T) {
56+
result := detectReadTerragruntConfigDependencies(tt.hclContent)
57+
if len(result) != len(tt.expected) {
58+
t.Errorf("Expected %d dependencies, got %d: %v", len(tt.expected), len(result), result)
59+
return
60+
}
61+
for i, expected := range tt.expected {
62+
if i >= len(result) || result[i] != expected {
63+
t.Errorf("Expected dependency %d to be %q, got %q", i, expected, result[i])
64+
}
65+
}
66+
})
67+
}
68+
}

libs/go.sum

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,35 +777,53 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX
777777
github.com/aws/aws-sdk-go v1.51.21 h1:UrT6JC9R9PkYYXDZBV0qDKTualMr+bfK2eboTknMgbs=
778778
github.com/aws/aws-sdk-go v1.51.21/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
779779
github.com/aws/aws-sdk-go-v2 v1.38.1 h1:j7sc33amE74Rz0M/PoCpsZQ6OunLqys/m5antM0J+Z8=
780+
github.com/aws/aws-sdk-go-v2 v1.38.1/go.mod h1:9Q0OoGQoboYIAJyslFyF1f5K1Ryddop8gqMhWx/n4Wg=
780781
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.0 h1:6GMWV6CNpA/6fbFHnoAjrv4+LGfyTqZz2LtCHnspgDg=
782+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.0/go.mod h1:/mXlTIVG9jbxkqDnr5UQNQxW1HRYxeGklkM9vAFeabg=
781783
github.com/aws/aws-sdk-go-v2/config v1.31.2 h1:NOaSZpVGEH2Np/c1toSeW0jooNl+9ALmsUTZ8YvkJR0=
784+
github.com/aws/aws-sdk-go-v2/config v1.31.2/go.mod h1:17ft42Yb2lF6OigqSYiDAiUcX4RIkEMY6XxEMJsrAes=
782785
github.com/aws/aws-sdk-go-v2/credentials v1.18.6 h1:AmmvNEYrru7sYNJnp3pf57lGbiarX4T9qU/6AZ9SucU=
786+
github.com/aws/aws-sdk-go-v2/credentials v1.18.6/go.mod h1:/jdQkh1iVPa01xndfECInp1v1Wnp70v3K4MvtlLGVEc=
783787
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.15.15 h1:2HXPu4MCUKVA/hU0g2DWtYgXjVPsj7Ujd+xif/Yl2fc=
784788
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.15.15/go.mod h1:fqQI+CG2FX4yVDJORf6QAKLRw16yO+JcB6io1iubcm0=
785789
github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.7.50 h1:SjyghAoNXXDMUUdx4BBFjqyuvuw2DuobVxBBXknsi4A=
786790
github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.7.50/go.mod h1:z4QntVMcpu4UnoKENJl8pFohHHf55MG8kM2fkA4x8fg=
787791
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.4 h1:lpdMwTzmuDLkgW7086jE94HweHCqG+uOJwHf3LZs7T0=
792+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.4/go.mod h1:9xzb8/SV62W6gHQGC/8rrvgNXU6ZoYM3sAIJCIrXJxY=
788793
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.4 h1:IdCLsiiIj5YJ3AFevsewURCPV+YWUlOW8JiPhoAy8vg=
794+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.4/go.mod h1:l4bdfCD7XyyZA9BolKBo1eLqgaJxl0/x91PL4Yqe0ao=
789795
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.4 h1:j7vjtr1YIssWQOMeOWRbh3z8g2oY/xPjnZH2gLY4sGw=
796+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.4/go.mod h1:yDmJgqOiH4EA8Hndnv4KwAo8jCGTSnM5ASG1nBI+toA=
790797
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
798+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
791799
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.4 h1:BE/MNQ86yzTINrfxPPFS86QCBNQeLKY2A0KhDh47+wI=
800+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.4/go.mod h1:SPBBhkJxjcrzJBc+qY85e83MQ2q3qdra8fghhkkyrJg=
792801
github.com/aws/aws-sdk-go-v2/service/cognitoidentity v1.27.5 h1:BH9f0H3Tl44iCofo/Vx+4LGfVJ/Ptjh3j/4cn25cU0E=
793802
github.com/aws/aws-sdk-go-v2/service/cognitoidentity v1.27.5/go.mod h1:JcmPakQKiVFzqrJFefuBFabERYm56bndwJqMHys0pEg=
794803
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.36.5 h1:VWun/99wjelZZ+d0DGeSrffiCBJhC481geypGc6rfn0=
795804
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.36.5/go.mod h1:P+1rrWglInpWvnBpN0pH8jIIhkLkBaolkRVG4X9Kous=
796805
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.5 h1:pc8+YeYe6bBe8D3QeBz9/S5kUZ9k9yoBMbljGIBMNK4=
797806
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.5/go.mod h1:R09/8/9eLYHJ50PQ8FlIGjZb3XA2t2XhcI5E5332eCI=
798807
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0 h1:6+lZi2JeGKtCraAj1rpoZfKqnQ9SptseRZioejfUOLM=
808+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0/go.mod h1:eb3gfbVIxIoGgJsi9pGne19dhCBpK6opTYpQqAmdy44=
799809
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.4 h1:Beh9oVgtQnBgR4sKKzkUBRQpf1GnL4wt0l4s8h2VCJ0=
810+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.4/go.mod h1:b17At0o8inygF+c6FOD3rNyYZufPw62o9XJbSfQPgbo=
800811
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.4 h1:rWKH6IiWDRIxmsTJUB/wEY+EIPp+P3C78Vidl+HXp6w=
801812
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.4/go.mod h1:MzOAfuiNZ6asjVrA+dNvXl5lI2nmzXakSpDFLOcOyJ4=
802813
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4 h1:ueB2Te0NacDMnaC+68za9jLwkjzxGWm0KB5HTUHjLTI=
814+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4/go.mod h1:nLEfLnVMmLvyIG58/6gsSA03F1voKGaCfHV7+lR8S7s=
803815
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.4 h1:HVSeukL40rHclNcUqVcBwE1YoZhOkoLeBfhUqR3tjIU=
816+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.4/go.mod h1:DnbBOv4FlIXHj2/xmrUQYtawRFC9L9ZmQPz+DBc6X5I=
804817
github.com/aws/aws-sdk-go-v2/service/s3 v1.87.1 h1:2n6Pd67eJwAb/5KCX62/8RTU0aFAAW7V5XIGSghiHrw=
818+
github.com/aws/aws-sdk-go-v2/service/s3 v1.87.1/go.mod h1:w5PC+6GHLkvMJKasYGVloB3TduOtROEMqm15HSuIbw4=
805819
github.com/aws/aws-sdk-go-v2/service/sso v1.28.2 h1:ve9dYBB8CfJGTFqcQ3ZLAAb/KXWgYlgu/2R2TZL2Ko0=
820+
github.com/aws/aws-sdk-go-v2/service/sso v1.28.2/go.mod h1:n9bTZFZcBa9hGGqVz3i/a6+NG0zmZgtkB9qVVFDqPA8=
806821
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2 h1:pd9G9HQaM6UZAZh19pYOkpKSQkyQQ9ftnl/LttQOcGI=
822+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2/go.mod h1:eknndR9rU8UpE/OmFpqU78V1EcXPKFTTm5l/buZYgvM=
807823
github.com/aws/aws-sdk-go-v2/service/sts v1.38.0 h1:iV1Ko4Em/lkJIsoKyGfc0nQySi+v0Udxr6Igq+y9JZc=
824+
github.com/aws/aws-sdk-go-v2/service/sts v1.38.0/go.mod h1:bEPcjW7IbolPfK67G1nilqWyoxYMSPrDiIQ3RdIdKgo=
808825
github.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw=
826+
github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
809827
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
810828
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
811829
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -1037,6 +1055,7 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w
10371055
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
10381056
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
10391057
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
1058+
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
10401059
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
10411060
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
10421061
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=

0 commit comments

Comments
 (0)