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

chore: pass previous values into terraform apply#17696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Emyrk merged 23 commits intomainfromstevenmasley/monotonic
May 12, 2025
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
23 commits
Select commitHold shift + click to select a range
d565cb5
chore: pass previous values into the terraform apply
EmyrkMay 6, 2025
b6d3d67
update preview
EmyrkMay 7, 2025
520fe49
make gen
EmyrkMay 7, 2025
690daac
test: fix asserted test error text
EmyrkMay 7, 2025
692bab8
remove from plan request
EmyrkMay 7, 2025
81ad901
remove previous values from plan
EmyrkMay 7, 2025
c917ab0
remove from plan request
EmyrkMay 7, 2025
28b2b9f
Merge remote-tracking branch 'origin/main' into stevenmasley/monotonic
EmyrkMay 9, 2025
3fb8a22
reset go.mod
EmyrkMay 9, 2025
2b642a6
update preview
EmyrkMay 9, 2025
fd6cdf5
update versions
EmyrkMay 9, 2025
2b41b8f
Merge remote-tracking branch 'origin/main' into stevenmasley/monotonic
EmyrkMay 12, 2025
8a0dab1
chore: add previous values to plan request
EmyrkMay 12, 2025
d9fc4cc
make gen
EmyrkMay 12, 2025
fb2f081
pass in previous values to the plan step
EmyrkMay 12, 2025
97a99aa
pass previous values in workspace build
EmyrkMay 12, 2025
9f3a8fd
Merge remote-tracking branch 'origin/main' into stevenmasley/monotonic
EmyrkMay 12, 2025
bc38bfa
revert go mod changes
EmyrkMay 12, 2025
a7ab88c
make gen
EmyrkMay 12, 2025
52dcd80
Merge branch 'main' into stevenmasley/monotonic
EmyrkMay 12, 2025
3eb22f4
Merge remote-tracking branch 'origin/main' into stevenmasley/monotonic
EmyrkMay 12, 2025
cb0f145
gen
EmyrkMay 12, 2025
2774c07
make gen
EmyrkMay 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
NextNext commit
chore: pass previous values into the terraform apply
remove custom monotonic check
  • Loading branch information
@Emyrk
Emyrk committedMay 6, 2025
commitd565cb57797bb8ed46a4b1fb668cf3b8da3becfb
35 changes: 29 additions & 6 deletionscoderd/provisionerdserver/provisionerdserver.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -543,6 +543,28 @@ func (s *server) acquireProtoJob(ctx context.Context, job database.ProvisionerJo
return nil, failJob(fmt.Sprintf("convert workspace transition: %s", err))
}

// A previous workspace build exists
var lastWorkspaceBuildParameters []database.WorkspaceBuildParameter
if workspaceBuild.BuildNumber > 1 {
// TODO: Should we fetch the last build that succeeded? This fetches the
// previous build regardless of the status of the build.
Comment on lines +555 to +556
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If we check for the last successful build, we could end up with no builds. What do we do then? Do we just settle for the last build? IMO just checking the previous build is simpler conceptually, and is more likely to be what users expect.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yea, the wsbuilder just takes the last build regardless of status. Just feels a bit off since the tfstate is different if the previous failed. 🤷‍♂️

buildNum := workspaceBuild.BuildNumber - 1
previous, err := s.Database.GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx, database.GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams{
WorkspaceID: workspaceBuild.WorkspaceID,
BuildNumber: buildNum,
})
Comment on lines +555 to +561
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

What problem are weactually trying to solve here?

wsbuilder already fetches the last build parameters, if they exist:

func (b*Builder)getLastBuildParameters() ([]database.WorkspaceBuildParameter,error) {
ifb.lastBuildParameters!=nil {
return*b.lastBuildParameters,nil
}
bld,err:=b.getLastBuild()
ifxerrors.Is(err,sql.ErrNoRows) {
// if the build doesn't exist, then clearly there can be no parameters.
b.lastBuildParameters=&[]database.WorkspaceBuildParameter{}
return*b.lastBuildParameters,nil
}
iferr!=nil {
returnnil,xerrors.Errorf("get last build to get parameters: %w",err)
}
values,err:=b.store.GetWorkspaceBuildParameters(b.ctx,bld.ID)
iferr!=nil&&!xerrors.Is(err,sql.ErrNoRows) {
returnnil,xerrors.Errorf("get last build %s parameters: %w",bld.ID,err)
}
b.lastBuildParameters=&values
returnvalues,nil
}

