Skip to content

Commit 2a47980

Browse files
committed
fix: create new template version when tfvars change
1 parent ee9ac22 commit 2a47980

File tree

2 files changed

+313
-71
lines changed

2 files changed

+313
-71
lines changed

internal/provider/template_resource.go

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/json"
77
"fmt"
88
"io"
9+
"slices"
910
"strings"
1011

1112
"cdr.dev/slog"
@@ -1053,7 +1054,7 @@ func markActive(ctx context.Context, client *codersdk.Client, templateID uuid.UU
10531054
ID: versionID,
10541055
})
10551056
if err != nil {
1056-
return fmt.Errorf("Failed to update active template version: %s", err)
1057+
return fmt.Errorf("failed to update active template version: %s", err)
10571058
}
10581059
tflog.Info(ctx, "marked template version as active")
10591060
return nil
@@ -1231,8 +1232,9 @@ type LastVersionsByHash = map[string][]PreviousTemplateVersion
12311232
var LastVersionsKey = "last_versions"
12321233

12331234
type PreviousTemplateVersion struct {
1234-
ID uuid.UUID `json:"id"`
1235-
Name string `json:"name"`
1235+
ID uuid.UUID `json:"id"`
1236+
Name string `json:"name"`
1237+
TFVars map[string]string
12361238
}
12371239

12381240
type privateState interface {
@@ -1244,18 +1246,24 @@ func (v Versions) setPrivateState(ctx context.Context, ps privateState) (diags d
12441246
lv := make(LastVersionsByHash)
12451247
for _, version := range v {
12461248
vbh, ok := lv[version.DirectoryHash.ValueString()]
1249+
tfVars := make(map[string]string, len(version.TerraformVariables))
1250+
for _, tfVar := range version.TerraformVariables {
1251+
tfVars[tfVar.Name.ValueString()] = tfVar.Value.ValueString()
1252+
}
12471253
// Store the IDs and names of all versions with the same directory hash,
12481254
// in the order they appear
12491255
if ok {
12501256
lv[version.DirectoryHash.ValueString()] = append(vbh, PreviousTemplateVersion{
1251-
ID: version.ID.ValueUUID(),
1252-
Name: version.Name.ValueString(),
1257+
ID: version.ID.ValueUUID(),
1258+
Name: version.Name.ValueString(),
1259+
TFVars: tfVars,
12531260
})
12541261
} else {
12551262
lv[version.DirectoryHash.ValueString()] = []PreviousTemplateVersion{
12561263
{
1257-
ID: version.ID.ValueUUID(),
1258-
Name: version.Name.ValueString(),
1264+
ID: version.ID.ValueUUID(),
1265+
Name: version.Name.ValueString(),
1266+
TFVars: tfVars,
12591267
},
12601268
}
12611269
}
@@ -1269,6 +1277,13 @@ func (v Versions) setPrivateState(ctx context.Context, ps privateState) (diags d
12691277
}
12701278

12711279
func (planVersions Versions) reconcileVersionIDs(lv LastVersionsByHash, configVersions Versions) {
1280+
// We remove versions that we've matched from `lv`, so make a copy for
1281+
// resolving tfvar changes at the end.
1282+
fullLv := make(LastVersionsByHash)
1283+
for k, v := range lv {
1284+
fullLv[k] = slices.Clone(v)
1285+
}
1286+
12721287
for i := range planVersions {
12731288
prevList, ok := lv[planVersions[i].DirectoryHash.ValueString()]
12741289
// If not in state, mark as known after apply since we'll create a new version.
@@ -1308,4 +1323,47 @@ func (planVersions Versions) reconcileVersionIDs(lv LastVersionsByHash, configVe
13081323
lv[planVersions[i].DirectoryHash.ValueString()] = prevList[1:]
13091324
}
13101325
}
1326+
1327+
// If only the Terraform variables have changed,
1328+
// we need to create a new version with the new variables.
1329+
for i := range planVersions {
1330+
if !planVersions[i].ID.IsUnknown() {
1331+
prevs, ok := fullLv[planVersions[i].DirectoryHash.ValueString()]
1332+
if !ok {
1333+
continue
1334+
}
1335+
if tfVariablesChanged(prevs, &planVersions[i]) {
1336+
planVersions[i].ID = NewUUIDUnknown()
1337+
// We could always set the name to unknown here, to generate a
1338+
// random one (this is what the Web UI currently does when
1339+
// only updating tfvars).
1340+
// However, I think it'd be weird if the provider just started
1341+
// ignoring the name you set in the config, we'll instead
1342+
// require that users update the name if they update the tfvars.
1343+
if configVersions[i].Name.IsNull() {
1344+
planVersions[i].Name = types.StringUnknown()
1345+
}
1346+
}
1347+
}
1348+
}
1349+
}
1350+
1351+
func tfVariablesChanged(prevs []PreviousTemplateVersion, planned *TemplateVersion) bool {
1352+
for _, prev := range prevs {
1353+
if prev.ID == planned.ID.ValueUUID() {
1354+
// If the previous version has no TFVars, then it was created using
1355+
// an older provider version.
1356+
if prev.TFVars == nil {
1357+
return true
1358+
}
1359+
for _, tfVar := range planned.TerraformVariables {
1360+
if prev.TFVars[tfVar.Name.ValueString()] != tfVar.Value.ValueString() {
1361+
return true
1362+
}
1363+
}
1364+
return false
1365+
}
1366+
}
1367+
return true
1368+
13111369
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy