Skip to content

Commit 35e4bf8

Browse files
committed
fix: ensure prebuilt workspace agent tokens are reused when a prebuild agent reinitializes
1 parent 99a9adc commit 35e4bf8

File tree

2 files changed

+71
-23
lines changed

2 files changed

+71
-23
lines changed

provisioner/terraform/executor.go

+64-11
Original file line numberDiff line numberDiff line change
@@ -261,17 +261,6 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
261261
e.mut.Lock()
262262
defer e.mut.Unlock()
263263

264-
// TODO: defunct?
265-
// var isPrebuild bool
266-
// for _, v := range env {
267-
// if envName(v) == provider.IsPrebuildEnvironmentVariable() && envVar(v) == "true" {
268-
// isPrebuild = true
269-
// break
270-
// }
271-
// }
272-
273-
// _ = isPrebuild
274-
275264
planfilePath := getPlanFilePath(e.workdir)
276265
args := []string{
277266
"plan",
@@ -341,6 +330,68 @@ func onlyDataResources(sm tfjson.StateModule) tfjson.StateModule {
341330
return filtered
342331
}
343332

333+
func (e *executor) logResourceReplacements(ctx context.Context, plan *tfjson.Plan) {
334+
if plan == nil {
335+
return
336+
}
337+
338+
if len(plan.ResourceChanges) == 0 {
339+
return
340+
}
341+
var (
342+
count int
343+
replacements = make(map[string][]string, len(plan.ResourceChanges))
344+
)
345+
346+
for _, ch := range plan.ResourceChanges {
347+
// No change, no problem!
348+
if ch.Change == nil {
349+
continue
350+
}
351+
352+
// No-op change, no problem!
353+
if ch.Change.Actions.NoOp() {
354+
continue
355+
}
356+
357+
// No replacements, no problem!
358+
if len(ch.Change.ReplacePaths) == 0 {
359+
continue
360+
}
361+
362+
// Replacing our resources, no problem!
363+
if strings.Index(ch.Type, "coder_") == 0 {
364+
continue
365+
}
366+
367+
for _, p := range ch.Change.ReplacePaths {
368+
var path string
369+
switch p := p.(type) {
370+
case []interface{}:
371+
segs := p
372+
list := make([]string, 0, len(segs))
373+
for _, s := range segs {
374+
list = append(list, fmt.Sprintf("%v", s))
375+
}
376+
path = strings.Join(list, ".")
377+
default:
378+
path = fmt.Sprintf("%v", p)
379+
}
380+
381+
replacements[ch.Address] = append(replacements[ch.Address], path)
382+
}
383+
384+
count++
385+
}
386+
387+
if count > 0 {
388+
e.server.logger.Warn(ctx, "plan introduces resource changes", slog.F("count", count))
389+
for n, p := range replacements {
390+
e.server.logger.Warn(ctx, "resource will be replaced!", slog.F("name", n), slog.F("replacement_paths", strings.Join(p, ",")))
391+
}
392+
}
393+
}
394+
344395
// planResources must only be called while the lock is held.
345396
func (e *executor) planResources(ctx, killCtx context.Context, planfilePath string) (*State, json.RawMessage, error) {
346397
ctx, span := e.server.startTrace(ctx, tracing.FuncName())
@@ -351,6 +402,8 @@ func (e *executor) planResources(ctx, killCtx context.Context, planfilePath stri
351402
return nil, nil, xerrors.Errorf("show terraform plan file: %w", err)
352403
}
353404

405+
e.logResourceReplacements(ctx, plan)
406+
354407
rawGraph, err := e.graph(ctx, killCtx)
355408
if err != nil {
356409
return nil, nil, xerrors.Errorf("graph: %w", err)

provisioner/terraform/provision.go

+7-12
Original file line numberDiff line numberDiff line change
@@ -272,21 +272,16 @@ func provisionEnv(
272272
)
273273
if metadata.GetIsPrebuild() {
274274
env = append(env, provider.IsPrebuildEnvironmentVariable()+"=true")
275+
}
276+
tokens := metadata.GetRunningAgentAuthTokens()
277+
if len(tokens) == 1 {
278+
env = append(env, provider.RunningAgentTokenEnvironmentVariable("")+"="+tokens[0].Token)
275279
} else {
276-
// TODO: provide an agentID to these functions so that we provide the right token
277-
// for single agent support, we use the zero value "" as the agentID
278-
// TODO: looks like we only provide agent tokens for reinit if metadata.GetIsPrebuild() is false
279-
// check this for consistency wherever else we use the isPrebuild attribute from the Proto and where we use the env derived from it.
280-
const singleAgentID = ""
281-
tokens := metadata.GetRunningAgentAuthTokens()
282-
var token string
283280
for _, t := range tokens {
284-
if t.AgentId == singleAgentID {
285-
token = t.Token
286-
break
287-
}
281+
// If there are multiple agents, provide all the tokens to terraform so that it can
282+
// choose the correct one for each agent ID.
283+
env = append(env, provider.RunningAgentTokenEnvironmentVariable(t.AgentId)+"="+t.Token)
288284
}
289-
env = append(env, provider.RunningAgentTokenEnvironmentVariable(singleAgentID)+"="+token)
290285
}
291286
for key, value := range provisionersdk.AgentScriptEnv() {
292287
env = append(env, key+"="+value)

0 commit comments

Comments
 (0)