Given that this is the case, why do we need to do this extra work forall jobs? Isn't this just for template version import jobs?

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

That does it incoder/coder at workspace create yes, but this passes the previous values to the terraform via env vars.

The terraform provider now enforces monotonicity:coder/terraform-provider-coder#392

So this is duplicating that check in wsbuilder atterraform apply/plan.
For dynamic parameters, we skip validating params inwsbuilder, so we need to make sure validation is applied in terraform

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Maybe I could pass the values from wsbuilder to here via the job? Rather than refetch

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I like that approach --wsbuilder is then still responsible for fetching all of the various baggage related to a workspace build, but just defers the validation part to Terraform.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@johnstcn actually, as much as I'd like to havewsbuilder be the source of truth. We fetch everything again at this step in the workspace build.

Current params, workspace data, external auth, etc.

We store very little in the job payload:

typeWorkspaceProvisionJobstruct {
WorkspaceBuildID uuid.UUID`json:"workspace_build_id"`
DryRunbool`json:"dry_run"`
LogLevelstring`json:"log_level,omitempty"`
PrebuiltWorkspaceBuildStage sdkproto.PrebuiltWorkspaceBuildStage`json:"prebuilt_workspace_stage,omitempty"`
}

So I'm going to keep this as a refetching. Ideally I would use the same function to fetch the previous params in both cases, however atwsbuild thelatestbuild is the "previous". And at the point I added code, the previous isbuild -1.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Ahh... gotcha. That's unfortunate :(

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

It is, I think it would be a large refactor to move all the fields into wsbuilder

if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
return nil, xerrors.Errorf("get last build with number=%d: %w", buildNum, err)
}

if err == nil {
lastWorkspaceBuildParameters, err = s.Database.GetWorkspaceBuildParameters(ctx, previous.ID)
if err != nil {
return nil, xerrors.Errorf("get last build parameters %q: %w", previous.ID, err)
}
}
}

workspaceBuildParameters, err := s.Database.GetWorkspaceBuildParameters(ctx, workspaceBuild.ID)
if err != nil {
return nil, failJob(fmt.Sprintf("get workspace build parameters: %s", err))
Expand DownExpand Up@@ -619,12 +641,13 @@ func (s *server) acquireProtoJob(ctx context.Context, job database.ProvisionerJo

protoJob.Type = &proto.AcquiredJob_WorkspaceBuild_{
WorkspaceBuild: &proto.AcquiredJob_WorkspaceBuild{
WorkspaceBuildId: workspaceBuild.ID.String(),
WorkspaceName: workspace.Name,
State: workspaceBuild.ProvisionerState,
RichParameterValues: convertRichParameterValues(workspaceBuildParameters),
VariableValues: asVariableValues(templateVariables),
ExternalAuthProviders: externalAuthProviders,
WorkspaceBuildId: workspaceBuild.ID.String(),
WorkspaceName: workspace.Name,
State: workspaceBuild.ProvisionerState,
RichParameterValues: convertRichParameterValues(workspaceBuildParameters),
PreviousParameterValues: convertRichParameterValues(lastWorkspaceBuildParameters),
VariableValues: asVariableValues(templateVariables),
ExternalAuthProviders: externalAuthProviders,
Metadata: &sdkproto.Metadata{
CoderUrl: s.AccessURL.String(),
WorkspaceTransition: transition,
Expand Down
33 changes: 7 additions & 26 deletionscodersdk/richparameters.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
package codersdk

import (
"strconv"

"golang.org/x/xerrors"

"github.com/coder/terraform-provider-coder/v2/provider"
Expand DownExpand Up@@ -60,29 +58,6 @@ func validateBuildParameter(richParameter TemplateVersionParameter, buildParamet
value = richParameter.DefaultValue
}

if lastBuildParameter != nil && lastBuildParameter.Value != "" && richParameter.Type == "number" && len(richParameter.ValidationMonotonic) > 0 {
prev, err := strconv.Atoi(lastBuildParameter.Value)
if err != nil {
return xerrors.Errorf("previous parameter value is not a number: %s", lastBuildParameter.Value)
}

current, err := strconv.Atoi(buildParameter.Value)
if err != nil {
return xerrors.Errorf("current parameter value is not a number: %s", buildParameter.Value)
}

switch richParameter.ValidationMonotonic {
case MonotonicOrderIncreasing:
if prev > current {
return xerrors.Errorf("parameter value must be equal or greater than previous value: %d", prev)
}
case MonotonicOrderDecreasing:
if prev < current {
return xerrors.Errorf("parameter value must be equal or lower than previous value: %d", prev)
}
}
}

if len(richParameter.Options) > 0 {
var matched bool
for _, opt := range richParameter.Options {
Expand DownExpand Up@@ -119,7 +94,13 @@ func validateBuildParameter(richParameter TemplateVersionParameter, buildParamet
Error: richParameter.ValidationError,
Monotonic: string(richParameter.ValidationMonotonic),
}
return validation.Valid(richParameter.Type, value)
var prev *string
// Empty strings should be rejected, however the previous behavior was to
// accept the empty string ("") as a `nil` previous value.
if lastBuildParameter != nil && lastBuildParameter.Value != "" {
prev = &lastBuildParameter.Value
}
return validation.Valid(richParameter.Type, value, prev)
}

func findBuildParameter(params []WorkspaceBuildParameter, parameterName string) (*WorkspaceBuildParameter, bool) {
Expand Down
4 changes: 2 additions & 2 deletionsgo.mod
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,7 +101,7 @@ require (
github.com/coder/quartz v0.1.2
github.com/coder/retry v1.5.1
github.com/coder/serpent v0.10.0
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250417100258-c86bb5c3ddcd
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250506184715-e011f733bf27
github.com/coder/websocket v1.8.13
github.com/coder/wgtunnel v0.1.13-0.20240522110300-ade90dfb2da0
github.com/coreos/go-oidc/v3 v3.14.1
Expand DownExpand Up@@ -488,7 +488,7 @@ require (

require (
github.com/anthropics/anthropic-sdk-go v0.2.0-beta.3
github.com/coder/preview v0.0.1
github.com/coder/preview v0.0.2-0.20250506195323-154d86b5a92a
github.com/fsnotify/fsnotify v1.9.0
github.com/kylecarbs/aisdk-go v0.0.8
github.com/mark3labs/mcp-go v0.25.0
Expand Down
8 changes: 4 additions & 4 deletionsgo.sum
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -907,8 +907,8 @@ github.com/coder/pq v1.10.5-0.20240813183442-0c420cb5a048 h1:3jzYUlGH7ZELIH4XggX
github.com/coder/pq v1.10.5-0.20240813183442-0c420cb5a048/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs=
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0/go.mod h1:5UuS2Ts+nTToAMeOjNlnHFkPahrtDkmpydBen/3wgZc=
github.com/coder/preview v0.0.1 h1:2X5McKdMOZJILTIDf7qRplXKupT+91qTJBN67XUh5cA=
github.com/coder/preview v0.0.1/go.mod h1:eInDmOdSDF8cxCvapIvYkGRzmzvcvGAFL1HYqcA4g+E=
github.com/coder/preview v0.0.2-0.20250506195323-154d86b5a92a h1:tmtq3YgYE69PKA7n10WRFZPQnLp45N3jPOcpr4Ki6z4=
github.com/coder/preview v0.0.2-0.20250506195323-154d86b5a92a/go.mod h1:j2JOd9aN+pGLxBxOawtm+1pF3kgWdbn5xGvnDSqER+8=
github.com/coder/quartz v0.1.2 h1:PVhc9sJimTdKd3VbygXtS4826EOCpB1fXoRlLnCrE+s=
github.com/coder/quartz v0.1.2/go.mod h1:vsiCc+AHViMKH2CQpGIpFgdHIEQsxwm8yCscqKmzbRA=
github.com/coder/retry v1.5.1 h1:iWu8YnD8YqHs3XwqrqsjoBTAVqT9ml6z9ViJ2wlMiqc=
Expand All@@ -921,8 +921,8 @@ github.com/coder/tailscale v1.1.1-0.20250422090654-5090e715905e h1:nope/SZfoLB9M
github.com/coder/tailscale v1.1.1-0.20250422090654-5090e715905e/go.mod h1:1ggFFdHTRjPRu9Yc1yA7nVHBYB50w9Ce7VIXNqcW6Ko=
github.com/coder/terraform-config-inspect v0.0.0-20250107175719-6d06d90c630e h1:JNLPDi2P73laR1oAclY6jWzAbucf70ASAvf5mh2cME0=
github.com/coder/terraform-config-inspect v0.0.0-20250107175719-6d06d90c630e/go.mod h1:Gz/z9Hbn+4KSp8A2FBtNszfLSdT2Tn/uAKGuVqqWmDI=
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250417100258-c86bb5c3ddcd h1:FsIG6Fd0YOEK7D0Hl/CJywRA+Y6Gd5RQbSIa2L+/BmE=
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250417100258-c86bb5c3ddcd/go.mod h1:56/KdGYaA+VbwXJbTI8CA57XPfnuTxN8rjxbR34PbZw=
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250506184715-e011f733bf27 h1:CLJwMqst39+wfFehYQzVOiG5uXUtC5fbAZ3/EpxOWos=
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250506184715-e011f733bf27/go.mod h1:2kaBpn5k9ZWtgKq5k4JbkVZG9DzEqR4mJSmpdshcO+s=
github.com/coder/trivy v0.0.0-20250409153844-e6b004bc465a h1:yryP7e+IQUAArlycH4hQrjXQ64eRNbxsV5/wuVXHgME=
github.com/coder/trivy v0.0.0-20250409153844-e6b004bc465a/go.mod h1:dDvq9axp3kZsT63gY2Znd1iwzfqDq3kXbQnccIrjRYY=
github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE=
Expand Down
9 changes: 6 additions & 3 deletionsprovisioner/terraform/provision.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -152,7 +152,7 @@ func (s *server) Plan(

s.logger.Debug(ctx, "ran initialization")

env, err := provisionEnv(sess.Config, request.Metadata, request.RichParameterValues, request.ExternalAuthProviders)
env, err := provisionEnv(sess.Config, request.Metadata, request.PreviousParameterValues, request.RichParameterValues, request.ExternalAuthProviders)
if err != nil {
return provisionersdk.PlanErrorf("setup env: %s", err)
}
Expand DownExpand Up@@ -205,7 +205,7 @@ func (s *server) Apply(

// Earlier in the session, Plan() will have written the state file and the plan file.
statefilePath := getStateFilePath(sess.WorkDirectory)
env, err := provisionEnv(sess.Config, request.Metadata, nil, nil)
env, err := provisionEnv(sess.Config, request.Metadata, nil, nil, nil)
if err != nil {
return provisionersdk.ApplyErrorf("provision env: %s", err)
}
Expand DownExpand Up@@ -236,7 +236,7 @@ func planVars(plan *proto.PlanRequest) ([]string, error) {

func provisionEnv(
config *proto.Config, metadata *proto.Metadata,
richParams []*proto.RichParameterValue, externalAuth []*proto.ExternalAuthProvider,
previousParams,richParams []*proto.RichParameterValue, externalAuth []*proto.ExternalAuthProvider,
) ([]string, error) {
env := safeEnviron()
ownerGroups, err := json.Marshal(metadata.GetWorkspaceOwnerGroups())
Expand DownExpand Up@@ -277,6 +277,9 @@ func provisionEnv(
for key, value := range provisionersdk.AgentScriptEnv() {
env = append(env, key+"="+value)
}
for _, param := range previousParams {
env = append(env, provider.ParameterEnvironmentVariablePrevious(param.Name)+"="+param.Value)
}
for _, param := range richParams {
env = append(env, provider.ParameterEnvironmentVariable(param.Name)+"="+param.Value)
}
Expand Down
6 changes: 5 additions & 1 deletionprovisioner/terraform/resources.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -749,13 +749,17 @@ func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph s
if err != nil {
return nil, xerrors.Errorf("decode map values for coder_parameter.%s: %w", resource.Name, err)
}
def := ""
if param.Default != nil {
def = *param.Default
}
protoParam := &proto.RichParameter{
Name: param.Name,
DisplayName: param.DisplayName,
Description: param.Description,
Type: param.Type,
Mutable: param.Mutable,
DefaultValue:param.Default,
DefaultValue:def,
Icon: param.Icon,
Required: !param.Optional,
// #nosec G115 - Safe conversion as parameter order value is expected to be within int32 range
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp