Skip to content

Commit 3a093e8

Browse files
committed
STACKITRCO-187 - Add option iaas API param agent
Adds a terraform `stackit_server` option for the iaas ( _create server_ ) API param: `"agent": {"provisioned": true}` ref STACKITRCO-187 ref: stackitcloud/stackit-cli#121 --- Tests: * ran `make fmt`, `make generate-docs` * ran unit tests ``` [~/terraform-provider-stackit] go test stackit/internal/services/iaas/server/* ok command-line-arguments 15.005s [~/terraform-provider-stackit] make test ... ok github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/server 15.006s coverage: 33.0% of statements ... [~/terraform-provider-stackit] ``` * Tested: with a locally-configured terraform - tested by adding, changing, deleting `agent`-related parts of the below main.tf ** Tested without providing agent inside main.tf (the result had `"agent" = null /* object */`) ** Tested with setting `agent = { provisioning = true }` (and then ran the `stackit-cli` command for checking if the agent was created successfully and able to run commands, `stackit -y server command create --server-id=3fdac6ea-3885-441c-b473-bc94ca570ca8 --project-id=c904f41c-2f8c-4edb-b966-e87d65f10b64 --template-name=RunShellScript --params script='echo hello'`). ** Tested when setting `agent = { provisioning = true }` and then set it to false - verified the server was deleted and recreated again with the new value. ``` [~] cat main.tf provider "stackit" { # Configuration options service_account_key_path = "/home/debian/terraform_dev/.terraform_key.json" default_region = "eu01" } resource "stackit_network_interface" "server_nic" { project_id = "c904f41c-2f8c-4edb-b966-e87d65f10b64" network_id = "97c5dde4-cb9d-49b8-be55-9cdf0c3795e1" } resource "stackit_server" "myserver1" { project_id = "c904f41c-2f8c-4edb-b966-e87d65f10b64" name = "terraformtestserver1" boot_volume = { size = 64 source_type = "image" source_id = "21466190-b904-4267-8bf3-1be4323f4ffb" delete_on_termination = true } availability_zone = "eu01-1" agent = { provisioned = true } machine_type = "t1.1" network_interfaces = [ stackit_network_interface.server_nic.network_interface_id ] } data "stackit_server" "myserver1_data" { project_id = "c904f41c-2f8c-4edb-b966-e87d65f10b64" server_id = stackit_server.myserver1.server_id } output "server_info_from_data" { value = data.stackit_server.myserver1_data } ``` ``` [~] terraform apply -auto-approve ## this is without `agent` set in the config ... server_info_from_data = { "affinity_group" = tostring(null) "agent" = null /* object */ "availability_zone" = "eu01-1" ... } ... ``` ``` [~] terraform apply -auto-approve ## this is with `agent = { provisioned = true }` set in the config ... server_info_from_data = { "affinity_group" = tostring(null) "agent" = { "provisioned" = true } "availability_zone" = "eu01-1" "boot_volume" = { "delete_on_termination" = true "id" = "673021e5-2a90-4482-8ffa-e0485c7588bd" } ... } ``` Signed-off-by: Adrian Nackov <[email protected]>
1 parent 74ed4bd commit 3a093e8

File tree

6 files changed

+250
-118
lines changed

6 files changed

+250
-118
lines changed

docs/data-sources/server.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ data "stackit_server" "example" {
3434
### Read-Only
3535

3636
- `affinity_group` (String) The affinity group the server is assigned to.
37+
- `agent` (Attributes) Stackit commands agent as setup on the server (see [below for nested schema](#nestedatt--agent))
3738
- `availability_zone` (String) The availability zone of the server.
3839
- `boot_volume` (Attributes) The boot volume for the server (see [below for nested schema](#nestedatt--boot_volume))
3940
- `created_at` (String) Date-time when the server was created
@@ -48,6 +49,14 @@ data "stackit_server" "example" {
4849
- `updated_at` (String) Date-time when the server was updated
4950
- `user_data` (String) User data that is passed via cloud-init to the server.
5051

52+
<a id="nestedatt--agent"></a>
53+
### Nested Schema for `agent`
54+
55+
Read-Only:
56+
57+
- `provisioned` (Boolean) Whether a stackit commands agent is provisioned at the server
58+
59+
5160
<a id="nestedatt--boot_volume"></a>
5261
### Nested Schema for `boot_volume`
5362

docs/resources/server.md

Lines changed: 105 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,43 @@ description: |-
66
Server resource schema. Must have a region specified in the provider configuration.
77
Example Usage
88
With key pair
9-
10-
resource "stackit_key_pair" "keypair" {
9+
```terraform
10+
resource "stackitkeypair" "keypair" {
1111
name = "example-key-pair"
12-
public_key = chomp(file("path/to/id_rsa.pub"))
12+
publickey = chomp(file("path/to/idrsa.pub"))
1313
}
14-
15-
resource "stackit_server" "user-data-from-file" {
16-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
17-
boot_volume = {
14+
resource "stackitserver" "user-data-from-file" {
15+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
16+
bootvolume = {
1817
size = 64
19-
source_type = "image"
20-
source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
18+
sourcetype = "image"
19+
sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
2120
}
2221
name = "example-server"
23-
machine_type = "g2i.1"
24-
keypair_name = stackit_key_pair.keypair.name
25-
user_data = file("${path.module}/cloud-init.yaml")
22+
machinetype = "g2i.1"
23+
keypairname = stackitkeypair.keypair.name
24+
userdata = file("${path.module}/cloud-init.yaml")
2625
}
27-
28-
26+
```
2927
Boot from volume
30-
31-
resource "stackit_server" "boot-from-volume" {
32-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
28+
```terraform
29+
resource "stackitserver" "boot-from-volume" {
30+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3331
name = "example-server"
34-
boot_volume = {
32+
bootvolume = {
3533
size = 64
36-
source_type = "image"
37-
source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
34+
sourcetype = "image"
35+
sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3836
}
39-
availability_zone = "eu01-1"
40-
machine_type = "g2i.1"
41-
keypair_name = "example-keypair"
37+
availabilityzone = "eu01-1"
38+
machinetype = "g2i.1"
39+
keypairname = "example-keypair"
4240
}
43-
44-
41+
```
4542
Boot from existing volume
46-
47-
resource "stackit_volume" "example-volume" {
48-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
43+
```terraform
44+
resource "stackitvolume" "example-volume" {
45+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
4946
size = 12
5047
source = {
5148
type = "image"
@@ -54,126 +51,115 @@ description: |-
5451
name = "example-volume"
5552
availability_zone = "eu01-1"
5653
}
57-
58-
resource "stackit_server" "boot-from-volume" {
59-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
54+
resource "stackitserver" "boot-from-volume" {
55+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
6056
name = "example-server"
61-
boot_volume = {
62-
source_type = "volume"
63-
source_id = stackit_volume.example-volume.volume_id
57+
bootvolume = {
58+
sourcetype = "volume"
59+
sourceid = stackitvolume.example-volume.volumeid
6460
}
65-
availability_zone = "eu01-1"
66-
machine_type = "g2i.1"
67-
keypair_name = stackit_key_pair.keypair.name
61+
availabilityzone = "eu01-1"
62+
machinetype = "g2i.1"
63+
keypairname = stackitkeypair.keypair.name
6864
}
69-
70-
65+
```
7166
Network setup
72-
73-
resource "stackit_network" "network" {
74-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
67+
```terraform
68+
resource "stackitnetwork" "network" {
69+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
7570
name = "example-network"
7671
nameservers = ["192.0.2.0", "198.51.100.0", "203.0.113.0"]
77-
ipv4_prefix_length = 24
72+
ipv4prefixlength = 24
7873
}
79-
80-
resource "stackit_security_group" "sec-group" {
74+
resource "stackitsecuritygroup" "sec-group" {
8175
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
8276
name = "example-security-group"
8377
stateful = true
8478
}
85-
86-
resource "stackit_security_group_rule" "rule" {
87-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
88-
security_group_id = stackit_security_group.sec-group.security_group_id
79+
resource "stackitsecuritygrouprule" "rule" {
80+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
81+
securitygroupid = stackitsecuritygroup.sec-group.securitygroupid
8982
direction = "ingress"
9083
ether_type = "IPv4"
9184
}
92-
93-
resource "stackit_network_interface" "nic" {
94-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
95-
network_id = stackit_network.network.network_id
96-
security_group_ids = [stackit_security_group.sec-group.security_group_id]
85+
resource "stackitnetworkinterface" "nic" {
86+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
87+
networkid = stackitnetwork.network.networkid
88+
securitygroupids = [stackitsecuritygroup.sec-group.securitygroupid]
9789
}
98-
99-
resource "stackit_server" "server-with-network" {
100-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
90+
resource "stackitserver" "server-with-network" {
91+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
10192
name = "example-server"
102-
boot_volume = {
93+
bootvolume = {
10394
size = 64
104-
source_type = "image"
105-
source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
95+
sourcetype = "image"
96+
sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
10697
}
107-
machine_type = "g2i.1"
108-
keypair_name = stackit_key_pair.keypair.name
109-
network_interfaces = [
110-
stackit_network_interface.nic.network_interface_id
111-
]
98+
machinetype = "g2i.1"
99+
keypairname = stackitkeypair.keypair.name
100+
networkinterfaces = [
101+
stackitnetworkinterface.nic.networkinterfaceid
102+
]
112103
}
113-
114-
resource "stackit_public_ip" "public-ip" {
115-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
116-
network_interface_id = stackit_network_interface.nic.network_interface_id
104+
resource "stackitpublicip" "public-ip" {
105+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
106+
networkinterfaceid = stackitnetworkinterface.nic.networkinterface_id
117107
}
118-
119-
108+
```
120109
Server with attached volume
121-
122-
resource "stackit_volume" "example-volume" {
123-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
110+
```terraform
111+
resource "stackitvolume" "example-volume" {
112+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
124113
size = 12
125-
performance_class = "storage_premium_perf6"
114+
performanceclass = "storagepremiumperf6"
126115
name = "example-volume"
127-
availability_zone = "eu01-1"
116+
availabilityzone = "eu01-1"
128117
}
129-
130-
resource "stackit_server" "server-with-volume" {
131-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
118+
resource "stackitserver" "server-with-volume" {
119+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
132120
name = "example-server"
133-
boot_volume = {
121+
bootvolume = {
134122
size = 64
135-
source_type = "image"
136-
source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
123+
sourcetype = "image"
124+
sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
137125
}
138-
availability_zone = "eu01-1"
139-
machine_type = "g2i.1"
140-
keypair_name = stackit_key_pair.keypair.name
126+
availabilityzone = "eu01-1"
127+
machinetype = "g2i.1"
128+
keypairname = stackitkeypair.keypair.name
141129
}
142-
143-
resource "stackit_server_volume_attach" "attach_volume" {
144-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
145-
server_id = stackit_server.server-with-volume.server_id
146-
volume_id = stackit_volume.example-volume.volume_id
130+
resource "stackitservervolumeattach" "attachvolume" {
131+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
132+
serverid = stackitserver.server-with-volume.serverid
133+
volumeid = stackitvolume.example-volume.volume_id
147134
}
148-
149-
135+
```
150136
Server with user data (cloud-init)
151-
152-
resource "stackit_server" "user-data" {
153-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
154-
boot_volume = {
137+
```terraform
138+
resource "stackitserver" "user-data" {
139+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
140+
bootvolume = {
155141
size = 64
156-
source_type = "image"
157-
source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
142+
sourcetype = "image"
143+
sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
158144
}
159145
name = "example-server"
160-
machine_type = "g2i.1"
161-
keypair_name = stackit_key_pair.keypair.name
162-
user_data = "#!/bin/bash\n/bin/su"
146+
machinetype = "g2i.1"
147+
keypairname = stackitkeypair.keypair.name
148+
userdata = "#!/bin/bash\n/bin/su"
163149
}
164-
165-
resource "stackit_server" "user-data-from-file" {
166-
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
167-
boot_volume = {
150+
resource "stackitserver" "user-data-from-file" {
151+
projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
152+
bootvolume = {
168153
size = 64
169-
source_type = "image"
170-
source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
154+
sourcetype = "image"
155+
sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
171156
}
172157
name = "example-server"
173-
machine_type = "g2i.1"
174-
keypair_name = stackit_key_pair.keypair.name
175-
user_data = file("${path.module}/cloud-init.yaml")
158+
machinetype = "g2i.1"
159+
keypairname = stackitkeypair.keypair.name
160+
userdata = file("${path.module}/cloud-init.yaml")
176161
}
162+
```
177163
---
178164

179165
# stackit_server (Resource)
@@ -404,6 +390,7 @@ import {
404390
### Optional
405391

406392
- `affinity_group` (String) The affinity group the server is assigned to.
393+
- `agent` (Attributes) The stackit commands agent configured for the server (see [below for nested schema](#nestedatt--agent))
407394
- `availability_zone` (String) The availability zone of the server.
408395
- `boot_volume` (Attributes) The boot volume for the server (see [below for nested schema](#nestedatt--boot_volume))
409396
- `desired_status` (String) The desired status of the server resource. Possible values are: `active`, `inactive`, `deallocated`.
@@ -422,6 +409,14 @@ import {
422409
- `server_id` (String) The server ID.
423410
- `updated_at` (String) Date-time when the server was updated
424411

412+
<a id="nestedatt--agent"></a>
413+
### Nested Schema for `agent`
414+
415+
Optional:
416+
417+
- `provisioned` (Boolean) Whether a stackit commands agent should be provisioned at the server
418+
419+
425420
<a id="nestedatt--boot_volume"></a>
426421
### Nested Schema for `boot_volume`
427422

stackit/internal/services/iaas/server/datasource.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type DataSourceModel struct {
3434
ServerId types.String `tfsdk:"server_id"`
3535
MachineType types.String `tfsdk:"machine_type"`
3636
Name types.String `tfsdk:"name"`
37+
Agent types.Object `tfsdk:"agent"`
3738
AvailabilityZone types.String `tfsdk:"availability_zone"`
3839
BootVolume types.Object `tfsdk:"boot_volume"`
3940
ImageId types.String `tfsdk:"image_id"`
@@ -52,6 +53,10 @@ var bootVolumeDataTypes = map[string]attr.Type{
5253
"delete_on_termination": basetypes.BoolType{},
5354
}
5455

56+
var agentDataTypes = map[string]attr.Type{
57+
"provisioned": basetypes.BoolType{},
58+
}
59+
5560
// NewServerDataSource is a helper function to simplify the provider implementation.
5661
func NewServerDataSource() datasource.DataSource {
5762
return &serverDataSource{}
@@ -123,6 +128,16 @@ func (d *serverDataSource) Schema(_ context.Context, _ datasource.SchemaRequest,
123128
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/)",
124129
Computed: true,
125130
},
131+
"agent": schema.SingleNestedAttribute{
132+
Description: "Stackit commands agent as setup on the server",
133+
Computed: true,
134+
Attributes: map[string]schema.Attribute{
135+
"provisioned": schema.BoolAttribute{
136+
Description: "Whether a stackit commands agent is provisioned at the server",
137+
Computed: true,
138+
},
139+
},
140+
},
126141
"availability_zone": schema.StringAttribute{
127142
Description: "The availability zone of the server.",
128143
Computed: true,
@@ -304,6 +319,18 @@ func mapDataSourceFields(ctx context.Context, serverResp *iaas.Server, model *Da
304319
model.BootVolume = types.ObjectNull(bootVolumeDataTypes)
305320
}
306321

322+
if serverResp.Agent != nil {
323+
agent, diags := types.ObjectValue(agentDataTypes, map[string]attr.Value{
324+
"provisioned": types.BoolPointerValue(serverResp.Agent.Provisioned),
325+
})
326+
if diags.HasError() {
327+
return fmt.Errorf("failed to map agent: %w", core.DiagsToError(diags))
328+
}
329+
model.Agent = agent
330+
} else {
331+
model.Agent = types.ObjectNull(agentDataTypes)
332+
}
333+
307334
if serverResp.UserData != nil && len(*serverResp.UserData) > 0 {
308335
model.UserData = types.StringValue(string(*serverResp.UserData))
309336
}

0 commit comments

Comments
 (0)