diff --git a/docs/data-sources/ske_cluster.md b/docs/data-sources/ske_cluster.md
index 755198d3c..34f1b8b78 100644
--- a/docs/data-sources/ske_cluster.md
+++ b/docs/data-sources/ske_cluster.md
@@ -117,8 +117,17 @@ Read-Only:
Read-Only:
+- `control_plane` (Attributes) Control plane for the cluster. (see [below for nested schema](#nestedatt--network--control_plane))
- `id` (String) ID of the STACKIT Network Area (SNA) network into which the cluster will be deployed.
+
+### Nested Schema for `network.control_plane`
+
+Read-Only:
+
+- `access_scope` (String) Access scope of the control plane. It defines if the Kubernetes control plane is public or only available inside a STACKIT Network Area.Possible values are: `PUBLIC`, `SNA`.
+
+
### Nested Schema for `node_pools`
diff --git a/docs/data-sources/ske_kubernetes_versions.md b/docs/data-sources/ske_kubernetes_versions.md
index c64bab2aa..bd3edbd2a 100644
--- a/docs/data-sources/ske_kubernetes_versions.md
+++ b/docs/data-sources/ske_kubernetes_versions.md
@@ -43,7 +43,7 @@ resource "stackit_ske_cluster" "example" {
### Optional
- `region` (String) Region override. If omitted, the provider’s region will be used.
-- `version_state` (String) If specified, only returns Kubernetes versions with this version state. Possible values are: `UNSPECIFIED`, `SUPPORTED`.
+- `version_state` (String) If specified, only returns Kubernetes versions with this version state. Possible values are: `SUPPORTED`.
### Read-Only
diff --git a/docs/data-sources/ske_machine_image_versions.md b/docs/data-sources/ske_machine_image_versions.md
index eaab52642..9ad650b60 100644
--- a/docs/data-sources/ske_machine_image_versions.md
+++ b/docs/data-sources/ske_machine_image_versions.md
@@ -53,7 +53,7 @@ resource "stackit_ske_cluster" "example" {
### Optional
- `region` (String) Region override. If omitted, the provider’s region will be used.
-- `version_state` (String) Filter returned machine image versions by their state. Possible values are: `UNSPECIFIED`, `SUPPORTED`.
+- `version_state` (String) Filter returned machine image versions by their state. Possible values are: `SUPPORTED`.
### Read-Only
diff --git a/docs/resources/ske_cluster.md b/docs/resources/ske_cluster.md
index 44616c9be..02383aeae 100644
--- a/docs/resources/ske_cluster.md
+++ b/docs/resources/ske_cluster.md
@@ -39,6 +39,9 @@ resource "stackit_ske_cluster" "example" {
start = "01:00:00Z"
end = "02:00:00Z"
}
+ network = {
+ access_scope = "PUBLIC"
+ }
}
# Only use the import statement, if you want to import an existing ske cluster
@@ -204,4 +207,12 @@ Optional:
Optional:
+- `control_plane` (Attributes) Control plane for the cluster. (see [below for nested schema](#nestedatt--network--control_plane))
- `id` (String) ID of the STACKIT Network Area (SNA) network into which the cluster will be deployed.
+
+
+### Nested Schema for `network.control_plane`
+
+Optional:
+
+- `access_scope` (String) Access scope of the control plane. It defines if the Kubernetes control plane is public or only available inside a STACKIT Network Area.Possible values are: `PUBLIC`, `SNA`.
diff --git a/examples/resources/stackit_ske_cluster/resource.tf b/examples/resources/stackit_ske_cluster/resource.tf
index e87958fd2..6514f5eb1 100644
--- a/examples/resources/stackit_ske_cluster/resource.tf
+++ b/examples/resources/stackit_ske_cluster/resource.tf
@@ -21,6 +21,9 @@ resource "stackit_ske_cluster" "example" {
start = "01:00:00Z"
end = "02:00:00Z"
}
+ network = {
+ access_scope = "PUBLIC"
+ }
}
# Only use the import statement, if you want to import an existing ske cluster
diff --git a/go.mod b/go.mod
index a6d9d6e10..39bbaa751 100644
--- a/go.mod
+++ b/go.mod
@@ -38,7 +38,7 @@ require (
github.com/stackitcloud/stackit-sdk-go/services/serviceaccount v0.11.6
github.com/stackitcloud/stackit-sdk-go/services/serviceenablement v1.2.7
github.com/stackitcloud/stackit-sdk-go/services/sfs v0.3.0
- github.com/stackitcloud/stackit-sdk-go/services/ske v1.6.3
+ github.com/stackitcloud/stackit-sdk-go/services/ske v1.7.0
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.3
github.com/teambition/rrule-go v1.8.2
golang.org/x/mod v0.32.0
diff --git a/go.sum b/go.sum
index 513d85b9e..c8c89e295 100644
--- a/go.sum
+++ b/go.sum
@@ -207,6 +207,8 @@ github.com/stackitcloud/stackit-sdk-go/services/sfs v0.3.0 h1:4567q2dFp3Hw+5Kx+N
github.com/stackitcloud/stackit-sdk-go/services/sfs v0.3.0/go.mod h1:r5lBwzJpJe2xBIYctkVIIpaZ41Y6vUEpkmsWR2VoQJs=
github.com/stackitcloud/stackit-sdk-go/services/ske v1.6.3 h1:c+nQMvSml08cdRF1kE24vCw0r/l56olP/svQyhcnKOs=
github.com/stackitcloud/stackit-sdk-go/services/ske v1.6.3/go.mod h1:1Jr+ImrmPERxbYnlTy6O2aSZYNnREf2qQyysv6YC1RY=
+github.com/stackitcloud/stackit-sdk-go/services/ske v1.7.0 h1:l1QjxW7sdE/6B6BZtHxbmus8XJdI9KDuXX3fwUa5fog=
+github.com/stackitcloud/stackit-sdk-go/services/ske v1.7.0/go.mod h1:1Jr+ImrmPERxbYnlTy6O2aSZYNnREf2qQyysv6YC1RY=
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.3 h1:AQrcr+qeIuZob+3TT2q1L4WOPtpsu5SEpkTnOUHDqfE=
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.3/go.mod h1:8BBGC69WFXWWmKgzSjgE4HvsI7pEgO0RN2cASwuPJ18=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
diff --git a/stackit/internal/services/ske/cluster/datasource.go b/stackit/internal/services/ske/cluster/datasource.go
index 2a7feca9c..58af37c02 100644
--- a/stackit/internal/services/ske/cluster/datasource.go
+++ b/stackit/internal/services/ske/cluster/datasource.go
@@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
+ sdkUtils "github.com/stackitcloud/stackit-sdk-go/core/utils"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
skeUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/ske/utils"
@@ -223,6 +224,16 @@ func (r *clusterDataSource) Schema(_ context.Context, _ datasource.SchemaRequest
validate.UUID(),
},
},
+ "control_plane": schema.SingleNestedAttribute{
+ Description: "Control plane for the cluster.",
+ Computed: true,
+ Attributes: map[string]schema.Attribute{
+ "access_scope": schema.StringAttribute{
+ Description: "Access scope of the control plane. It defines if the Kubernetes control plane is public or only available inside a STACKIT Network Area." + utils.FormatPossibleValues(sdkUtils.EnumSliceToStringSlice(ske.AllowedAccessScopeEnumValues)...),
+ Computed: true,
+ },
+ },
+ },
},
},
diff --git a/stackit/internal/services/ske/cluster/resource.go b/stackit/internal/services/ske/cluster/resource.go
index a01a37a05..de86f775e 100644
--- a/stackit/internal/services/ske/cluster/resource.go
+++ b/stackit/internal/services/ske/cluster/resource.go
@@ -157,12 +157,23 @@ var maintenanceTypes = map[string]attr.Type{
// Struct corresponding to Model.Network
type network struct {
- ID types.String `tfsdk:"id"`
+ ID types.String `tfsdk:"id"`
+ ControlPlane types.Object `tfsdk:"control_plane"`
}
// Types corresponding to network
var networkTypes = map[string]attr.Type{
- "id": basetypes.StringType{},
+ "id": basetypes.StringType{},
+ "control_plane": types.ObjectType{AttrTypes: controlPlaneTypes},
+}
+
+type controlPlane struct {
+ AccessScope types.String `tfsdk:"access_scope"`
+}
+
+// Types corresponding to control plane
+var controlPlaneTypes = map[string]attr.Type{
+ "access_scope": basetypes.StringType{},
}
// Struct corresponding to Model.Hibernations[i]
@@ -563,6 +574,16 @@ func (r *clusterResource) Schema(_ context.Context, _ resource.SchemaRequest, re
stringplanmodifier.RequiresReplace(),
},
},
+ "control_plane": schema.SingleNestedAttribute{
+ Description: "Control plane for the cluster.",
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "access_scope": schema.StringAttribute{
+ Description: "Access scope of the control plane. It defines if the Kubernetes control plane is public or only available inside a STACKIT Network Area." + utils.FormatPossibleValues(sdkUtils.EnumSliceToStringSlice(ske.AllowedAccessScopeEnumValues)...),
+ Optional: true,
+ },
+ },
+ },
},
},
"hibernations": schema.ListNestedAttribute{
@@ -1352,8 +1373,21 @@ func toNetworkPayload(ctx context.Context, m *Model) (*ske.Network, error) {
return nil, fmt.Errorf("converting network object: %v", diags.Errors())
}
+ var networkControlPlane *ske.V2ControlPlaneNetwork
+ if !(network.ControlPlane.IsNull() || network.ControlPlane.IsUnknown()) {
+ networkControlPlaneModel := controlPlane{}
+ diags = network.ControlPlane.As(ctx, &networkControlPlaneModel, basetypes.ObjectAsOptions{})
+ if diags.HasError() {
+ return nil, fmt.Errorf("converting network control plane: %w", core.DiagsToError(diags))
+ }
+ networkControlPlane = &ske.V2ControlPlaneNetwork{
+ AccessScope: ske.V2ControlPlaneNetworkGetAccessScopeAttributeType(conversion.StringValueToPointer(networkControlPlaneModel.AccessScope)),
+ }
+ }
+
return &ske.Network{
- Id: conversion.StringValueToPointer(network.ID),
+ Id: conversion.StringValueToPointer(network.ID),
+ ControlPlane: networkControlPlane,
}, nil
}
@@ -1657,12 +1691,32 @@ func mapNetwork(cl *ske.Cluster, m *Model) error {
return nil
}
+ var diags diag.Diagnostics
id := types.StringNull()
if cl.Network.Id != nil {
id = types.StringValue(*cl.Network.Id)
}
+
+ networkControlPlane := types.ObjectNull(controlPlaneTypes)
+ if cl.Network.ControlPlane != nil {
+ controlPlaneAccessScope := types.StringNull()
+ if cl.Network.ControlPlane.AccessScope != nil {
+ controlPlaneAccessScope = types.StringValue(string(cl.Network.ControlPlane.GetAccessScope()))
+ }
+
+ controlPlaneValues := map[string]attr.Value{
+ "access_scope": controlPlaneAccessScope,
+ }
+
+ networkControlPlane, diags = types.ObjectValue(controlPlaneTypes, controlPlaneValues)
+ if diags.HasError() {
+ return fmt.Errorf("creating network control plane: %w", core.DiagsToError(diags))
+ }
+ }
+
networkValues := map[string]attr.Value{
- "id": id,
+ "id": id,
+ "control_plane": networkControlPlane,
}
networkObject, diags := types.ObjectValue(networkTypes, networkValues)
if diags.HasError() {
diff --git a/stackit/internal/services/ske/cluster/resource_test.go b/stackit/internal/services/ske/cluster/resource_test.go
index e29c15cc8..f8d7137e2 100644
--- a/stackit/internal/services/ske/cluster/resource_test.go
+++ b/stackit/internal/services/ske/cluster/resource_test.go
@@ -110,6 +110,9 @@ func TestMapFields(t *testing.T) {
},
Network: &ske.Network{
Id: utils.Ptr("nid"),
+ ControlPlane: &ske.V2ControlPlaneNetwork{
+ AccessScope: ske.V2ControlPlaneNetworkGetAccessScopeAttributeType(utils.Ptr("SNA")),
+ },
},
Name: utils.Ptr("name"),
Nodepools: &[]ske.Nodepool{
@@ -231,6 +234,9 @@ func TestMapFields(t *testing.T) {
}),
Network: types.ObjectValueMust(networkTypes, map[string]attr.Value{
"id": types.StringValue("nid"),
+ "control_plane": types.ObjectValueMust(controlPlaneTypes, map[string]attr.Value{
+ "access_scope": types.StringValue("SNA"),
+ }),
}),
Hibernations: types.ListValueMust(
types.ObjectType{AttrTypes: hibernationTypes},
@@ -560,6 +566,9 @@ func TestMapFields(t *testing.T) {
},
Network: &ske.Network{
Id: utils.Ptr("nid"),
+ ControlPlane: &ske.V2ControlPlaneNetwork{
+ AccessScope: ske.V2ControlPlaneNetworkGetAccessScopeAttributeType(utils.Ptr("SNA")),
+ },
},
Name: utils.Ptr("name"),
Nodepools: &[]ske.Nodepool{
@@ -648,6 +657,9 @@ func TestMapFields(t *testing.T) {
}),
Network: types.ObjectValueMust(networkTypes, map[string]attr.Value{
"id": types.StringValue("nid"),
+ "control_plane": types.ObjectValueMust(controlPlaneTypes, map[string]attr.Value{
+ "access_scope": types.StringValue("SNA"),
+ }),
}),
Hibernations: types.ListValueMust(
types.ObjectType{AttrTypes: hibernationTypes},
@@ -2239,10 +2251,16 @@ func TestToNetworkPayload(t *testing.T) {
Name: types.StringValue("name"),
Network: types.ObjectValueMust(networkTypes, map[string]attr.Value{
"id": types.StringValue("nid"),
+ "control_plane": types.ObjectValueMust(controlPlaneTypes, map[string]attr.Value{
+ "access_scope": types.StringValue("SNA"),
+ }),
}),
},
&ske.Network{
Id: utils.Ptr("nid"),
+ ControlPlane: &ske.V2ControlPlaneNetwork{
+ AccessScope: ske.V2ControlPlaneNetworkGetAccessScopeAttributeType(utils.Ptr("SNA")),
+ },
},
true,
},
@@ -2252,12 +2270,29 @@ func TestToNetworkPayload(t *testing.T) {
ProjectId: types.StringValue("pid"),
Name: types.StringValue("name"),
Network: types.ObjectValueMust(networkTypes, map[string]attr.Value{
- "id": types.StringNull(),
+ "id": types.StringNull(),
+ "control_plane": types.ObjectNull(controlPlaneTypes),
}),
},
&ske.Network{},
true,
},
+ {
+ "no_control_plane",
+ &Model{
+ ProjectId: types.StringValue("pid"),
+ Name: types.StringValue("name"),
+ Network: types.ObjectValueMust(networkTypes, map[string]attr.Value{
+ "id": types.StringValue("nid"),
+ "control_plane": types.ObjectNull(controlPlaneTypes),
+ }),
+ },
+ &ske.Network{
+ Id: utils.Ptr("nid"),
+ ControlPlane: nil,
+ },
+ true,
+ },
{
"no_network",
&Model{
diff --git a/stackit/internal/services/ske/ske_acc_test.go b/stackit/internal/services/ske/ske_acc_test.go
index c862daa98..d394ca9d5 100644
--- a/stackit/internal/services/ske/ske_acc_test.go
+++ b/stackit/internal/services/ske/ske_acc_test.go
@@ -92,6 +92,7 @@ var testConfigVarsMax = config.Variables{
"refresh_before": config.StringVariable("600"),
"dns_zone_name": config.StringVariable("acc-" + acctest.RandStringFromCharSet(6, acctest.CharSetAlpha)),
"dns_name": config.StringVariable("acc-" + acctest.RandStringFromCharSet(6, acctest.CharSetAlpha) + ".runs.onstackit.cloud"),
+ "network_control_plane_access_scope": config.StringVariable("PUBLIC"),
}
var testConfigDatasource = config.Variables{
@@ -299,6 +300,8 @@ func TestAccSKEMax(t *testing.T) {
resource.TestCheckResourceAttrSet("stackit_ske_cluster.cluster", "pod_address_ranges.0"),
resource.TestCheckResourceAttrSet("stackit_ske_cluster.cluster", "kubernetes_version_used"),
+ resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "network.control_plane.access_scope", testutil.ConvertConfigVariable(testConfigVarsMax["network_control_plane_access_scope"])),
+
// Kubeconfig
resource.TestCheckResourceAttrPair(
"stackit_ske_kubeconfig.kubeconfig", "project_id",
@@ -373,6 +376,8 @@ func TestAccSKEMax(t *testing.T) {
resource.TestCheckResourceAttrSet("data.stackit_ske_cluster.cluster", "pod_address_ranges.0"),
resource.TestCheckResourceAttrSet("data.stackit_ske_cluster.cluster", "kubernetes_version_used"),
+
+ resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "network.control_plane.access_scope", testutil.ConvertConfigVariable(testConfigVarsMax["network_control_plane_access_scope"])),
),
},
// 3) Import cluster
diff --git a/stackit/internal/services/ske/testdata/resource-max.tf b/stackit/internal/services/ske/testdata/resource-max.tf
index 192c9138f..fde7ff1cc 100644
--- a/stackit/internal/services/ske/testdata/resource-max.tf
+++ b/stackit/internal/services/ske/testdata/resource-max.tf
@@ -35,6 +35,7 @@ variable "refresh" {}
variable "refresh_before" {}
variable "dns_zone_name" {}
variable "dns_name" {}
+variable "network_control_plane_access_scope" {}
resource "stackit_ske_cluster" "cluster" {
project_id = var.project_id
@@ -92,6 +93,11 @@ resource "stackit_ske_cluster" "cluster" {
end = var.maintenance_end
}
region = var.region
+ network = {
+ control_plane = {
+ access_scope = var.network_control_plane_access_scope
+ }
+ }
}
resource "stackit_ske_kubeconfig" "kubeconfig" {