@@ -3,10 +3,13 @@ package provider
33import (
44 "context"
55 "fmt"
6+ "os"
67 "path/filepath"
78 "reflect"
89 "strings"
910
11+ "github.com/hashicorp/terraform-plugin-log/tflog"
12+
1013 "github.com/google/uuid"
1114 "github.com/hashicorp/go-cty/cty"
1215 "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -22,10 +25,54 @@ func agentResource() *schema.Resource {
2225 SchemaVersion : 1 ,
2326
2427 Description : "Use this resource to associate an agent." ,
25- CreateContext : func (_ context.Context , resourceData * schema.ResourceData , i interface {}) diag.Diagnostics {
28+ CreateContext : func (ctx context.Context , resourceData * schema.ResourceData , i interface {}) diag.Diagnostics {
2629 // This should be a real authentication token!
2730 resourceData .SetId (uuid .NewString ())
28- err := resourceData .Set ("token" , uuid .NewString ())
31+
32+ // CODER_RUNNING_WORKSPACE_AGENT_TOKEN is *only* used for prebuilds. We pass it down when we want to rebuild a prebuilt workspace
33+ // but not generate a new agent token. The provisionerdserver will retrieve this token and push it down to
34+ // here where it will be reused.
35+ // Context: the agent token is often used in immutable attributes of workspace resource (e.g. VM/container)
36+ // to initialize the agent, so if that value changes it will necessitate a replacement of that resource, thus
37+ // obviating the whole point of the prebuild.
38+ //
39+ // The default path is for a new token to be generated on each new resource creation.
40+ // TODO: add logging when the running token is actually used.
41+ var token string
42+
43+ isPrebuild := helpers .OptionalEnv (IsPrebuildEnvironmentVariable ()) == "true"
44+ if ! isPrebuild {
45+ token = os .Getenv (RunningAgentTokenEnvironmentVariable ())
46+ }
47+
48+ allEnv := make (map [string ]interface {})
49+ for _ , v := range os .Environ () {
50+ split := strings .Split (v , "=" )
51+ var key , val string
52+ if len (split ) > 0 {
53+ key = split [0 ]
54+ }
55+ if len (split ) > 1 {
56+ val = split [1 ]
57+ }
58+
59+ allEnv [key ] = val
60+ }
61+
62+ allEnv ["is_prebuild" ] = fmt .Sprintf ("%v" , isPrebuild )
63+
64+ if token == "" {
65+ token = uuid .NewString ()
66+ if ! isPrebuild {
67+ tflog .Warn (ctx , "NOT USING EXISTING AGENT TOKEN" , allEnv )
68+ }
69+ } else {
70+ if ! isPrebuild {
71+ tflog .Info (ctx , "IS USING EXISTING AGENT TOKEN" , allEnv )
72+ }
73+ }
74+
75+ err := resourceData .Set ("token" , token )
2976 if err != nil {
3077 return diag .FromErr (err )
3178 }
@@ -469,3 +516,7 @@ func updateInitScript(resourceData *schema.ResourceData, i interface{}) diag.Dia
469516 }
470517 return nil
471518}
519+
520+ func RunningAgentTokenEnvironmentVariable () string {
521+ return "CODER_RUNNING_WORKSPACE_AGENT_TOKEN"
522+ }
0 commit comments