Skip to content
Open
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 .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @yzha645 @nanux @bianchi2
* @yzha645 @nanux @bianchi2 @kush982
10 changes: 7 additions & 3 deletions config.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ products = ["<LIST_OF_PRODUCTS>"]

# List of IP ranges that are allowed to access the running applications over the World Wide Web.
# By default the deployed applications are publicly accessible (0.0.0.0/0). You can restrict this access by changing the
# default value to your desired CIDR blocks. e.g. ["10.20.0.0/16" , "99.68.64.0/10"]
# default value to your desired CIDR blocks.
# Examples:
# IPv4: ["10.20.0.0/16", "99.68.64.0/10"]
# IPv6: ["2001:db8::/32", "2001:db8:1234::/48"]
# Mixed: ["10.20.0.0/16", "2001:db8::/32"]
whitelist_cidr = ["0.0.0.0/0"]

# By default, Ingress controller listens on 443 and 80. You can enable only http port 80 by
Expand Down Expand Up @@ -126,8 +130,8 @@ max_cluster_capacity = 5
# If undefined, current AWS region will be used (the one set in `region` in this file). Defaults to undefined.
# osquery_fleet_enrollment_secret_region_aws = ""

# The value of OSQUERY_ENV that will be used to send logs to Splunk. It should not be something like production
# or prod-west2 but should instead relate to the product, platform, or team. Defaults to osquery_dc_e2e_tests
# The value of OSQUERY_ENV that will be used to send logs to Splunk. It should not be something like "production"
# or "prod-west2" but should instead relate to the product, platform, or team. Defaults to osquery_dc_e2e_tests
# osquery_env = "osquery_dc_e2e_tests"

# Osquery version. Defaults to 5.7.0. Osquery is installed as yum package, make sure you test the version before an update
Expand Down
4 changes: 3 additions & 1 deletion modules/AWS/eks/locals.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

locals {

oicd_provider = replace(module.eks.cluster_oidc_issuer_url, "https://", "")
Expand All @@ -9,7 +8,10 @@ locals {

ami_type = "AL2_x86_64"

# IPv4 service CIDR (used for backward compatibility)
cluster_service_ipv4_cidr = "172.20.0.0/16"

# IPv6 service CIDR will be automatically assigned by AWS

osquery_secret_region = var.osquery_secret_region != "" ? var.osquery_secret_region : var.region

Expand Down
13 changes: 12 additions & 1 deletion modules/AWS/eks/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ module "eks" {
kube-proxy = {}
vpc-cni = {
resolve_conflicts_on_create = "OVERWRITE"
configuration_values = jsonencode({
env = {
# Enable IPv6 for pods
ENABLE_IPV6 = "true"
# Enable prefix delegation
ENABLE_PREFIX_DELEGATION = "true"
}
})
}
aws-ebs-csi-driver = {
resolve_conflicts_on_create = "OVERWRITE"
Expand Down Expand Up @@ -66,11 +74,14 @@ module "eks" {
create_kms_key = false
cluster_encryption_config = {}


# Networking
vpc_id = var.vpc_id
subnet_ids = var.subnets
cluster_service_ipv4_cidr = local.cluster_service_ipv4_cidr

# Enable IPv6 for cluster
cluster_ip_family = "ipv6"
create_cni_ipv6_iam_policy = true

# Managed node group defaults
eks_managed_node_group_defaults = {
Expand Down
25 changes: 14 additions & 11 deletions modules/AWS/ingress/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ resource "helm_release" "ingress" {
controller = {
config = {
# If true, NGINX passes the incoming "X-Forwarded-*" headers to upstreams.
# https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-forwarded-headers
# https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
"use-forwarded-headers" : "true"
"use-forwarded-headers" : "true",
# Enable IPv6 in nginx
"enable-ipv6" : "true",
# Configure IPv6 resolver
"enable-real-ip" : "true",
"proxy-real-ip-cidr" : "::/0"
}
service = {
# The value "Local" preserves the client source IP.
# https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer
externalTrafficPolicy = "Local"

enableHttps = local.enable_https_ingress
Expand All @@ -80,19 +82,20 @@ resource "helm_release" "ingress" {
}
annotations = {
# Whether the LB will be internet-facing or internal.
# https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.3/guide/service/annotations/#lb-internal
"service.beta.kubernetes.io/aws-load-balancer-internal" : "false"

# Specifies the IP address type, in this case "dualstack" will allow clients
# can access the load balancer using either IPv4 or IPv6.
# https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/annotations/#ip-address-type
# Enable dualstack mode for the load balancer
"service.beta.kubernetes.io/aws-load-balancer-ip-address-type" : "dualstack"

# The protocol to use for backend traffic between the load balancer and the k8s pods.
# https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.3/guide/service/annotations/#backend-protocol
# Configure IPv6 health checks
"service.beta.kubernetes.io/aws-load-balancer-healthcheck-protocol" : "HTTP"
"service.beta.kubernetes.io/aws-load-balancer-healthcheck-port" : "80"
"service.beta.kubernetes.io/aws-load-balancer-healthcheck-path" : "/healthz"

# The protocol to use for backend traffic
"service.beta.kubernetes.io/aws-load-balancer-backend-protocol" : "http"

# LoadBalancer is created by AWS not Terraform, so we need to add resource tags to it
# LoadBalancer tags
"service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags" : local.resource_tags
}
}
Expand Down
8 changes: 5 additions & 3 deletions modules/AWS/ingress/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ variable "enable_ssh_tcp" {
}

variable "load_balancer_access_ranges" {
description = "List of allowed CIDRs that can access the load balancer."
description = "List of allowed CIDRs (IPv4 and IPv6) that can access the load balancer."
type = list(string)
validation {
condition = alltrue([
for cidr in var.load_balancer_access_ranges : can(regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]|1[0-9]|2[0-9]|3[0-2])$", cidr))])
error_message = "Invalid CIDR. Valid format is a list of '<IPv4>/[0-32]' e.g: [\"10.0.0.0/18\"]."
for cidr in var.load_balancer_access_ranges : can(regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]|1[0-9]|2[0-9]|3[0-2])$", cidr)) ||
can(regex("^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$", cidr))
])
error_message = "Invalid CIDR. Valid format is a list of IPv4 CIDR '<IPv4>/[0-32]' (e.g: [\"10.0.0.0/18\"]) or IPv6 CIDR '<IPv6>/[0-128]' (e.g: [\"2001:db8::/32\"])."
}
}

Expand Down
15 changes: 13 additions & 2 deletions modules/AWS/rds/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,20 @@ module "security_group" {
from_port = 5432
to_port = 5432
protocol = "tcp"
description = "PostgreSQL access from within EKS cluster"
description = "PostgreSQL access from within EKS cluster (IPv4)"
cidr_blocks = var.vpc.vpc_cidr_block
},
}
]

# IPv6 ingress
ingress_with_ipv6_cidr_blocks = [
{
from_port = 5432
to_port = 5432
protocol = "tcp"
description = "PostgreSQL access from within EKS cluster (IPv6)"
ipv6_cidr_blocks = var.vpc.vpc_ipv6_cidr_block
}
]
}

Expand Down
7 changes: 6 additions & 1 deletion modules/AWS/vpc/locals.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
locals {
subnets = [for cidr_block in cidrsubnets(var.vpc_cidr, 2, 2) : cidrsubnets(cidr_block, 2, 2)]
# For IPv4, we split the VPC CIDR into 2 parts with 2 bits each, then split each part into 2 more with 2 bits each
# For IPv6, we use the AWS VPC module's built-in IPv6 subnet allocation
is_ipv6 = can(regex("^([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$", var.vpc_cidr))

# For IPv4, calculate subnet ranges. For IPv6, we'll let the VPC module handle it
subnets = local.is_ipv6 ? [[], []] : [for cidr_block in cidrsubnets(var.vpc_cidr, 2, 2) : cidrsubnets(cidr_block, 2, 2)]
}

22 changes: 22 additions & 0 deletions modules/AWS/vpc/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,28 @@ module "vpc" {
single_nat_gateway = true
enable_dns_hostnames = true

# Enable IPv6 support
enable_ipv6 = true
assign_ipv6_address_on_creation = true

# Enable IPv6 DNS support
enable_dns_support = true

# Create IPv6-enabled subnets with Amazon-provided IPv6 CIDR blocks
create_egress_only_igw = true
enable_ipv6_public_subnet = true
enable_ipv6_private_subnet = true
public_subnet_ipv6_prefixes = [0, 1]
private_subnet_ipv6_prefixes = [2, 3]

public_subnet_suffix = "public-subnet"
private_subnet_suffix = "private-subnet"

# Tags for subnets to support EKS
public_subnet_tags = {
"kubernetes.io/role/elb" = "1"
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = "1"
}
}
9 changes: 6 additions & 3 deletions modules/AWS/vpc/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ variable "vpc_name" {
}

variable "vpc_cidr" {
description = "Cidr block for vpc"
description = "CIDR block for VPC (IPv4 or IPv6)"
type = string
default = "10.0.0.0/18"
validation {
condition = can(regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([1-9]|1[0-9]|2[0-4])$", var.vpc_cidr))
error_message = "Invalid CIDR. Valid format is '<IPv4>/[1-24]' e.g: 10.0.0.0/18."
condition = (
can(regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([1-9]|1[0-9]|2[0-4])$", var.vpc_cidr)) ||
can(regex("^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$", var.vpc_cidr))
)
error_message = "Invalid VPC CIDR block. Must be a valid IPv4 CIDR (e.g., 10.0.0.0/16) or IPv6 CIDR (e.g., 2001:db8::/32) with appropriate prefix length."
}
}
15 changes: 14 additions & 1 deletion modules/common/security_group.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
resource "aws_security_group" "vpc" {
name_prefix = format("%s_sg", local.vpc_name)
description = "VPC security group."
description = "VPC security group with IPv4 and IPv6 support."
vpc_id = module.vpc.vpc_id

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
description = "Allow all outbound traffic (IPv4 and IPv6)"
}

tags = {
Name = format("%s_sg", local.vpc_name)
}
}
8 changes: 5 additions & 3 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,15 @@ variable "eks_additional_roles" {
}

variable "whitelist_cidr" {
description = "List of CIDRs allowed accessing the application(s)."
description = "List of CIDRs (IPv4 and IPv6) allowed accessing the application(s)."
default = ["0.0.0.0/0"]
type = list(string)
validation {
condition = alltrue([
for o in var.whitelist_cidr : can(regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]|1[0-9]|2[0-9]|3[0-2])$", o))])
error_message = "Invalid whitelist CIDR. Valid format is a list of '<IPv4>/[0-32]' e.g: [\"10.0.0.0/18\"]."
for o in var.whitelist_cidr : can(regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]|1[0-9]|2[0-9]|3[0-2])$", o)) ||
can(regex("^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$", o))
])
error_message = "Invalid whitelist CIDR. Valid format is a list of IPv4 CIDR '<IPv4>/[0-32]' (e.g: [\"10.0.0.0/18\"]) or IPv6 CIDR '<IPv6>/[0-128]' (e.g: [\"2001:db8::/32\"])."
}
}

Expand Down
Loading