Skip to content

Commit 5eda96d

Browse files
ciriskedleonkuperman
authored andcommitted
wip
1 parent 9e08fd1 commit 5eda96d

File tree

9 files changed

+590
-0
lines changed

9 files changed

+590
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Example of EKS cluster connected to CAST AI with enabled Kvisor security agent
2+
Following this example creates EKS cluster and its supporting resources using AWS community modules.\
3+
After EKS cluster is created it is onboarded to CAST AI.\
4+
[Kvisor security agent](https://docs.cast.ai/docs/kvisor) is deployed to the cluster and security policies are enabled.\
5+
See `install_security_agent` and `kvisor_values` variables in `castai.tf` file.\
6+
Example configuration should be analysed in the following order:
7+
1. Create VPC - `vpc.tf`
8+
2. Create EKS cluster - `eks.tf`
9+
3. Create CAST AI related resources to connect EKS cluster to CAST AI with Kvisor enabled - `castai.tf`
10+
11+
# Usage
12+
1. Rename `tf.vars.example` to `tf.vars`
13+
2. Update `tf.vars` file with your cluster name, cluster region and CAST AI API token
14+
15+
| Variable | Description |
16+
| --- | --- |
17+
| cluster_name = "" | Name of cluster |
18+
| cluster_region = "" | Name of region of cluster |
19+
| castai_api_token = "" | Cast api token |
20+
21+
3. Initialize Terraform. Under example root folder run:
22+
```
23+
terraform init
24+
```
25+
4. Run Terraform apply:
26+
```
27+
terraform apply -var-file=tf.vars
28+
```
29+
5. To destroy resources created by this example:
30+
```
31+
terraform destroy -var-file=tf.vars
32+
```
33+
34+
Please refer to this guide if you run into any issues https://docs.cast.ai/docs/terraform-troubleshooting
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# 3. Connect EKS cluster to CAST AI with enabled Kvisor security agent.
2+
3+
# Configure Data sources and providers required for CAST AI connection.
4+
data "aws_caller_identity" "current" {}
5+
6+
# Configure EKS cluster connection using CAST AI eks-cluster module.
7+
resource "castai_eks_clusterid" "cluster_id" {
8+
account_id = data.aws_caller_identity.current.account_id
9+
region = var.cluster_region
10+
cluster_name = var.cluster_name
11+
}
12+
13+
resource "castai_eks_user_arn" "castai_user_arn" {
14+
cluster_id = castai_eks_clusterid.cluster_id.id
15+
}
16+
17+
# Create AWS IAM policies and a user to connect to CAST AI.
18+
module "castai-eks-role-iam" {
19+
source = "castai/eks-role-iam/castai"
20+
version = "~> 1.0"
21+
22+
aws_account_id = data.aws_caller_identity.current.account_id
23+
aws_cluster_region = var.cluster_region
24+
aws_cluster_name = var.cluster_name
25+
aws_cluster_vpc_id = module.vpc.vpc_id
26+
27+
castai_user_arn = castai_eks_user_arn.castai_user_arn.arn
28+
29+
create_iam_resources_per_cluster = true
30+
}
31+
32+
# Install CAST AI with enabled Kvisor security agent.
33+
module "castai-eks-cluster" {
34+
source = "castai/eks-cluster/castai"
35+
version = "~> 13.0"
36+
37+
kvisor_grpc_addr = var.kvisor_grpc_addr
38+
39+
# Kvisor is an open-source security agent from CAST AI.
40+
# install_security_agent by default installs Kvisor controller (k8s: deployment)
41+
# https://docs.cast.ai/docs/kvisor
42+
install_security_agent = true
43+
44+
# Kvisor configuration examples, enable certain features:
45+
kvisor_values = [
46+
yamlencode({
47+
controller = {
48+
extraArgs = {
49+
# UI: Vulnerability management configuration = API: IMAGE_SCANNING
50+
"image-scan-enabled" = true
51+
# UI: Compliance configuration = API: CONFIGURATION_SCANNING
52+
"kube-bench-enabled" = true
53+
"kube-linter-enabled" = true
54+
}
55+
}
56+
57+
# UI: Runtime Security = API: RUNTIME_SECURITY
58+
agent = {
59+
# In order to enable Runtime security set agent.enabled to true.
60+
# This will install Kvisor agent (k8s: daemonset)
61+
# https://docs.cast.ai/docs/sec-runtime-security
62+
"enabled" = true
63+
64+
extraArgs = {
65+
# Runtime security configuration examples:
66+
# By default, most users enable the eBPF events and file hash enricher.
67+
# For all flag explanations and code, see: https://github.com/castai/kvisor/blob/main/cmd/agent/daemon/daemon.go
68+
"ebpf-events-enabled" = true
69+
"file-hash-enricher-enabled" = true
70+
# other examples
71+
"netflow-enabled" = false
72+
"netflow-export-interval" = "30s"
73+
"ebpf-program-metrics-enabled" = false
74+
"prom-metrics-export-enabled" = false
75+
"prom-metrics-export-interval" = "30s"
76+
"process-tree-enabled" = false
77+
}
78+
}
79+
})
80+
]
81+
82+
# Deprecated, leave this empty, to prevent setting defaults.
83+
kvisor_controller_extra_args = {}
84+
85+
# Everything else...
86+
87+
wait_for_cluster_ready = false
88+
89+
install_egressd = false
90+
install_workload_autoscaler = false
91+
install_pod_mutator = false
92+
delete_nodes_on_disconnect = false
93+
94+
api_url = var.castai_api_url
95+
castai_api_token = var.castai_api_token
96+
grpc_url = var.castai_grpc_url
97+
98+
aws_account_id = data.aws_caller_identity.current.account_id
99+
aws_cluster_region = var.cluster_region
100+
aws_cluster_name = var.cluster_name
101+
102+
aws_assume_role_arn = module.castai-eks-role-iam.role_arn
103+
104+
default_node_configuration = module.castai-eks-cluster.castai_node_configurations["default"]
105+
node_configurations = {
106+
default = {
107+
subnets = module.vpc.private_subnets
108+
tags = {}
109+
security_groups = [
110+
module.eks.cluster_security_group_id,
111+
module.eks.node_security_group_id,
112+
]
113+
instance_profile_arn = module.castai-eks-role-iam.instance_profile_arn
114+
}
115+
}
116+
117+
node_templates = {
118+
default_by_castai = {
119+
name = "default-by-castai"
120+
configuration_id = module.castai-eks-cluster.castai_node_configurations["default"]
121+
is_default = true
122+
is_enabled = true
123+
should_taint = false
124+
125+
constraints = {
126+
on_demand = true
127+
spot = false
128+
use_spot_fallbacks = false
129+
130+
enable_spot_diversity = false
131+
spot_diversity_price_increase_limit_percent = 20
132+
133+
spot_interruption_predictions_enabled = false
134+
spot_interruption_predictions_type = "aws-rebalance-recommendations"
135+
}
136+
}
137+
}
138+
139+
# module "castai-eks-cluster" has to be destroyed before module "castai-eks-role-iam".
140+
depends_on = [module.castai-eks-role-iam, module.eks, module.vpc]
141+
}
142+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# 2. Create EKS cluster.
2+
3+
module "eks" {
4+
source = "terraform-aws-modules/eks/aws"
5+
version = "19.4.2"
6+
putin_khuylo = true
7+
8+
cluster_name = var.cluster_name
9+
cluster_version = var.cluster_version
10+
cluster_endpoint_public_access = true
11+
12+
cluster_addons = {
13+
coredns = {
14+
most_recent = true
15+
}
16+
kube-proxy = {
17+
most_recent = true
18+
}
19+
vpc-cni = {
20+
most_recent = true
21+
}
22+
}
23+
24+
vpc_id = module.vpc.vpc_id
25+
subnet_ids = module.vpc.private_subnets
26+
27+
eks_managed_node_groups = {
28+
node_group_1 = {
29+
name = "${var.cluster_name}-ng-1"
30+
instance_types = ["m5.large", "m5.xlarge", "t3.large"]
31+
desired_size = 2
32+
subnets = module.vpc.private_subnets
33+
}
34+
}
35+
36+
manage_aws_auth_configmap = true
37+
38+
aws_auth_roles = [
39+
# Add the CAST AI IAM role which required for CAST AI nodes to join the cluster.
40+
{
41+
rolearn = module.castai-eks-role-iam.instance_profile_role_arn
42+
username = "system:node:{{EC2PrivateDNSName}}"
43+
groups = [
44+
"system:bootstrappers",
45+
"system:nodes",
46+
]
47+
}
48+
]
49+
50+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
resource "aws_security_group" "cast_ai_vpc_service" {
2+
name = "SG used by NGINX proxy VMs"
3+
vpc_id = module.vpc.vpc_id
4+
5+
ingress {
6+
description = "Accessing CAST AI endpoints"
7+
from_port = 443
8+
to_port = 443
9+
protocol = "tcp"
10+
cidr_blocks = ["0.0.0.0/0"]
11+
ipv6_cidr_blocks = ["::/0"]
12+
}
13+
14+
depends_on = [
15+
module.vpc
16+
]
17+
}
18+
19+
locals {
20+
interface_endpoints = [
21+
"ecr.api",
22+
"ecr.dkr",
23+
"logs",
24+
"sts"
25+
]
26+
}
27+
28+
resource "aws_vpc_endpoint" "interface_endpoints" {
29+
for_each = toset(local.interface_endpoints)
30+
31+
vpc_id = module.vpc.vpc_id
32+
service_name = "com.amazonaws.${var.cluster_region}.${each.key}"
33+
vpc_endpoint_type = "Interface"
34+
subnet_ids = module.vpc.private_subnets
35+
private_dns_enabled = true
36+
security_group_ids = [aws_security_group.vpce_sg.id]
37+
}
38+
39+
resource "aws_vpc_endpoint" "s3" {
40+
vpc_id = module.vpc.vpc_id
41+
service_name = "com.amazonaws.${var.cluster_region}.s3"
42+
route_table_ids = module.vpc.private_route_table_ids
43+
}
44+
45+
resource "aws_security_group" "vpce_sg" {
46+
name = "vpc-endpoints-sg"
47+
description = "Allow access to VPC interface endpoints"
48+
vpc_id = module.vpc.vpc_id
49+
50+
ingress {
51+
from_port = 443
52+
to_port = 443
53+
protocol = "tcp"
54+
cidr_blocks = [module.vpc.vpc_cidr_block]
55+
}
56+
57+
egress {
58+
from_port = 0
59+
to_port = 0
60+
protocol = "-1"
61+
cidr_blocks = ["0.0.0.0/0"]
62+
}
63+
}
64+
65+
resource "aws_vpc_endpoint" "cast_ai_rest_api" {
66+
vpc_id = module.vpc.vpc_id
67+
service_name = var.rest_api_service_name
68+
vpc_endpoint_type = "Interface"
69+
subnet_ids = module.vpc.private_subnets
70+
security_group_ids = [aws_security_group.cast_ai_vpc_service.id]
71+
private_dns_enabled = true
72+
73+
depends_on = [
74+
module.vpc
75+
]
76+
}
77+
78+
resource "aws_vpc_endpoint" "cast_ai_grpc" {
79+
vpc_id = module.vpc.vpc_id
80+
service_name = var.grpc_service_name
81+
vpc_endpoint_type = "Interface"
82+
subnet_ids = module.vpc.private_subnets
83+
security_group_ids = [aws_security_group.cast_ai_vpc_service.id]
84+
private_dns_enabled = true
85+
86+
depends_on = [
87+
module.vpc
88+
]
89+
}
90+
91+
resource "aws_vpc_endpoint" "cast_ai_api_grpc" {
92+
vpc_id = module.vpc.vpc_id
93+
service_name = var.api_grpc_service_name
94+
vpc_endpoint_type = "Interface"
95+
subnet_ids = module.vpc.private_subnets
96+
security_group_ids = [aws_security_group.cast_ai_vpc_service.id]
97+
private_dns_enabled = true
98+
99+
depends_on = [
100+
module.vpc
101+
]
102+
}
103+
104+
resource "aws_vpc_endpoint" "cast_ai_files" {
105+
vpc_id = module.vpc.vpc_id
106+
service_name = var.files_service_name
107+
vpc_endpoint_type = "Interface"
108+
subnet_ids = module.vpc.private_subnets
109+
security_group_ids = [aws_security_group.cast_ai_vpc_service.id]
110+
private_dns_enabled = true
111+
112+
depends_on = [
113+
module.vpc
114+
]
115+
}
116+
117+
resource "aws_vpc_endpoint" "cast_ai_kvisor" {
118+
vpc_id = module.vpc.vpc_id
119+
service_name = var.kvisor_service_name
120+
vpc_endpoint_type = "Interface"
121+
subnet_ids = module.vpc.private_subnets
122+
security_group_ids = [aws_security_group.cast_ai_vpc_service.id]
123+
private_dns_enabled = true
124+
125+
depends_on = [
126+
module.vpc
127+
]
128+
}
129+
130+
resource "aws_vpc_endpoint" "cast_ai_telemetry" {
131+
vpc_id = module.vpc.vpc_id
132+
service_name = var.telemetry_service_name
133+
vpc_endpoint_type = "Interface"
134+
subnet_ids = module.vpc.private_subnets
135+
security_group_ids = [aws_security_group.cast_ai_vpc_service.id]
136+
private_dns_enabled = true
137+
138+
depends_on = [
139+
module.vpc
140+
]
141+
}
142+
143+

0 commit comments

Comments
 (0)