Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit31ae915

Browse files
feat: warn when .terraform.lock.hcl is modified during terraform init
Fixes#18237This PR adds diff generation for .terraform.lock.hcl files before and after running terraform init to detect when provider hashes are missing for the target architecture.## ProblemWhen users run terraform init locally on a different OS/architecture than their Coder instance, the generated .terraform.lock.hcl file may be missing provider hashes for the target architecture. This causes Terraform to download providers unnecessarily during provisioning, slowing down the process.## Solution- Read .terraform.lock.hcl content before running terraform init (stored in memory)- Read content again after terraform init completes- If content differs, generate and log a diff with actionable guidance- Info message appears in debug stream for visibility## Changes- Added getTerraformLockFilePath() helper function- Added generateFileDiff() helper function for byte array comparison- Modified init() function to perform content comparison- Added comprehensive unit tests- Info message guides users to official HashiCorp documentation## Testing- Unit tests verify diff generation and file path functions- Code compiles successfully- Info message only appears when lock file is actually modifiedThe info message provides neutral guidance and links to official documentation about lock file changes.Co-authored-by: kylecarbs <7122116+kylecarbs@users.noreply.github.com>
1 parent910858b commit31ae915

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

‎provisioner/terraform/executor.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ func (e *executor) init(ctx, killCtx context.Context, logr logSink) error {
222222
e.mut.Lock()
223223
defere.mut.Unlock()
224224

225+
// Read .terraform.lock.hcl content before running terraform init
226+
lockFilePath:=getTerraformLockFilePath(e.workdir)
227+
preInitLockFileContent,_:=os.ReadFile(lockFilePath)
228+
225229
outWriter,doneOut:=logWriter(logr,proto.LogLevel_DEBUG)
226230
errWriter,doneErr:=logWriter(logr,proto.LogLevel_ERROR)
227231
deferfunc() {
@@ -242,6 +246,29 @@ func (e *executor) init(ctx, killCtx context.Context, logr logSink) error {
242246
}
243247

244248
err:=e.execWriteOutput(ctx,killCtx,args,e.basicEnv(),outWriter,errBuf)
249+
250+
// Check if .terraform.lock.hcl was modified after terraform init
251+
postInitLockFileContent,_:=os.ReadFile(lockFilePath)
252+
diff:=generateFileDiff(preInitLockFileContent,postInitLockFileContent)
253+
ifdiff!="" {
254+
// Log informational message about lock file changes with diff
255+
infoMsg:="INFO: .terraform.lock.hcl was modified during 'terraform init'. "+
256+
"This is normal when Terraform downloads providers or updates dependencies. "+
257+
"See https://developer.hashicorp.com/terraform/language/files/dependency-lock#understanding-lock-file-changes "+
258+
"for more information about lock file changes."
259+
260+
// Write info message to debug stream
261+
ifoutWriter!=nil {
262+
_,_=outWriter.Write([]byte(infoMsg+"\n"))
263+
_,_=outWriter.Write([]byte("\nLock file changes:\n"+diff+"\n"))
264+
}
265+
266+
e.logger.Info(ctx,"terraform lock file modified during init",
267+
slog.F("lock_file_path",lockFilePath),
268+
slog.F("diff",diff),
269+
)
270+
}
271+
245272
varexitErr*exec.ExitError
246273
ifxerrors.As(err,&exitErr) {
247274
ifbytes.Contains(errBuf.b.Bytes(), []byte("text file busy")) {
@@ -259,6 +286,53 @@ func getStateFilePath(workdir string) string {
259286
returnfilepath.Join(workdir,"terraform.tfstate")
260287
}
261288

289+
funcgetTerraformLockFilePath(workdirstring)string {
290+
returnfilepath.Join(workdir,".terraform.lock.hcl")
291+
}
292+
293+
// generateFileDiff generates a simple diff between two file contents.
294+
// Returns empty string if files are identical.
295+
funcgenerateFileDiff(beforeContent,afterContent []byte)string {
296+
ifbytes.Equal(beforeContent,afterContent) {
297+
return""
298+
}
299+
300+
// Simple line-by-line diff
301+
beforeLines:=strings.Split(string(beforeContent),"\n")
302+
afterLines:=strings.Split(string(afterContent),"\n")
303+
304+
vardiff strings.Builder
305+
diff.WriteString("--- .terraform.lock.hcl (before terraform init)\n")
306+
diff.WriteString("+++ .terraform.lock.hcl (after terraform init)\n")
307+
308+
// Simple diff showing added/removed lines
309+
beforeMap:=make(map[string]bool)
310+
for_,line:=rangebeforeLines {
311+
beforeMap[line]=true
312+
}
313+
314+
afterMap:=make(map[string]bool)
315+
for_,line:=rangeafterLines {
316+
afterMap[line]=true
317+
}
318+
319+
// Show removed lines
320+
for_,line:=rangebeforeLines {
321+
if!afterMap[line]&&strings.TrimSpace(line)!="" {
322+
diff.WriteString("- "+line+"\n")
323+
}
324+
}
325+
326+
// Show added lines
327+
for_,line:=rangeafterLines {
328+
if!beforeMap[line]&&strings.TrimSpace(line)!="" {
329+
diff.WriteString("+ "+line+"\n")
330+
}
331+
}
332+
333+
returndiff.String()
334+
}
335+
262336
// revive:disable-next-line:flag-parameter
263337
func (e*executor)plan(ctx,killCtx context.Context,env,vars []string,logrlogSink,metadata*proto.Metadata) (*proto.PlanComplete,error) {
264338
ctx,span:=e.server.startTrace(ctx,tracing.FuncName())

‎provisioner/terraform/executor_internal_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,41 @@ func TestOnlyDataResources(t *testing.T) {
173173
})
174174
}
175175
}
176+
177+
funcTestGetTerraformLockFilePath(t*testing.T) {
178+
t.Parallel()
179+
180+
workdir:="/tmp/test"
181+
expected:=filepath.Join(workdir,".terraform.lock.hcl")
182+
got:=getTerraformLockFilePath(workdir)
183+
require.Equal(t,expected,got)
184+
}
185+
186+
funcTestGenerateFileDiff(t*testing.T) {
187+
t.Parallel()
188+
189+
// Test with identical content
190+
content:= []byte("line1\nline2\nline3")
191+
diff:=generateFileDiff(content,content)
192+
require.Equal(t,"",diff)
193+
194+
// Test with different content
195+
content1:= []byte("line1\nline2\nline3")
196+
content2:= []byte("line1\nmodified line2\nline3\nnew line4")
197+
diff=generateFileDiff(content1,content2)
198+
require.NotEmpty(t,diff)
199+
require.Contains(t,diff,"--- .terraform.lock.hcl (before terraform init)")
200+
require.Contains(t,diff,"+++ .terraform.lock.hcl (after terraform init)")
201+
require.Contains(t,diff,"- line2")
202+
require.Contains(t,diff,"+ modified line2")
203+
require.Contains(t,diff,"+ new line4")
204+
205+
// Test with empty before content (new file)
206+
emptyContent:= []byte("")
207+
newContent:= []byte("provider\"aws\" {\n version =\"5.0.0\"\n}")
208+
diff=generateFileDiff(emptyContent,newContent)
209+
require.NotEmpty(t,diff)
210+
require.Contains(t,diff,"+ provider\"aws\" {")
211+
require.Contains(t,diff,"+ version =\"5.0.0\"")
212+
require.Contains(t,diff,"+ }")
213+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp