diff --git a/docs/data-sources/server.md b/docs/data-sources/server.md index 631a4ff9e..e7691d6be 100644 --- a/docs/data-sources/server.md +++ b/docs/data-sources/server.md @@ -34,6 +34,7 @@ data "stackit_server" "example" { ### Read-Only - `affinity_group` (String) The affinity group the server is assigned to. +- `agent` (Attributes) STACKIT Server Agent as setup on the server (see [below for nested schema](#nestedatt--agent)) - `availability_zone` (String) The availability zone of the server. - `boot_volume` (Attributes) The boot volume for the server (see [below for nested schema](#nestedatt--boot_volume)) - `created_at` (String) Date-time when the server was created @@ -48,6 +49,14 @@ data "stackit_server" "example" { - `updated_at` (String) Date-time when the server was updated - `user_data` (String) User data that is passed via cloud-init to the server. + +### Nested Schema for `agent` + +Read-Only: + +- `provisioned` (Boolean) Whether a STACKIT Server Agent is provisioned at the server + + ### Nested Schema for `boot_volume` diff --git a/docs/resources/server.md b/docs/resources/server.md index e7559dfc0..4aa3ecea3 100644 --- a/docs/resources/server.md +++ b/docs/resources/server.md @@ -404,6 +404,7 @@ import { ### Optional - `affinity_group` (String) The affinity group the server is assigned to. +- `agent` (Attributes) The STACKIT Server Agent configured for the server (see [below for nested schema](#nestedatt--agent)) - `availability_zone` (String) The availability zone of the server. - `boot_volume` (Attributes) The boot volume for the server (see [below for nested schema](#nestedatt--boot_volume)) - `desired_status` (String) The desired status of the server resource. Possible values are: `active`, `inactive`, `deallocated`. @@ -422,6 +423,18 @@ import { - `server_id` (String) The server ID. - `updated_at` (String) Date-time when the server was updated + +### Nested Schema for `agent` + +Optional: + +- `provisioning_policy` (String) Agent provisioning policy: "ALWAYS", "NEVER", or "INHERIT". "INHERIT" follows the image default value. + +Read-Only: + +- `provisioned` (Boolean) Whether a STACKIT Server Agent should be provisioned at the server + + ### Nested Schema for `boot_volume` diff --git a/stackit/internal/services/iaas/iaas_acc_test.go b/stackit/internal/services/iaas/iaas_acc_test.go index ab27d2563..db0ffea3c 100644 --- a/stackit/internal/services/iaas/iaas_acc_test.go +++ b/stackit/internal/services/iaas/iaas_acc_test.go @@ -149,6 +149,7 @@ var testConfigServerVarsMax = config.Variables{ "service_account_mail": config.StringVariable(testutil.TestProjectServiceAccountEmail), "public_key": config.StringVariable(keypairPublicKey), "desired_status": config.StringVariable("active"), + "agent_policy": config.StringVariable("ALWAYS"), } var testConfigServerVarsMaxUpdated = func() config.Variables { @@ -158,6 +159,7 @@ var testConfigServerVarsMaxUpdated = func() config.Variables { updatedConfig["machine_type"] = config.StringVariable("t1.2") updatedConfig["label"] = config.StringVariable("updated") updatedConfig["desired_status"] = config.StringVariable("inactive") + updatedConfig["agent_policy"] = config.StringVariable("NEVER") return updatedConfig }() @@ -2223,6 +2225,8 @@ func TestAccServerMin(t *testing.T) { resource.TestCheckResourceAttrSet("stackit_server.server", "created_at"), resource.TestCheckResourceAttrSet("stackit_server.server", "launched_at"), resource.TestCheckResourceAttrSet("stackit_server.server", "updated_at"), + resource.TestCheckResourceAttr("stackit_server.server", "agent.provisioning_policy", "INHERIT"), + resource.TestCheckNoResourceAttr("stackit_server.server", "agent.provisioned"), ), }, // Data source @@ -2275,6 +2279,7 @@ func TestAccServerMin(t *testing.T) { resource.TestCheckResourceAttrSet("data.stackit_server.server", "created_at"), resource.TestCheckResourceAttrSet("data.stackit_server.server", "launched_at"), resource.TestCheckResourceAttrSet("data.stackit_server.server", "updated_at"), + resource.TestCheckNoResourceAttr("data.stackit_server.server", "agent.provisioned"), ), }, // Import @@ -2328,6 +2333,8 @@ func TestAccServerMin(t *testing.T) { resource.TestCheckResourceAttrSet("stackit_server.server", "created_at"), resource.TestCheckResourceAttrSet("stackit_server.server", "launched_at"), resource.TestCheckResourceAttrSet("stackit_server.server", "updated_at"), + resource.TestCheckResourceAttr("stackit_server.server", "agent.provisioning_policy", "INHERIT"), + resource.TestCheckNoResourceAttr("stackit_server.server", "agent.provisioned"), ), }, // Deletion is done by the framework implicitly @@ -2352,6 +2359,10 @@ func TestAccServerMax(t *testing.T) { resource.TestCheckResourceAttr("stackit_affinity_group.affinity_group", "policy", testutil.ConvertConfigVariable(testConfigServerVarsMax["policy"])), resource.TestCheckResourceAttrSet("stackit_affinity_group.affinity_group", "affinity_group_id"), + // Agent + resource.TestCheckResourceAttr("stackit_server.server", "agent.provisioning_policy", testutil.ConvertConfigVariable(testConfigServerVarsMax["agent_policy"])), + resource.TestCheckResourceAttr("stackit_server.server", "agent.provisioned", "true"), + // Volume base resource.TestCheckResourceAttr("stackit_volume.base_volume", "project_id", testutil.ConvertConfigVariable(testConfigServerVarsMax["project_id"])), resource.TestCheckResourceAttr("stackit_volume.base_volume", "availability_zone", testutil.ConvertConfigVariable(testConfigServerVarsMax["availability_zone"])), @@ -2500,6 +2511,7 @@ func TestAccServerMax(t *testing.T) { "stackit_key_pair.key_pair", "name", "data.stackit_server.server", "keypair_name", ), + resource.TestCheckResourceAttr("data.stackit_server.server", "agent.provisioned", "true"), // All network interface which was are attached appear here resource.TestCheckResourceAttr("data.stackit_server.server", "network_interfaces.#", "2"), resource.TestCheckTypeSetElemAttrPair( @@ -2725,7 +2737,7 @@ func TestAccServerMax(t *testing.T) { }, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"boot_volume", "desired_status", "network_interfaces"}, // Field is not mapped as it is only relevant on creation + ImportStateVerifyIgnore: []string{"boot_volume", "desired_status", "network_interfaces", "agent"}, // Field is not mapped as it is only relevant on creation }, // Update { @@ -2738,6 +2750,10 @@ func TestAccServerMax(t *testing.T) { resource.TestCheckResourceAttr("stackit_affinity_group.affinity_group", "policy", testutil.ConvertConfigVariable(testConfigServerVarsMaxUpdated["policy"])), resource.TestCheckResourceAttrSet("stackit_affinity_group.affinity_group", "affinity_group_id"), + // Agent + resource.TestCheckResourceAttr("stackit_server.server", "agent.provisioning_policy", testutil.ConvertConfigVariable(testConfigServerVarsMaxUpdated["agent_policy"])), + resource.TestCheckResourceAttr("stackit_server.server", "agent.provisioned", "false"), + // Volume base resource.TestCheckResourceAttr("stackit_volume.base_volume", "project_id", testutil.ConvertConfigVariable(testConfigServerVarsMaxUpdated["project_id"])), resource.TestCheckResourceAttr("stackit_volume.base_volume", "availability_zone", testutil.ConvertConfigVariable(testConfigServerVarsMaxUpdated["availability_zone"])), @@ -2843,6 +2859,10 @@ func TestAccServerMax(t *testing.T) { resource.TestCheckResourceAttr("stackit_affinity_group.affinity_group", "policy", testutil.ConvertConfigVariable(testConfigServerVarsMaxUpdatedDesiredStatus["policy"])), resource.TestCheckResourceAttrSet("stackit_affinity_group.affinity_group", "affinity_group_id"), + // Agent + resource.TestCheckResourceAttr("stackit_server.server", "agent.provisioning_policy", testutil.ConvertConfigVariable(testConfigServerVarsMaxUpdatedDesiredStatus["agent_policy"])), + resource.TestCheckResourceAttr("stackit_server.server", "agent.provisioned", "false"), + // Volume base resource.TestCheckResourceAttr("stackit_volume.base_volume", "project_id", testutil.ConvertConfigVariable(testConfigServerVarsMaxUpdatedDesiredStatus["project_id"])), resource.TestCheckResourceAttr("stackit_volume.base_volume", "availability_zone", testutil.ConvertConfigVariable(testConfigServerVarsMaxUpdatedDesiredStatus["availability_zone"])), diff --git a/stackit/internal/services/iaas/server/datasource.go b/stackit/internal/services/iaas/server/datasource.go index 75f45c85c..6c989b723 100644 --- a/stackit/internal/services/iaas/server/datasource.go +++ b/stackit/internal/services/iaas/server/datasource.go @@ -35,6 +35,7 @@ type DataSourceModel struct { ServerId types.String `tfsdk:"server_id"` MachineType types.String `tfsdk:"machine_type"` Name types.String `tfsdk:"name"` + Agent types.Object `tfsdk:"agent"` AvailabilityZone types.String `tfsdk:"availability_zone"` BootVolume types.Object `tfsdk:"boot_volume"` ImageId types.String `tfsdk:"image_id"` @@ -53,6 +54,10 @@ var bootVolumeDataTypes = map[string]attr.Type{ "delete_on_termination": basetypes.BoolType{}, } +var agentDataTypes = map[string]attr.Type{ + "provisioned": basetypes.BoolType{}, +} + // NewServerDataSource is a helper function to simplify the provider implementation. func NewServerDataSource() datasource.DataSource { return &serverDataSource{} @@ -124,6 +129,16 @@ func (d *serverDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, MarkdownDescription: "Name of the type of the machine for the server. Possible values are documented in [Virtual machine flavors](https://docs.stackit.cloud/products/compute-engine/server/basics/machine-types/)", Computed: true, }, + "agent": schema.SingleNestedAttribute{ + Description: "STACKIT Server Agent as setup on the server", + Computed: true, + Attributes: map[string]schema.Attribute{ + "provisioned": schema.BoolAttribute{ + Description: "Whether a STACKIT Server Agent is provisioned at the server", + Computed: true, + }, + }, + }, "availability_zone": schema.StringAttribute{ Description: "The availability zone of the server.", Computed: true, @@ -305,6 +320,18 @@ func mapDataSourceFields(ctx context.Context, serverResp *iaas.Server, model *Da model.BootVolume = types.ObjectNull(bootVolumeDataTypes) } + agentProvisioned := types.BoolNull() + if serverResp.Agent != nil && serverResp.Agent.Provisioned != nil { + agentProvisioned = types.BoolPointerValue(serverResp.Agent.Provisioned) + } + agent, diags := types.ObjectValue(agentDataTypes, map[string]attr.Value{ + "provisioned": agentProvisioned, + }) + if diags.HasError() { + return fmt.Errorf("failed to map agent: %w", core.DiagsToError(diags)) + } + model.Agent = agent + if serverResp.UserData != nil && len(*serverResp.UserData) > 0 { model.UserData = types.StringValue(string(*serverResp.UserData)) } diff --git a/stackit/internal/services/iaas/server/datasource_test.go b/stackit/internal/services/iaas/server/datasource_test.go index d6c8dca09..44c1a3892 100644 --- a/stackit/internal/services/iaas/server/datasource_test.go +++ b/stackit/internal/services/iaas/server/datasource_test.go @@ -10,6 +10,10 @@ import ( "github.com/stackitcloud/stackit-sdk-go/services/iaas" ) +var expectedNullAgentData, _ = types.ObjectValue(agentDataTypes, map[string]attr.Value{ + "provisioned": types.BoolNull(), +}) + func TestMapDataSourceFields(t *testing.T) { type args struct { state DataSourceModel @@ -40,6 +44,7 @@ func TestMapDataSourceFields(t *testing.T) { ServerId: types.StringValue("sid"), Name: types.StringNull(), AvailabilityZone: types.StringNull(), + Agent: expectedNullAgentData, Labels: types.MapNull(types.StringType), ImageId: types.StringNull(), NetworkInterfaces: types.ListNull(types.StringType), @@ -77,7 +82,10 @@ func TestMapDataSourceFields(t *testing.T) { NicId: new("nic2"), }, }, - KeypairName: new("keypair_name"), + KeypairName: new("keypair_name"), + Agent: &iaas.ServerAgent{ + Provisioned: new(true), + }, AffinityGroup: new("group_id"), CreatedAt: new(testTimestamp()), UpdatedAt: new(testTimestamp()), @@ -100,7 +108,10 @@ func TestMapDataSourceFields(t *testing.T) { types.StringValue("nic1"), types.StringValue("nic2"), }), - KeypairName: types.StringValue("keypair_name"), + KeypairName: types.StringValue("keypair_name"), + Agent: types.ObjectValueMust(agentDataTypes, map[string]attr.Value{ + "provisioned": types.BoolValue(true), + }), AffinityGroup: types.StringValue("group_id"), CreatedAt: types.StringValue(testTimestampValue), UpdatedAt: types.StringValue(testTimestampValue), @@ -131,6 +142,7 @@ func TestMapDataSourceFields(t *testing.T) { Labels: types.MapValueMust(types.StringType, map[string]attr.Value{}), ImageId: types.StringNull(), NetworkInterfaces: types.ListNull(types.StringType), + Agent: expectedNullAgentData, KeypairName: types.StringNull(), AffinityGroup: types.StringNull(), UserData: types.StringNull(), diff --git a/stackit/internal/services/iaas/server/resource.go b/stackit/internal/services/iaas/server/resource.go index a56ef0747..e7f5161ff 100644 --- a/stackit/internal/services/iaas/server/resource.go +++ b/stackit/internal/services/iaas/server/resource.go @@ -25,6 +25,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" @@ -64,6 +65,7 @@ type Model struct { ServerId types.String `tfsdk:"server_id"` MachineType types.String `tfsdk:"machine_type"` Name types.String `tfsdk:"name"` + Agent types.Object `tfsdk:"agent"` AvailabilityZone types.String `tfsdk:"availability_zone"` BootVolume types.Object `tfsdk:"boot_volume"` ImageId types.String `tfsdk:"image_id"` @@ -78,6 +80,12 @@ type Model struct { DesiredStatus types.String `tfsdk:"desired_status"` } +// Struct corresponding to Model.Agent +type agentModel struct { + Provisioned types.Bool `tfsdk:"provisioned"` + ProvisioningPolicy types.String `tfsdk:"provisioning_policy"` +} + // Struct corresponding to Model.BootVolume type bootVolumeModel struct { Id types.String `tfsdk:"id"` @@ -98,6 +106,12 @@ var bootVolumeTypes = map[string]attr.Type{ "id": basetypes.StringType{}, } +// Types corresponding to agentModel +var agentTypes = map[string]attr.Type{ + "provisioned": basetypes.BoolType{}, + "provisioning_policy": basetypes.StringType{}, +} + // NewServerResource is a helper function to simplify the provider implementation. func NewServerResource() resource.Resource { return &serverResource{} @@ -276,6 +290,35 @@ func (r *serverResource) Schema(_ context.Context, _ resource.SchemaRequest, res Optional: true, Computed: true, }, + "agent": schema.SingleNestedAttribute{ + Description: "The STACKIT Server Agent configured for the server", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Object{ + objectplanmodifier.RequiresReplace(), + }, + Attributes: map[string]schema.Attribute{ + "provisioned": schema.BoolAttribute{ + Description: "Whether a STACKIT Server Agent should be provisioned at the server", + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.UseStateForUnknown(), + }, + }, + "provisioning_policy": schema.StringAttribute{ + Description: "Agent provisioning policy: \"ALWAYS\", \"NEVER\", or \"INHERIT\". \"INHERIT\" follows the image default value.", + Optional: true, + Computed: true, + Default: stringdefault.StaticString("INHERIT"), + Validators: []validator.String{ + stringvalidator.OneOf("ALWAYS", "NEVER", "INHERIT"), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), // trigger recreation on change + }, + }, + }, + }, "boot_volume": schema.SingleNestedAttribute{ Description: "The boot volume for the server", Optional: true, @@ -982,6 +1025,31 @@ func mapFields(ctx context.Context, serverResp *iaas.Server, model *Model, regio model.NetworkInterfaces = types.ListNull(types.StringType) } + // agent{...} block, determine the intent policy from Terraform state + currentPolicy := types.StringValue("INHERIT") + if !(model.Agent.IsNull() || model.Agent.IsUnknown()) { + var currentAgent agentModel + if diags := model.Agent.As(ctx, ¤tAgent, basetypes.ObjectAsOptions{}); !diags.HasError() { + if !currentAgent.ProvisioningPolicy.IsNull() { + currentPolicy = currentAgent.ProvisioningPolicy + } + } + } + // agent{...} block, determine the 'provisioned' field from API response + agentProvisioned := types.BoolNull() + if serverResp.Agent != nil && serverResp.Agent.Provisioned != nil { + agentProvisioned = types.BoolPointerValue(serverResp.Agent.Provisioned) + } + // agent{...} block, finalizing + agent, diags := types.ObjectValue(agentTypes, map[string]attr.Value{ + "provisioned": agentProvisioned, + "provisioning_policy": currentPolicy, + }) + if diags.HasError() { + return fmt.Errorf("failed to map agent: %w", core.DiagsToError(diags)) + } + model.Agent = agent + if serverResp.BootVolume != nil { // convert boot volume model var bootVolumeModel = &bootVolumeModel{} @@ -1050,6 +1118,14 @@ func toCreatePayload(ctx context.Context, model *Model) (*iaas.CreateServerPaylo } } + var agent = &agentModel{} + if !(model.Agent.IsNull() || model.Agent.IsUnknown()) { + diags := model.Agent.As(ctx, agent, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return nil, fmt.Errorf("convert agent object to struct: %w", core.DiagsToError(diags)) + } + } + labels, err := conversion.ToStringInterfaceMap(ctx, model.Labels) if err != nil { return nil, fmt.Errorf("converting to Go map: %w", err) @@ -1071,6 +1147,16 @@ func toCreatePayload(ctx context.Context, model *Model) (*iaas.CreateServerPaylo } } + var agentPayload *iaas.ServerAgent + switch agent.ProvisioningPolicy.ValueString() { + case "ALWAYS": + agentPayload = &iaas.ServerAgent{Provisioned: conversion.BoolValueToPointer(types.BoolValue(true))} + case "NEVER": + agentPayload = &iaas.ServerAgent{Provisioned: conversion.BoolValueToPointer(types.BoolValue(false))} + case "INHERIT": + agentPayload = nil // "agent" key is omitted from JSON thanks to omitempty + } + var userData *[]byte if !model.UserData.IsNull() && !model.UserData.IsUnknown() { src := []byte(model.UserData.ValueString()) @@ -1100,6 +1186,7 @@ func toCreatePayload(ctx context.Context, model *Model) (*iaas.CreateServerPaylo return &iaas.CreateServerPayload{ AffinityGroup: conversion.StringValueToPointer(model.AffinityGroup), AvailabilityZone: conversion.StringValueToPointer(model.AvailabilityZone), + Agent: agentPayload, BootVolume: bootVolumePayload, ImageId: conversion.StringValueToPointer(model.ImageId), KeypairName: conversion.StringValueToPointer(model.KeypairName), diff --git a/stackit/internal/services/iaas/server/resource_test.go b/stackit/internal/services/iaas/server/resource_test.go index ff59cf37d..05af8cff2 100644 --- a/stackit/internal/services/iaas/server/resource_test.go +++ b/stackit/internal/services/iaas/server/resource_test.go @@ -20,6 +20,11 @@ const ( testTimestampValue = "2006-01-02T15:04:05Z" ) +var expectedNullAgent, _ = types.ObjectValue(agentTypes, map[string]attr.Value{ + "provisioned": types.BoolNull(), + "provisioning_policy": types.StringValue("INHERIT"), +}) + func testTimestamp() time.Time { timestamp, _ := time.Parse(time.RFC3339, testTimestampValue) return timestamp @@ -59,6 +64,7 @@ func TestMapFields(t *testing.T) { ImageId: types.StringNull(), NetworkInterfaces: types.ListNull(types.StringType), KeypairName: types.StringNull(), + Agent: expectedNullAgent, AffinityGroup: types.StringNull(), UserData: types.StringNull(), CreatedAt: types.StringNull(), @@ -92,6 +98,9 @@ func TestMapFields(t *testing.T) { NicId: new("nic2"), }, }, + Agent: &iaas.ServerAgent{ + Provisioned: new(true), + }, KeypairName: new("keypair_name"), AffinityGroup: new("group_id"), CreatedAt: new(testTimestamp()), @@ -113,11 +122,15 @@ func TestMapFields(t *testing.T) { ImageId: types.StringValue("image_id"), NetworkInterfaces: types.ListNull(types.StringType), KeypairName: types.StringValue("keypair_name"), - AffinityGroup: types.StringValue("group_id"), - CreatedAt: types.StringValue(testTimestampValue), - UpdatedAt: types.StringValue(testTimestampValue), - LaunchedAt: types.StringValue(testTimestampValue), - Region: types.StringValue("eu02"), + Agent: types.ObjectValueMust(agentTypes, map[string]attr.Value{ + "provisioned": types.BoolValue(true), + "provisioning_policy": types.StringValue("INHERIT"), + }), + AffinityGroup: types.StringValue("group_id"), + CreatedAt: types.StringValue(testTimestampValue), + UpdatedAt: types.StringValue(testTimestampValue), + LaunchedAt: types.StringValue(testTimestampValue), + Region: types.StringValue("eu02"), }, isValid: true, }, @@ -144,6 +157,7 @@ func TestMapFields(t *testing.T) { ImageId: types.StringNull(), NetworkInterfaces: types.ListNull(types.StringType), KeypairName: types.StringNull(), + Agent: expectedNullAgent, AffinityGroup: types.StringNull(), UserData: types.StringNull(), CreatedAt: types.StringNull(), @@ -216,6 +230,10 @@ func TestToCreatePayload(t *testing.T) { types.StringValue("nic1"), types.StringValue("nic2"), }), + Agent: types.ObjectValueMust(agentTypes, map[string]attr.Value{ + "provisioned": types.BoolValue(true), + "provisioning_policy": types.StringValue("ALWAYS"), + }), }, expected: &iaas.CreateServerPayload{ Name: new("name"), @@ -240,6 +258,9 @@ func TestToCreatePayload(t *testing.T) { NicIds: &[]string{"nic1", "nic2"}, }, }, + Agent: &iaas.ServerAgent{ + Provisioned: new(true), + }, }, isValid: true, }, @@ -267,6 +288,10 @@ func TestToCreatePayload(t *testing.T) { types.StringValue("nic1"), types.StringValue("nic2"), }), + Agent: types.ObjectValueMust(agentTypes, map[string]attr.Value{ + "provisioned": types.BoolValue(false), + "provisioning_policy": types.StringValue("NEVER"), + }), }, expected: &iaas.CreateServerPayload{ Name: new("name"), @@ -292,6 +317,9 @@ func TestToCreatePayload(t *testing.T) { NicIds: &[]string{"nic1", "nic2"}, }, }, + Agent: &iaas.ServerAgent{ + Provisioned: new(false), + }, }, isValid: true, }, diff --git a/stackit/internal/services/iaas/testdata/resource-server-max.tf b/stackit/internal/services/iaas/testdata/resource-server-max.tf index 4150bcc24..d741342a1 100644 --- a/stackit/internal/services/iaas/testdata/resource-server-max.tf +++ b/stackit/internal/services/iaas/testdata/resource-server-max.tf @@ -12,6 +12,7 @@ variable "policy" {} variable "size" {} variable "public_key" {} variable "service_account_mail" {} +variable "agent_policy" {} resource "stackit_affinity_group" "affinity_group" { project_id = var.project_id @@ -79,4 +80,7 @@ resource "stackit_server" "server" { labels = { "acc-test" : var.label } + agent = { + provisioning_policy = var.agent_policy + } }