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
2 changes: 2 additions & 0 deletions examples/simple/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ module "materialize_infrastructure" {
node_group_capacity_type = "ON_DEMAND"
enable_cluster_creator_admin_permissions = true

swap_enabled = var.swap_enabled

# Storage Configuration
bucket_force_destroy = true

Expand Down
5 changes: 5 additions & 0 deletions examples/simple/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
variable "swap_enabled" {
description = "Enable swap for Materialize. When enabled, this configures swap on a new nodepool, and adds it to the clusterd node selectors."
type = bool
default = false
}
35 changes: 34 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,38 @@ module "eks" {
]
}

module "swap_node_group" {
source = "./modules/eks-node-group"
count = var.swap_enabled ? 1 : 0

cluster_name = module.eks.cluster_name
subnet_ids = local.network_private_subnet_ids
node_group_name = "${local.name_prefix}-mz-swap"
instance_types = var.node_group_instance_types
swap_enabled = true
min_size = var.node_group_min_size
max_size = var.node_group_max_size
desired_size = var.node_group_desired_size
cluster_service_cidr = module.eks.cluster_service_cidr
cluster_primary_security_group_id = module.eks.node_security_group_id

labels = {
"materialize.cloud/swap" = "true"
"workload" = "materialize-instance"
}

tags = merge(
local.common_tags,
{
Swap = "true"
}
)

depends_on = [
module.eks,
]
}

module "aws_lbc" {
source = "./modules/aws-lbc"
count = var.install_aws_load_balancer_controller ? 1 : 0
Expand Down Expand Up @@ -136,6 +168,7 @@ module "operator" {

depends_on = [
module.eks,
module.swap_node_group,
module.database,
module.storage,
module.networking,
Expand Down Expand Up @@ -199,7 +232,7 @@ locals {
}
operator = {
clusters = {
swap_enabled = false
swap_enabled = var.swap_enabled
}
image = var.orchestratord_version == null ? {} : {
tag = var.orchestratord_version
Expand Down
50 changes: 50 additions & 0 deletions modules/eks-node-group/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 5.0 |
| <a name="requirement_kubernetes"></a> [kubernetes](#requirement\_kubernetes) | ~> 2.0 |

## Providers

No providers.

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_node_group"></a> [node\_group](#module\_node\_group) | terraform-aws-modules/eks/aws//modules/eks-managed-node-group | ~> 20.0 |

## Resources

No resources.

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_ami_type"></a> [ami\_type](#input\_ami\_type) | AMI type for the node group. | `string` | `"BOTTLEROCKET_ARM_64"` | no |
| <a name="input_capacity_type"></a> [capacity\_type](#input\_capacity\_type) | Capacity type for worker nodes (ON\_DEMAND or SPOT). | `string` | `"ON_DEMAND"` | no |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster to attach the node group to. | `string` | n/a | yes |
| <a name="input_cluster_primary_security_group_id"></a> [cluster\_primary\_security\_group\_id](#input\_cluster\_primary\_security\_group\_id) | The ID of the primary security group for the cluster | `string` | n/a | yes |
| <a name="input_cluster_service_cidr"></a> [cluster\_service\_cidr](#input\_cluster\_service\_cidr) | The CIDR block for the cluster service | `string` | n/a | yes |
| <a name="input_desired_size"></a> [desired\_size](#input\_desired\_size) | Desired number of worker nodes. | `number` | `1` | no |
| <a name="input_disk_setup_image"></a> [disk\_setup\_image](#input\_disk\_setup\_image) | Docker image for the disk setup script | `string` | `"docker.io/materialize/ephemeral-storage-setup-image:v0.4.0"` | no |
| <a name="input_iam_role_use_name_prefix"></a> [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Use name prefix for IAM roles | `bool` | `true` | no |
| <a name="input_instance_types"></a> [instance\_types](#input\_instance\_types) | Instance types for worker nodes.<br/><br/>Recommended Configuration:<br/>- For other workloads: `r7g`, `r6g` families (ARM-based Graviton, without local disks)<br/>- For materialize instance workloads: `r6gd`, `r7gd` families (ARM-based Graviton, with local NVMe disks)<br/>- Enable disk setup when using instance types with local storage | `list(string)` | n/a | yes |
| <a name="input_labels"></a> [labels](#input\_labels) | Labels to apply to the node group. | `map(string)` | `{}` | no |
| <a name="input_max_size"></a> [max\_size](#input\_max\_size) | Maximum number of worker nodes. | `number` | `4` | no |
| <a name="input_min_size"></a> [min\_size](#input\_min\_size) | Minimum number of worker nodes. | `number` | `1` | no |
| <a name="input_node_group_name"></a> [node\_group\_name](#input\_node\_group\_name) | Name of the node group. | `string` | n/a | yes |
| <a name="input_node_taints"></a> [node\_taints](#input\_node\_taints) | Taints to apply to the node group. | <pre>list(object({<br/> key = string<br/> value = string<br/> effect = string<br/> }))</pre> | `[]` | no |
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | List of subnet IDs for the node group. | `list(string)` | n/a | yes |
| <a name="input_swap_enabled"></a> [swap\_enabled](#input\_swap\_enabled) | Whether to enable swap on the local NVMe disks. | `bool` | `true` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to apply to all resources | `map(string)` | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_node_group_arn"></a> [node\_group\_arn](#output\_node\_group\_arn) | ARN of the EKS managed node group. |
| <a name="output_node_group_id"></a> [node\_group\_id](#output\_node\_group\_id) | ID of the EKS managed node group. |
51 changes: 51 additions & 0 deletions modules/eks-node-group/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
locals {
node_labels = merge(
var.labels,
var.swap_enabled ? {
"materialize.cloud/swap" = "true"
"materialize.cloud/disk-config-required" = "true"
} : {}
)

swap_bootstrap_args = <<-EOF
[settings.bootstrap-containers.diskstrap]
source = "${var.disk_setup_image}"
mode = "always"
essential = true
user-data = "${base64encode(jsonencode(["swap", "--cloud-provider", "aws", "--bottlerocket-enable-swap"]))}"

[settings.kernel.sysctl]
"vm.swappiness" = "100"
"vm.min_free_kbytes" = "1048576"
"vm.watermark_scale_factor" = "100"
EOF
}

module "node_group" {
source = "terraform-aws-modules/eks/aws//modules/eks-managed-node-group"
version = "~> 20.0"

cluster_name = var.cluster_name
subnet_ids = var.subnet_ids
name = var.node_group_name
desired_size = var.desired_size
min_size = var.min_size
max_size = var.max_size
instance_types = var.instance_types
capacity_type = var.capacity_type
ami_type = var.ami_type
labels = local.node_labels

taints = var.node_taints

# useful to disable this when prefix might be too long and hit following char limit
# expected length of name_prefix to be in the range (1 - 38)
iam_role_use_name_prefix = var.iam_role_use_name_prefix

bootstrap_extra_args = var.swap_enabled ? local.swap_bootstrap_args : ""

cluster_service_cidr = var.cluster_service_cidr
cluster_primary_security_group_id = var.cluster_primary_security_group_id

tags = var.tags
}
9 changes: 9 additions & 0 deletions modules/eks-node-group/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "node_group_arn" {
description = "ARN of the EKS managed node group."
value = module.node_group.node_group_arn
}

output "node_group_id" {
description = "ID of the EKS managed node group."
value = module.node_group.node_group_id
}
122 changes: 122 additions & 0 deletions modules/eks-node-group/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
variable "cluster_name" {
description = "Name of the EKS cluster to attach the node group to."
type = string
nullable = false
}

variable "subnet_ids" {
description = "List of subnet IDs for the node group."
type = list(string)
nullable = false
}

variable "node_group_name" {
description = "Name of the node group."
type = string
nullable = false
}

variable "desired_size" {
description = "Desired number of worker nodes."
type = number
default = 1
nullable = false
}

variable "min_size" {
description = "Minimum number of worker nodes."
type = number
default = 1
nullable = false
}

variable "max_size" {
description = "Maximum number of worker nodes."
type = number
default = 4
nullable = false
}

variable "instance_types" {
description = <<EOF
Instance types for worker nodes.

Recommended Configuration:
- For other workloads: `r7g`, `r6g` families (ARM-based Graviton, without local disks)
- For materialize instance workloads: `r6gd`, `r7gd` families (ARM-based Graviton, with local NVMe disks)
- Enable disk setup when using instance types with local storage
EOF
type = list(string)
nullable = false
}

variable "capacity_type" {
description = "Capacity type for worker nodes (ON_DEMAND or SPOT)."
type = string
default = "ON_DEMAND"
validation {
condition = contains(["ON_DEMAND", "SPOT"], var.capacity_type)
error_message = "Capacity type must be either ON_DEMAND or SPOT."
}
}

variable "ami_type" {
description = "AMI type for the node group."
type = string
default = "BOTTLEROCKET_ARM_64"
nullable = false
}

variable "labels" {
description = "Labels to apply to the node group."
type = map(string)
default = {}
}

variable "node_taints" {
description = "Taints to apply to the node group."
type = list(object({
key = string
value = string
effect = string
}))
default = []
}

variable "tags" {
description = "Tags to apply to all resources"
type = map(string)
default = {}
}

variable "swap_enabled" {
description = "Whether to enable swap on the local NVMe disks."
type = bool
default = true
nullable = false
}

variable "disk_setup_image" {
description = "Docker image for the disk setup script"
type = string
default = "docker.io/materialize/ephemeral-storage-setup-image:v0.4.0"
nullable = false
}

variable "cluster_service_cidr" {
description = "The CIDR block for the cluster service"
type = string
nullable = false
}

variable "cluster_primary_security_group_id" {
description = "The ID of the primary security group for the cluster"
type = string
nullable = false
}

variable "iam_role_use_name_prefix" {
description = "Use name prefix for IAM roles"
type = bool
default = true
}
14 changes: 14 additions & 0 deletions modules/eks-node-group/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.0"
}
}
}
5 changes: 5 additions & 0 deletions modules/eks/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ output "cluster_name" {
value = module.eks.cluster_name
}

output "cluster_service_cidr" {
description = "CIDR of kubernetes service IP addresses"
value = module.eks.cluster_service_cidr
}

output "cluster_security_group_id" {
description = "Security group ID attached to the EKS cluster"
value = module.eks.cluster_security_group_id
Expand Down
6 changes: 6 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,12 @@ variable "enable_disk_support" {
default = true
}

variable "swap_enabled" {
description = "Enable swap for Materialize. When enabled, this configures swap on a new nodepool, and adds it to the clusterd node selectors."
type = bool
default = false
}

variable "disk_support_config" {
description = "Advanced configuration for disk support (only used when enable_disk_support = true)"
type = object({
Expand Down