feat(provisioner): associate resources with coder_devcontainer#21602
feat(provisioner): associate resources with coder_devcontainer#21602DanielleMaywood merged 6 commits intomainfrom
coder_devcontainer#21602Conversation
3fb3fe6 to
6d2900e
Compare
6d2900e to
68c3ab5
Compare
| func dependsOnDevcontainer(graph *gographviz.Graph, dc *proto.Devcontainer, resourceAgentID string, resource *tfjson.StateResource) bool { | ||
| // Plan: we need to find if there is an edge between the resource and the devcontainer. | ||
| if dc.SubagentId == "" && resourceAgentID == "" { | ||
| resourceNodeSuffix := fmt.Sprintf(`] %s.%s (expand)"`, resource.Type, resource.Name) | ||
| agentNodeSuffix := fmt.Sprintf(`] coder_devcontainer.%s (expand)"`, dc.Name) | ||
|
|
||
| // Traverse the graph to check if the coder_<resource_type> depends on coder_devcontainer. | ||
| for _, dst := range graph.Edges.SrcToDsts { | ||
| for _, edges := range dst { | ||
| for _, edge := range edges { | ||
| if strings.HasSuffix(edge.Src, resourceNodeSuffix) && | ||
| strings.HasSuffix(edge.Dst, agentNodeSuffix) { | ||
| return true | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return false | ||
| } | ||
|
|
||
| // Provision: subagent ID and child resource ID are present | ||
| return dc.SubagentId == resourceAgentID | ||
| } |
There was a problem hiding this comment.
(nit, non-blocking): Could refactor alongside dependsOnAgent given that there are minimal differences between the two functions. Maybe not worth it yet though, so omakase.
There was a problem hiding this comment.
We could do the following:
Introduce a new function resourceDependsOn
// resourceDependsOn checks if a resource depends on a target entity (agent or devcontainer).
// During Plan phase (when IDs aren't available), it uses graph edge analysis.
// During Provision phase (when IDs are present), it compares IDs directly.
func resourceDependsOn(graph *gographviz.Graph, resource *tfjson.StateResource, resourceTargetID, targetType, targetName, targetID string) bool {
// Provision: IDs available, compare directly
if targetID != "" || resourceTargetID != "" {
return targetID == resourceTargetID
}
// Plan: IDs not yet available, check graph edges
resourceNodeSuffix := fmt.Sprintf(`] %s.%s (expand)"`, resource.Type, resource.Name)
targetNodeSuffix := fmt.Sprintf(`] %s.%s (expand)"`, targetType, targetName)
for _, dst := range graph.Edges.SrcToDsts {
for _, edges := range dst {
for _, edge := range edges {
if strings.HasSuffix(edge.Src, resourceNodeSuffix) &&
strings.HasSuffix(edge.Dst, targetNodeSuffix) {
return true
}
}
}
}
return false
}As well as some constants
// Terraform resource type constants for the Coder provider.
const (
tfCoderAgent = "coder_agent"
tfCoderDevcontainer = "coder_devcontainer"
...
)And then the callsites could look like
resourceDependsOn(graph, resource, attrs.AgentID, tfCoderAgent, agent.Name, agent.Id)resourceDependsOn(graph, resource, attrs.AgentID, tfCoderDevcontainer, dc.Name, dc.SubagentId)There was a problem hiding this comment.
Yeah, I was thinking along those lines. Doesn't necessarily have to be in this PR though.
There was a problem hiding this comment.
Will do it in a follow-up PR then
Documentation CheckUpdates Needed
The note should be updated to reflect that these resources CAN now be attached to dev containers when using the Automated review via Coder Tasks |
Documentation CheckUpdates Needed
New Documentation Needed
Example pattern to document: resource "coder_devcontainer" "dev" {
agent_id = coder_agent.main.id
workspace_folder = "/workspace"
}
resource "coder_app" "devcontainer-app" {
agent_id = coder_devcontainer.dev.subagent_id
slug = "devcontainer-app"
}
resource "coder_script" "devcontainer-script" {
agent_id = coder_devcontainer.dev.subagent_id
display_name = "Devcontainer Script"
script = "echo hello"
run_on_start = true
}
resource "coder_env" "devcontainer-env" {
agent_id = coder_devcontainer.dev.subagent_id
name = "MY_VAR"
value = "my-value"
}Automated review via Coder Tasks |
Closes coder/internal#1239
Allow associating
coder_env,coder_scriptandcoder_appwithcoder_devcontainerresource. To do this we make use of the newly addedsubagent_idfield in thecoder_devcontainerresource added in coder/terraform-provider-coder#474