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

fix: create new template version when tfvars change#98

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
Show file tree
Hide file tree
Changes fromall commits
Commits
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
6 changes: 3 additions & 3 deletionsdocs/resources/template.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,15 +4,15 @@ page_title: "coderd_template Resource - terraform-provider-coderd"
subcategory: ""
description: |-
A Coder template.
Logs from building template versionsarestreamed from the provisionerwhenthe TF_LOG environment variableis INFO or higher.
Logs from building template versionscan be optionallystreamed from the provisionerby settingthe TF_LOG environment variableto INFO or higher.
When importing, the ID supplied can be either a template UUID retrieved via the API or <organization-name>/<template-name>.
---

# coderd_template (Resource)

A Coder template.

Logs from building template versionsarestreamed from the provisionerwhenthe `TF_LOG` environment variableis `INFO` or higher.
Logs from building template versionscan be optionallystreamed from the provisionerby settingthe `TF_LOG` environment variableto `INFO` or higher.

When importing, the ID supplied can be either a template UUID retrieved via the API or `<organization-name>/<template-name>`.

Expand DownExpand Up@@ -101,7 +101,7 @@ Optional:

- `active` (Boolean) Whether this version is the active version of the template. Only one version can be active at a time.
- `message` (String) A message describing the changes in this version of the template. Messages longer than 72 characters will be truncated.
- `name` (String) The name of the template version. Automatically generated if not provided. If provided, the name *must* change each time the directory contents are updated.
- `name` (String) The name of the template version. Automatically generated if not provided. If provided, the name *must* change each time the directory contents, or the `tf_vars` attribute are updated.
- `provisioner_tags` (Attributes Set) Provisioner tags for the template version. (see [below for nested schema](#nestedatt--versions--provisioner_tags))
- `tf_vars` (Attributes Set) Terraform variables for the template version. (see [below for nested schema](#nestedatt--versions--tf_vars))

Expand Down
78 changes: 68 additions & 10 deletionsinternal/provider/template_resource.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"io"
"slices"
"strings"

"cdr.dev/slog"
Expand DownExpand Up@@ -230,8 +231,8 @@ func (r *TemplateResource) Metadata(ctx context.Context, req resource.MetadataRe

func (r *TemplateResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "A Coder template.\n\nLogs from building template versionsare streamed from the provisioner " +
"whenthe `TF_LOG` environment variableis `INFO` or higher.\n\n" +
MarkdownDescription: "A Coder template.\n\nLogs from building template versionscan be optionally streamed from the provisioner " +
"by settingthe `TF_LOG` environment variableto `INFO` or higher.\n\n" +
"When importing, the ID supplied can be either a template UUID retrieved via the API or `<organization-name>/<template-name>`.",

Attributes: map[string]schema.Attribute{
Expand DownExpand Up@@ -395,7 +396,7 @@ func (r *TemplateResource) Schema(ctx context.Context, req resource.SchemaReques
Computed: true,
},
"name": schema.StringAttribute{
MarkdownDescription: "The name of the template version. Automatically generated if not provided. If provided, the name *must* change each time the directory contents are updated.",
MarkdownDescription: "The name of the template version. Automatically generated if not provided. If provided, the name *must* change each time the directory contents, or the `tf_vars` attribute are updated.",
Optional: true,
Computed: true,
Validators: []validator.String{
Expand DownExpand Up@@ -1053,7 +1054,7 @@ func markActive(ctx context.Context, client *codersdk.Client, templateID uuid.UU
ID: versionID,
})
if err != nil {
return fmt.Errorf("Failed to update active template version: %s", err)
return fmt.Errorf("failed to update active template version: %s", err)
}
tflog.Info(ctx, "marked template version as active")
return nil
Expand DownExpand Up@@ -1231,8 +1232,9 @@ type LastVersionsByHash = map[string][]PreviousTemplateVersion
var LastVersionsKey = "last_versions"

type PreviousTemplateVersion struct {
ID uuid.UUID `json:"id"`
Name string `json:"name"`
ID uuid.UUID `json:"id"`
Name string `json:"name"`
TFVars map[string]string `json:"tf_vars"`
}

type privateState interface {
Expand All@@ -1244,18 +1246,24 @@ func (v Versions) setPrivateState(ctx context.Context, ps privateState) (diags d
lv := make(LastVersionsByHash)
for _, version := range v {
vbh, ok := lv[version.DirectoryHash.ValueString()]
tfVars := make(map[string]string, len(version.TerraformVariables))
for _, tfVar := range version.TerraformVariables {
tfVars[tfVar.Name.ValueString()] = tfVar.Value.ValueString()
}
// Store the IDs and names of all versions with the same directory hash,
// in the order they appear
if ok {
lv[version.DirectoryHash.ValueString()] = append(vbh, PreviousTemplateVersion{
ID: version.ID.ValueUUID(),
Name: version.Name.ValueString(),
ID: version.ID.ValueUUID(),
Name: version.Name.ValueString(),
TFVars: tfVars,
})
} else {
lv[version.DirectoryHash.ValueString()] = []PreviousTemplateVersion{
{
ID: version.ID.ValueUUID(),
Name: version.Name.ValueString(),
ID: version.ID.ValueUUID(),
Name: version.Name.ValueString(),
TFVars: tfVars,
},
}
}
Expand All@@ -1269,6 +1277,13 @@ func (v Versions) setPrivateState(ctx context.Context, ps privateState) (diags d
}

func (planVersions Versions) reconcileVersionIDs(lv LastVersionsByHash, configVersions Versions) {
// We remove versions that we've matched from `lv`, so make a copy for
// resolving tfvar changes at the end.
fullLv := make(LastVersionsByHash)
for k, v := range lv {
fullLv[k] = slices.Clone(v)
}

for i := range planVersions {
prevList, ok := lv[planVersions[i].DirectoryHash.ValueString()]
// If not in state, mark as known after apply since we'll create a new version.
Expand DownExpand Up@@ -1308,4 +1323,47 @@ func (planVersions Versions) reconcileVersionIDs(lv LastVersionsByHash, configVe
lv[planVersions[i].DirectoryHash.ValueString()] = prevList[1:]
}
}

// If only the Terraform variables have changed,
// we need to create a new version with the new variables.
for i := range planVersions {
if !planVersions[i].ID.IsUnknown() {
prevs, ok := fullLv[planVersions[i].DirectoryHash.ValueString()]
if !ok {
continue
}
if tfVariablesChanged(prevs, &planVersions[i]) {
planVersions[i].ID = NewUUIDUnknown()
// We could always set the name to unknown here, to generate a
// random one (this is what the Web UI currently does when
// only updating tfvars).
// However, I think it'd be weird if the provider just started
// ignoring the name you set in the config, we'll instead
// require that users update the name if they update the tfvars.
if configVersions[i].Name.IsNull() {
planVersions[i].Name = types.StringUnknown()
}
}
}
}
}

func tfVariablesChanged(prevs []PreviousTemplateVersion, planned *TemplateVersion) bool {
for _, prev := range prevs {
if prev.ID == planned.ID.ValueUUID() {
// If the previous version has no TFVars, then it was created using
// an older provider version.
if prev.TFVars == nil {
return true
}
for _, tfVar := range planned.TerraformVariables {
if prev.TFVars[tfVar.Name.ValueString()] != tfVar.Value.ValueString() {
return true
}
}
return false
}
}
return true

}
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp