Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
15 changes: 14 additions & 1 deletion docs/resources/k8s_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,20 @@ you can still set it now. In this case it will not destroy and recreate your clu

- `required_claim` - (Optional) Multiple key=value pairs that describes a required claim in the ID Token

- `default_pool` - (Deprecated) See below.
- `pod_cidr` - (Optional) The subnet used for the Pod CIDR.

~> **Important:** Changes to this field will recreate a new resource. However once it has been set to a custom value,
unsetting it to go back to the default value will not have any effect.

- `service_cidr` - (Optional) The subnet used for the Service CIDR.

~> **Important:** Changes to this field will recreate a new resource. However once it has been set to a custom value,
unsetting it to go back to the default value will not have any effect.

- `service_dns_ip` - (Optional) The IP used for the DNS Service. If unset, defaults to Service CIDR's network + 10.

~> **Important:** Changes to this field will recreate a new resource. However once it has been set to a custom value,
unsetting it to go back to the default value will not have any effect.

- `region` - (Defaults to [provider](../index.md#arguments-reference) `region`) The [region](../guides/regions_and_zones.md#regions) in which the cluster should be created.

Expand Down
69 changes: 69 additions & 0 deletions internal/services/k8s/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"net"
"strings"
"time"

Expand All @@ -18,11 +19,18 @@ import (
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
)

var NetworkingDefaultValues = map[string]string{
"pod_cidr": "100.64.0.0/15",
"service_cidr": "10.32.0.0/20",
"service_dns_ip": "10.32.0.10",
}

func ResourceCluster() *schema.Resource {
return &schema.Resource{
CreateContext: ResourceK8SClusterCreate,
Expand Down Expand Up @@ -167,6 +175,30 @@ func ResourceCluster() *schema.Resource {
ValidateDiagFunc: verify.IsUUIDorUUIDWithLocality(),
DiffSuppressFunc: dsf.Locality,
},
"pod_cidr": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
Description: "The subnet used for the Pod CIDR.",
ValidateFunc: validation.IsCIDR,
},
"service_cidr": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
Description: "The subnet used for the Service CIDR.",
ValidateFunc: validation.IsCIDR,
},
"service_dns_ip": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
Description: "The IP used for the DNS Service.",
ValidateFunc: validation.IsIPAddress,
},
"region": regional.Schema(),
"organization_id": account.OrganizationIDSchema(),
"project_id": account.ProjectIDSchema(),
Expand Down Expand Up @@ -506,6 +538,23 @@ func ResourceK8SClusterCreate(ctx context.Context, d *schema.ResourceData, m any
req.PrivateNetworkID = scw.StringPtr(regional.ExpandID(pnID.(string)).ID)
}

// Networking configuration

if podCIDR, ok := d.GetOk("pod_cidr"); ok {
podCIDRIPNet, _ := types.ExpandIPNet(podCIDR.(string))
req.PodCidr = &podCIDRIPNet
}

if serviceCIDR, ok := d.GetOk("service_cidr"); ok {
serviceCIDRIPNet, _ := types.ExpandIPNet(serviceCIDR.(string))
req.ServiceCidr = &serviceCIDRIPNet
}

if serviceDNSIP, ok := d.GetOk("service_dns_ip"); ok {
serviceDNSIPNetIP := net.ParseIP(serviceDNSIP.(string))
req.ServiceDNSIP = &serviceDNSIPNetIP
}

// Cluster creation

res, err := k8sAPI.CreateCluster(req, scw.WithContext(ctx))
Expand Down Expand Up @@ -587,6 +636,11 @@ func ResourceK8SClusterRead(ctx context.Context, d *schema.ResourceData, m any)
// private_network
_ = d.Set("private_network_id", types.FlattenStringPtr(cluster.PrivateNetworkID))

// networking
_ = d.Set("pod_cidr", cluster.PodCidr.String())
_ = d.Set("service_cidr", cluster.ServiceCidr.String())
_ = d.Set("service_dns_ip", cluster.ServiceDNSIP.String())

////
// Read kubeconfig
////
Expand Down Expand Up @@ -876,6 +930,21 @@ func ResourceK8SClusterUpdate(ctx context.Context, d *schema.ResourceData, m any
}
}

// Display warning if an update of networking fields is requested
// Setting the value can be done with ForceNew, but unsetting is not possible at the time because Terraform doesn't
// detect changes on fields that are both optional and computed, and those fields are not updatable with the API.
for _, key := range []string{"pod_cidr", "service_cidr", "service_dns_ip"} {
raw, ok := meta.GetRawConfigForKey(d, key, cty.String)
if !ok || raw == "" && d.Get(key) != NetworkingDefaultValues[key] {
diags = append(diags, diag.Diagnostic{
Severity: diag.Warning,
Summary: fmt.Sprintf("It is not possible to unset %q at the time", key),
Detail: "Once it has been set to a custom value, unsetting it in order to go back to the default value will not have any effect.",
AttributePath: cty.GetAttrPath(key),
})
}
}

return append(ResourceK8SClusterRead(ctx, d, m), diags...)
}

Expand Down
137 changes: 137 additions & 0 deletions internal/services/k8s/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ resource "scaleway_k8s_cluster" "minimal" {
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "tags.1", "scaleway_k8s_cluster"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "tags.2", "minimal"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "description", "terraform basic test cluster"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "pod_cidr", k8s.NetworkingDefaultValues["pod_cidr"]),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "service_cidr", k8s.NetworkingDefaultValues["service_cidr"]),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "service_dns_ip", k8s.NetworkingDefaultValues["service_dns_ip"]),
),
},
{
Expand Down Expand Up @@ -178,6 +181,9 @@ resource "scaleway_k8s_cluster" "minimal" {
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "tags.1", "scaleway_k8s_cluster"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "tags.2", "minimal"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "description", ""),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "pod_cidr", k8s.NetworkingDefaultValues["pod_cidr"]),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "service_cidr", k8s.NetworkingDefaultValues["service_cidr"]),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.minimal", "service_dns_ip", k8s.NetworkingDefaultValues["service_dns_ip"]),
),
},
},
Expand Down Expand Up @@ -916,3 +922,134 @@ resource "scaleway_k8s_cluster" "type-change" {

return config
}

func TestAccCluster_Networking(t *testing.T) {
tt := acctest.NewTestTools(t)
defer tt.Cleanup()

latestK8SVersion := testAccK8SClusterGetLatestK8SVersion(tt)
clusterID := ""

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(t)
},
ProtoV6ProviderFactories: tt.ProviderFactories,
CheckDestroy: resource.ComposeTestCheckFunc(
testAccCheckK8SClusterDestroy(tt),
vpcchecks.CheckPrivateNetworkDestroy(tt),
),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
resource "scaleway_vpc" "networking" {
name = "vpc-networking"
}
resource "scaleway_vpc_private_network" "networking" {
name = "pn-networking"
vpc_id = scaleway_vpc.networking.id
}
resource "scaleway_k8s_cluster" "networking" {
cni = "cilium"
version = "%s"
name = "test-networking"
tags = [ "terraform-test", "scaleway_k8s_cluster", "networking" ]
delete_additional_resources = false
private_network_id = scaleway_vpc_private_network.networking.id
}`, latestK8SVersion),
Check: resource.ComposeTestCheckFunc(
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.networking"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "version", latestK8SVersion),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "cni", "cilium"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "pod_cidr", k8s.NetworkingDefaultValues["pod_cidr"]),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "service_cidr", k8s.NetworkingDefaultValues["service_cidr"]),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "service_dns_ip", k8s.NetworkingDefaultValues["service_dns_ip"]),
acctest.CheckResourceIDPersisted("scaleway_k8s_cluster.networking", &clusterID),
),
},
{
Config: fmt.Sprintf(`
resource "scaleway_vpc" "networking" {
name = "vpc-networking"
}
resource "scaleway_vpc_private_network" "networking" {
name = "pn-networking"
vpc_id = scaleway_vpc.networking.id
}
resource "scaleway_k8s_cluster" "networking" {
cni = "cilium"
version = "%s"
name = "test-networking"
tags = [ "terraform-test", "scaleway_k8s_cluster", "networking" ]
delete_additional_resources = false
private_network_id = scaleway_vpc_private_network.networking.id
pod_cidr = "10.11.0.0/16"
service_cidr = "10.12.0.0/16"
}`, latestK8SVersion),
Check: resource.ComposeTestCheckFunc(
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.networking"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "version", latestK8SVersion),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "cni", "cilium"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "pod_cidr", "10.11.0.0/16"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "service_cidr", "10.12.0.0/16"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "service_dns_ip", "10.12.0.10"),
acctest.CheckResourceIDChanged("scaleway_k8s_cluster.networking", &clusterID),
),
},
{
Config: fmt.Sprintf(`
resource "scaleway_vpc" "networking" {
name = "vpc-networking"
}
resource "scaleway_vpc_private_network" "networking" {
name = "pn-networking"
vpc_id = scaleway_vpc.networking.id
}
resource "scaleway_k8s_cluster" "networking" {
cni = "cilium"
version = "%s"
name = "test-networking"
tags = [ "terraform-test", "scaleway_k8s_cluster", "networking" ]
delete_additional_resources = false
private_network_id = scaleway_vpc_private_network.networking.id
pod_cidr = "10.16.0.0/16"
service_cidr = "10.12.0.0/16"
service_dns_ip = "10.12.0.53"
}`, latestK8SVersion),
Check: resource.ComposeTestCheckFunc(
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.networking"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "version", latestK8SVersion),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "cni", "cilium"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "pod_cidr", "10.16.0.0/16"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "service_cidr", "10.12.0.0/16"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "service_dns_ip", "10.12.0.53"),
acctest.CheckResourceIDChanged("scaleway_k8s_cluster.networking", &clusterID),
),
},
{
Config: fmt.Sprintf(`
resource "scaleway_vpc" "networking" {
name = "vpc-networking"
}
resource "scaleway_vpc_private_network" "networking" {
name = "pn-networking"
vpc_id = scaleway_vpc.networking.id
}
resource "scaleway_k8s_cluster" "networking" {
cni = "cilium"
version = "%s"
name = "test-networking"
tags = [ "terraform-test", "scaleway_k8s_cluster", "networking" ]
delete_additional_resources = true
private_network_id = scaleway_vpc_private_network.networking.id
}`, latestK8SVersion),
Check: resource.ComposeTestCheckFunc(
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.networking"),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "version", latestK8SVersion),
resource.TestCheckResourceAttr("scaleway_k8s_cluster.networking", "cni", "cilium"),
acctest.CheckResourceIDPersisted("scaleway_k8s_cluster.networking", &clusterID),
),
},
},
})
}
Loading
Loading