@@ -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