Skip to content
Closed
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
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ For questions or issues with the provider, open up an issue in the provider GitH

- `api_key` (String, Sensitive) The Spectro Cloud API key. Can also be set with the `SPECTROCLOUD_APIKEY` environment variable.
- `host` (String) The Spectro Cloud API host url. Can also be set with the `SPECTROCLOUD_HOST` environment variable. Defaults to https://api.spectrocloud.com
- `ignore_insecure_tls_error` (Boolean) Ignore insecure TLS errors for Spectro Cloud API endpoints. Defaults to false.
- `ignore_insecure_tls_error` (Boolean) Ignore insecure TLS errors for Spectro Cloud API endpoints. ⚠️ WARNING: Setting this to true disables SSL certificate verification and makes connections vulnerable to man-in-the-middle attacks. Only use this in development/testing environments or when connecting to self-signed certificates in trusted networks. Defaults to false.
- `project_name` (String) The Palette project the provider will target. If no value is provided, the `Default` Palette project is used. The default value is `Default`.
- `retry_attempts` (Number) Number of retry attempts. Can also be set with the `SPECTROCLOUD_RETRY_ATTEMPTS` environment variable. Defaults to 10.
- `trace` (Boolean) Enable HTTP request tracing. Can also be set with the `SPECTROCLOUD_TRACE` environment variable. To enable Terraform debug logging, set `TF_LOG=DEBUG`. Visit the Terraform documentation to learn more about Terraform [debugging](https://developer.hashicorp.com/terraform/plugin/log/managing).
3 changes: 2 additions & 1 deletion docs/resources/cloudaccount_azure.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ resource "spectrocloud_cloudaccount_azure" "azure-1" {
### Optional

- `cloud` (String) The Azure partition in which the cloud account is located.
Can be 'AzurePublicCloud' for standard Azure regions or 'AzureUSGovernmentCloud' for Azure GovCloud (US) regions.
Can be 'AzurePublicCloud' for standard Azure regions or 'AzureUSGovernmentCloud' for Azure GovCloud (US) regions or 'AzureUSSecretCloud' for Azure Secret Cloud regions.
Default is 'AzurePublicCloud'.
- `context` (String) The context of the Azure configuration. Defaults to `project`. If the `project` context is specified, the project name will sourced from the provider configuration parameter [`project_name`](https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs#schema).
- `disable_properties_request` (Boolean) Disable properties request. This is a boolean value that indicates whether to disable properties request or not. If not specified, the default value is `false`.
- `private_cloud_gateway_id` (String) ID of the private cloud gateway. This is the ID of the private cloud gateway that is used to connect to the private cluster endpoint.
- `tenant_name` (String) The name of the tenant. This is the name of the tenant that is used to connect to the Azure cloud.
- `tls_cert` (String) TLS certificate for authentication. This field is only allowed when cloud is set to 'AzureUSSecretCloud'.

### Read-Only

Expand Down
19 changes: 19 additions & 0 deletions docs/resources/cluster_maas.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ Required:

- `domain` (String) Domain name in which the cluster to be provisioned.

Optional:

- `enable_lxd_vm` (Boolean) Whether to enable LXD VM. Default is `false`.


<a id="nestedblock--machine_pool"></a>
### Nested Schema for `machine_pool`
Expand All @@ -179,6 +183,7 @@ Required:
- `count` (Number) Number of nodes in the machine pool.
- `instance_type` (Block List, Min: 1, Max: 1) (see [below for nested schema](#nestedblock--machine_pool--instance_type))
- `name` (String) Name of the machine pool.
- `network` (Block List, Min: 1, Max: 1) (see [below for nested schema](#nestedblock--machine_pool--network))
- `placement` (Block List, Min: 1, Max: 1) (see [below for nested schema](#nestedblock--machine_pool--placement))

Optional:
Expand All @@ -193,6 +198,7 @@ Optional:
- `node_tags` (Set of String) Node tags to dynamically place nodes in a pool by using MAAS automatic tags. Specify the tag values that you want to apply to all nodes in the node pool.
- `taints` (Block List) (see [below for nested schema](#nestedblock--machine_pool--taints))
- `update_strategy` (String) Update strategy for the machine pool. Valid values are `RollingUpdateScaleOut` and `RollingUpdateScaleIn`.
- `use_lxd_vm` (Boolean) Whether to use LXD VM. Default is `false`.

<a id="nestedblock--machine_pool--instance_type"></a>
### Nested Schema for `machine_pool.instance_type`
Expand All @@ -203,6 +209,19 @@ Required:
- `min_memory_mb` (Number) Minimum memory in MB required for the machine pool node.


<a id="nestedblock--machine_pool--network"></a>
### Nested Schema for `machine_pool.network`

Required:

- `network_name` (String) The name of the network in which VMs are created/located.

Optional:

- `parent_pool_uid` (String) The UID of the parent pool which allocates IPs for this IPPool.
- `static_ip` (Boolean) Whether to use static IP. Default is `false`.


<a id="nestedblock--machine_pool--placement"></a>
### Nested Schema for `machine_pool.placement`

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/registry_oci.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Optional:
Optional:

- `certificate` (String) Specifies the TLS certificate used for secure communication. Required for enabling SSL/TLS encryption.
- `insecure_skip_verify` (Boolean) Disables TLS certificate verification when set to true. Use with caution as it may expose connections to security risks.
- `insecure_skip_verify` (Boolean) Disables TLS certificate verification when set to true. ⚠️ WARNING: Setting this to true disables SSL certificate verification and makes connections vulnerable to man-in-the-middle attacks. Only use this when connecting to registries with self-signed certificates in trusted networks.



Expand Down
2 changes: 1 addition & 1 deletion docs/resources/sso.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Optional:

- `default_team_ids` (Set of String) A set of default team IDs assigned to users.
- `identity_provider_ca_certificate` (String) Certificate authority (CA) certificate for the identity provider.
- `insecure_skip_tls_verify` (Boolean) Boolean to skip TLS verification for identity provider communication.
- `insecure_skip_tls_verify` (Boolean) Boolean to skip TLS verification for identity provider communication. ⚠️ WARNING: Setting this to true disables SSL certificate verification and makes connections vulnerable to man-in-the-middle attacks. Only use this when connecting to identity providers with self-signed certificates in trusted networks.
- `user_info_endpoint` (Block List, Max: 1) To allow Palette to query the OIDC userinfo endpoint using the provided Issuer URL. Palette will first attempt to retrieve role and group information from userInfo endpoint. If unavailable, Palette will fall back to using Required Claims as specified above. Use the following fields to specify what Required Claims Palette will include when querying the userinfo endpoint. (see [below for nested schema](#nestedblock--oidc--user_info_endpoint))

Read-Only:
Expand Down
34 changes: 34 additions & 0 deletions examples/resources/eks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Basic Cluster demo

End-to-end example of provisioning a new AWS K8s cluster with all of its dependencies. This terraform configuration
will provision the following resources on Spectro Cloud:
- AWS Cloud Account
- Eks Cluster Profile
- Eks Cluster

## Instructions:

Clone this repository to a local directory, and then change directory to `examples/e2e/eks`. Proceed with the following:
1. Follow the Spectro Cloud documentation to create an AWS cloud account with appropriate permissions:
[AWS Cloud Account](https://docs.spectrocloud.com/clusters/?clusterType=aws_cluster#awscloudaccountpermissions).
2. From the current directory, copy the template variable file `terraform.template.tfvars` to a new file `terraform.tfvars`.
3. Specify and update all the placeholder values in the `terraform.tfvars` file.
4. Initialize and run terraform: `terraform init && terraform apply`.
5. Wait for the cluster creation to finish.

Once the cluster is provisioned, the cluster _kubeconfig_ file is exported in the current working directly.

Export the kubeconfig and check cluster pods:

```shell
export KUBECONFIG=kubeconfig_eks
kubectl get pod -A
```

## Clean up:

Run the destroy operation:

```shell
terraform destroy
```
28 changes: 28 additions & 0 deletions examples/resources/eks/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
terraform {
required_providers {
spectrocloud = {
version = ">= 0.1"
source = "spectrocloud/spectrocloud"
}
}
}

variable "sc_host" {
description = "Spectro Cloud Endpoint"
default = "api.spectrocloud.com"
}

variable "sc_api_key" {
description = "Spectro Cloud API key"
}

variable "sc_project_name" {
description = "Spectro Cloud Project (e.g: Default)"
default = "Default"
}

provider "spectrocloud" {
host = var.sc_host
api_key = var.sc_api_key
project_name = var.sc_project_name
}
36 changes: 36 additions & 0 deletions examples/resources/eks/resource_cluster.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
resource "spectrocloud_cluster_eks" "cluster" {
name = "ran-tf-eks"
context = "tenant"
tags_map = {"QA" = "ranjithroy@_ .:/=+-@.@123"}

cluster_profile {
id = "68a6e0bc500766a5c9241784"
}

cloud_account_id = "68a6e0ec788fd02b1e0151a4"


cloud_config {
ssh_key_name = var.aws_ssh_key_name
region = var.aws_region
vpc_id = var.aws_vpc_id
azs = ["ap-south-1a", "ap-south-1b"]
}

machine_pool {
name = "worker-basic"
count = 1
instance_type = "t3.xlarge"
azs = ["ap-south-1a", "ap-south-1b"]
disk_size_gb = 60
}

machine_pool {
name = "worker-basic-2"
count = 1
instance_type = "t3.xlarge"
azs = ["ap-south-1a", "ap-south-1b"]
disk_size_gb = 60
}

}
43 changes: 43 additions & 0 deletions examples/resources/eks/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#variable "cloud_account_type" {}

## Option A (When Using access key and secret key)
#variable "aws_access_key" {
# default = ""
#}
#variable "aws_secret_key" {
# default = ""
#}

# Option B (When Using sts info, arn and external id)
#variable "arn" {
# default = ""
#}
#variable "external_id" {
# default = ""
#}
#
## Cluster
variable "aws_ssh_key_name" {
default = ""
}
variable "aws_region" {}
variable "aws_vpc_id" {
default = ""
}

# Provisioning Option A (Dynamic)
variable "azs" {
default = []
type = list(string)
}

# Provisioning Option B (Static)
variable "cp_azs_subnets_map" {
default = {}
type = map(string)
}

variable "worker_azs_subnets_map" {
default = {}
type = map(string)
}
16 changes: 16 additions & 0 deletions examples/resources/spectrocloud_cloudaccount_azure/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,19 @@ resource "spectrocloud_cloudaccount_azure" "azure_government" {
cloud = "AzureUSGovernmentCloud"
context = "project"
}

# Example 3: Azure US Secret Cloud account with TLS certificate
resource "spectrocloud_cloudaccount_azure" "azure_secret" {
name = "azure-secret-account"
azure_tenant_id = var.azure_secret_tenant_id
azure_client_id = var.azure_secret_client_id
azure_client_secret = var.azure_secret_client_secret

cloud = "AzureUSSecretCloud"
context = "project"

# TLS certificate is only allowed when cloud is set to "AzureUSSecretCloud"
tls_cert = var.azure_secret_tls_cert

tenant_name = "Secret Cloud Tenant"
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,10 @@ variable "azure_secret_client_secret" {
default = ""
sensitive = true
}

variable "azure_secret_tls_cert" {
description = "TLS certificate for Azure US Secret Cloud authentication"
type = string
default = ""
sensitive = true
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/hashicorp/terraform-plugin-docs v0.16.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0
github.com/robfig/cron v1.2.0
github.com/spectrocloud/palette-sdk-go v0.0.0-20250813031623-91ef23e78e8f
github.com/spectrocloud/palette-sdk-go v0.0.0-20250826051324-b2ea90bf151b
github.com/stretchr/testify v1.10.0
gopkg.in/yaml.v3 v3.0.1
gotest.tools v2.2.0+incompatible
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,8 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spectrocloud/palette-sdk-go v0.0.0-20250813031623-91ef23e78e8f h1:KAEMjdoWEQ9FlHIVybcLDILngTmuhD7BqsNve4z8W5E=
github.com/spectrocloud/palette-sdk-go v0.0.0-20250813031623-91ef23e78e8f/go.mod h1:wIt8g7I7cmcQvTo5ktwhSF0/bWq6uRdxGBs9dwTpleU=
github.com/spectrocloud/palette-sdk-go v0.0.0-20250826051324-b2ea90bf151b h1:Xhup+ut+6exZDTKu2SYTFHrAM/PZ625/w+X5DRwirG4=
github.com/spectrocloud/palette-sdk-go v0.0.0-20250826051324-b2ea90bf151b/go.mod h1:wIt8g7I7cmcQvTo5ktwhSF0/bWq6uRdxGBs9dwTpleU=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
Expand Down
6 changes: 3 additions & 3 deletions spectrocloud/application_create_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func toAppDeploymentTargetClusterLimits(d *schema.ResourceData) *models.V1AppDep
limits := config["limits"].([]interface{})[i].(map[string]interface{})
if limits["cpu"] != nil && limits["memory"] != nil {
return &models.V1AppDeploymentTargetClusterLimits{
CPU: int32(limits["cpu"].(int)),
MemoryMiB: int32(limits["memory"].(int)),
StorageGiB: int32(limits["storage"].(int)),
CPU: SafeInt32(limits["cpu"].(int)),
MemoryMiB: SafeInt32(limits["memory"].(int)),
StorageGiB: SafeInt32(limits["storage"].(int)),
}
}
}
Expand Down
33 changes: 32 additions & 1 deletion spectrocloud/cluster_common_crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package spectrocloud

import (
"context"
"errors"
"fmt"
"log"
"time"

Expand Down Expand Up @@ -140,9 +142,38 @@ func waitForClusterCreation(ctx context.Context, d *schema.ResourceData, uid str
// Wait, catching any errors
_, err := stateConf.WaitForStateContext(ctx)
if err != nil {
// Check if this is a timeout error
var timeoutErr *retry.TimeoutError
if errors.As(err, &timeoutErr) {
// Get current cluster state for warning message
cluster, stateErr := c.GetCluster(d.Id())
currentState := timeoutErr.LastState
if currentState == "" {
currentState = "Unknown"
}
if stateErr == nil && cluster != nil && cluster.Status != nil {
currentState = cluster.Status.State
if cluster.Status.State == "Running" {
if clusterSummary, _ := c.GetClusterOverview(d.Id()); clusterSummary != nil && clusterSummary.Status.Health != nil {
if clusterSummary.Status.Health.State != "" && clusterSummary.Status.Health.State != "Healthy" {
currentState += "-" + clusterSummary.Status.Health.State
}
}
}
}

// Return warning instead of error
diags = append(diags, diag.Diagnostic{
Severity: diag.Warning,
Summary: "Cluster creation timeout",
Detail: fmt.Sprintf("Cluster creation timed out after waiting for %v. Current cluster state is '%s'. The cluster may still be provisioning in the background and will eventually reach the 'Running-Healthy' state.", d.Timeout(schema.TimeoutCreate)-1*time.Minute, currentState),
})
return diags, false
}
// For non-timeout errors, still return the error
return diag.FromErr(err), true
}
return nil, false
return diags, false
}

// var resourceClusterUpdatePendingStates = []string{
Expand Down
6 changes: 5 additions & 1 deletion spectrocloud/cluster_common_hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"hash/fnv"
"sort"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -467,7 +468,10 @@ func hash(s string) uint32 {
func YamlContentHash(yamlContent string) string {
canonicalContent := yamlContentToCanonicalString(yamlContent)
h := fnv.New64a()
h.Write([]byte(canonicalContent))
if _, err := h.Write([]byte(canonicalContent)); err != nil {
// If hash writing fails, return a fallback hash
return fmt.Sprintf("error_hash_%d", time.Now().UnixNano())
}
return fmt.Sprintf("%x", h.Sum64())
}

Expand Down
15 changes: 15 additions & 0 deletions spectrocloud/constants/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package constants

const (
// Int32MaxValue represents the maximum value for int32 type (2^31 - 1)
Int32MaxValue = 2147483647

// Int32MinValue represents the minimum value for int32 type (-2^31)
Int32MinValue = -2147483648

// UInt32MaxValue represents the maximum value for uint32 type (2^32 - 1)
UInt32MaxValue = 4294967295

// Int64MaxValue represents the maximum value for int64 type (2^63 - 1)
Int64MaxValue = 9223372036854775807
)
Loading
Loading