Skip to content

Commit fb43178

Browse files
committed
Add triggers support to spiceai_deployment resource
- Add triggers argument to spiceai_deployment to force new deployments - Document triggers usage in resource schema and examples - Warn users on delete that deployments are not stopped - Add mapPlanModifierRequiresReplace for triggers attribute - Add spicepod normalization and plan modifier tests
1 parent 4d3e112 commit fb43178

3 files changed

Lines changed: 354 additions & 1 deletion

File tree

examples/local-spice-api/main.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ resource "spiceai_app" "test" {
3636
resource "spiceai_deployment" "test" {
3737
app_id = spiceai_app.test.id
3838

39+
# Trigger new deployment when app configuration changes
40+
triggers = {
41+
spicepod = spiceai_app.test.spicepod
42+
image_tag = spiceai_app.test.image_tag
43+
replicas = spiceai_app.test.replicas
44+
}
45+
3946
# Use app defaults
4047
debug = false
4148
}

internal/provider/resource_deployment.go

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type DeploymentResource struct {
4040
type DeploymentResourceModel struct {
4141
ID types.String `tfsdk:"id"`
4242
AppID types.String `tfsdk:"app_id"`
43+
Triggers types.Map `tfsdk:"triggers"`
4344
ImageTag types.String `tfsdk:"image_tag"`
4445
Replicas types.Int64 `tfsdk:"replicas"`
4546
Branch types.String `tfsdk:"branch"`
@@ -66,8 +67,12 @@ func (r *DeploymentResource) Schema(ctx context.Context, req resource.SchemaRequ
6667
6768
A deployment uses the app's current spicepod configuration and deploys it to the Spice.ai cloud infrastructure. Deployments are immutable - any changes to deployment parameters will create a new deployment.
6869
70+
~> **Note:** Deployments are append-only log entries. Removing this resource from your configuration will only remove it from Terraform state - it will NOT stop or affect the running instance. To deploy new changes, modify the configuration or triggers to create a new deployment.
71+
6972
## Example Usage
7073
74+
### Basic Deployment
75+
7176
` + "```hcl" + `
7277
resource "spiceai_deployment" "example" {
7378
app_id = spiceai_app.example.id
@@ -82,6 +87,23 @@ resource "spiceai_deployment" "example" {
8287
commit_sha = "abc123def456"
8388
commit_message = "Deploy via Terraform"
8489
}
90+
` + "```" + `
91+
92+
### Deployment with Triggers
93+
94+
Use triggers to force a new deployment when external values change (similar to ` + "`null_resource`" + `):
95+
96+
` + "```hcl" + `
97+
resource "spiceai_deployment" "example" {
98+
app_id = spiceai_app.example.id
99+
100+
# Trigger new deployment when spicepod config changes
101+
triggers = {
102+
spicepod_hash = sha256(spiceai_app.example.spicepod)
103+
# Or trigger on any value change
104+
# deployment_version = "v1.2.3"
105+
}
106+
}
85107
` + "```",
86108

87109
Attributes: map[string]schema.Attribute{
@@ -99,6 +121,14 @@ resource "spiceai_deployment" "example" {
99121
stringplanmodifier.RequiresReplace(),
100122
},
101123
},
124+
"triggers": schema.MapAttribute{
125+
MarkdownDescription: "A map of arbitrary strings that, when changed, will force a new deployment to be created. Use this to trigger deployments based on external changes, such as spicepod configuration updates. Similar to `triggers` in `null_resource`.",
126+
Optional: true,
127+
ElementType: types.StringType,
128+
PlanModifiers: []planmodifier.Map{
129+
mapPlanModifierRequiresReplace{},
130+
},
131+
},
102132
"image_tag": schema.StringAttribute{
103133
MarkdownDescription: "Override the Spice.ai runtime image tag for this deployment. If not specified, uses the app's configured image tag. Changing this forces a new deployment to be created.",
104134
Optional: true,
@@ -325,7 +355,14 @@ func (r *DeploymentResource) Delete(ctx context.Context, req resource.DeleteRequ
325355
}
326356

327357
// Deployments cannot be deleted via API, they just get superseded by new deployments
328-
// We just remove from Terraform state
358+
// We just remove from Terraform state and warn the user
359+
resp.Diagnostics.AddWarning(
360+
"Deployment Not Stopped",
361+
"Removing the deployment resource from Terraform only removes it from state. "+
362+
"The running instance is not affected. To deploy new changes, create a new deployment. "+
363+
"To stop the instance, use the Spice.ai dashboard or CLI.",
364+
)
365+
329366
tflog.Trace(ctx, "removed deployment from state (deployments cannot be deleted)", map[string]interface{}{
330367
"id": data.ID.ValueString(),
331368
"app_id": data.AppID.ValueString(),
@@ -478,3 +515,29 @@ func (m boolPlanModifierRequiresReplace) PlanModifyBool(ctx context.Context, req
478515

479516
resp.RequiresReplace = true
480517
}
518+
519+
type mapPlanModifierRequiresReplace struct{}
520+
521+
func (m mapPlanModifierRequiresReplace) Description(ctx context.Context) string {
522+
return "If the value of this attribute changes, Terraform will destroy and recreate the resource."
523+
}
524+
525+
func (m mapPlanModifierRequiresReplace) MarkdownDescription(ctx context.Context) string {
526+
return "If the value of this attribute changes, Terraform will destroy and recreate the resource."
527+
}
528+
529+
func (m mapPlanModifierRequiresReplace) PlanModifyMap(ctx context.Context, req planmodifier.MapRequest, resp *planmodifier.MapResponse) {
530+
if req.StateValue.IsNull() {
531+
return
532+
}
533+
534+
if req.PlanValue.IsUnknown() {
535+
return
536+
}
537+
538+
if req.StateValue.Equal(req.PlanValue) {
539+
return
540+
}
541+
542+
resp.RequiresReplace = true
543+
}

0 commit comments

Comments
 (0)