diff --git a/README.md b/README.md
index 94811c1..4eae809 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,6 @@ sys 0m2.015s
|------|-------------|------|---------|:--------:|
| [cluster\_name](#input\_cluster\_name) | EKS cluster name name component used through out the EKS cluster describing its purpose (ex: dice-dev) | `string` | n/a | yes |
| [operators\_ns](#input\_operators\_ns) | Namespace to create where operators will be installed. | `string` | `"operators"` | no |
-| [region](#input\_region) | AWS region | `string` | n/a | yes |
| [release\_version](#input\_release\_version) | The version of helm charts to use | `string` | n/a | yes |
| [security\_group\_all\_worker\_mgmt\_id](#input\_security\_group\_all\_worker\_mgmt\_id) | The security group representing all of the worker nodes in the cluster. | `string` | n/a | yes |
| [subnets](#input\_subnets) | Specify the subnets used by this cluster | `list(string)` | n/a | yes |
diff --git a/providers.tf b/providers.tf
new file mode 100644
index 0000000..82bcf8b
--- /dev/null
+++ b/providers.tf
@@ -0,0 +1,22 @@
+provider "aws" {
+ region = var.region
+
+ default_tags {
+ tags = {
+ "boc:tf_module_name" = local.module_name
+ "boc:tf_module_version" = local.module_version
+ }
+ }
+}
+
+provider "kubernetes" {
+ experiments {
+ manifest_resource = true
+ }
+}
+
+provider "helm" {
+ kubernetes {
+ # Configuration will be loaded from KUBECONFIG environment variable
+ }
+}
diff --git a/variables.tf b/variables.tf
index 4fad9b2..8592348 100644
--- a/variables.tf
+++ b/variables.tf
@@ -1,48 +1,82 @@
variable "cluster_name" {
description = "EKS cluster name name component used through out the EKS cluster describing its purpose (ex: dice-dev)"
type = string
-}
-
-# tflint-ignore: terraform_unused_declarations
-variable "region" {
- description = "AWS region"
- type = string
+ validation {
+ condition = can(regex("^[a-zA-Z][a-zA-Z0-9-]*$", var.cluster_name)) && length(var.cluster_name) <= 100
+ error_message = "Cluster name must start with a letter, can only contain letters, numbers, and hyphens, and must be no longer than 100 characters."
+ }
}
variable "vpc_id" {
description = "Specify the VPC id that is used by this cluster"
type = string
+ validation {
+ condition = can(regex("^vpc-[a-f0-9]{8,}$", var.vpc_id))
+ error_message = "VPC ID must be a valid vpc-* identifier."
+ }
}
variable "subnets" {
description = "Specify the subnets used by this cluster"
type = list(string)
+ validation {
+ condition = length(var.subnets) >= 2
+ error_message = "At least 2 subnets must be specified for high availability."
+ }
+ validation {
+ condition = alltrue([for s in var.subnets : can(regex("^subnet-[a-f0-9]{8,}$", s))])
+ error_message = "All subnet IDs must be valid subnet-* identifiers."
+ }
}
variable "security_group_all_worker_mgmt_id" {
description = "The security group representing all of the worker nodes in the cluster."
type = string
+ validation {
+ condition = can(regex("^sg-[a-f0-9]{8,}$", var.security_group_all_worker_mgmt_id))
+ error_message = "Security group ID must be a valid sg-* identifier."
+ }
}
variable "operators_ns" {
description = "Namespace to create where operators will be installed."
type = string
default = "operators"
+ validation {
+ condition = can(regex("^[a-z0-9][-a-z0-9]*[a-z0-9]$", var.operators_ns)) && length(var.operators_ns) <= 63
+ error_message = "Namespace must be a valid k8s namespace name: start with alphanumeric, contain only lowercase alphanumeric and hyphens, end with alphanumeric, and be no longer than 63 characters."
+ }
}
variable "tag_costallocation" {
description = "Tag CostAllocation (default)"
type = string
default = "csvd:infrastructure"
+ validation {
+ condition = can(regex("^[\\w\\s+=.@-]+:[\\w\\s+=.@-]+$", var.tag_costallocation))
+ error_message = "Cost allocation tag must be in format 'key:value' and can only contain alphanumeric characters, spaces, and '.+-=@_'."
+ }
}
variable "tags" {
description = "AWS Tags to apply to appropriate resources"
type = map(string)
default = {}
+ validation {
+ condition = length(var.tags) <= 45
+ error_message = "Maximum number of tags allowed is 45."
+ }
+ validation {
+ condition = alltrue([for k, v in var.tags : length(k) <= 128 && length(v) <= 256 && can(regex("^[\\w\\s+=.@-]*$", k)) && can(regex("^[\\w\\s+=.@-]*$", v))])
+ error_message = "Tag keys must be <= 128 chars, values <= 256 chars, and both can only contain alphanumeric characters, spaces, and '.+-=@_'."
+ }
}
variable "release_version" {
description = "The version of helm charts to use"
type = string
+ validation {
+ condition = can(regex("^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9]+)*$", var.release_version))
+ error_message = "Release version must be in semantic versioning format (e.g., 1.2.3 or 1.2.3-alpha)."
+ }
}