Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AWS EKS Karpenter Terraform support #317

Closed
wants to merge 71 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
9387d66
Add auto scaler and karpenter support
sumanthreddy29 Sep 9, 2024
4a71f48
update
sumanthreddy29 Sep 9, 2024
b3e49cf
update azure module
sumanthreddy29 Sep 10, 2024
4ec1b1b
update tfvars
sumanthreddy29 Sep 10, 2024
d5a4013
update format
sumanthreddy29 Sep 10, 2024
1b5a781
update tfvars
sumanthreddy29 Sep 10, 2024
8656934
update aws eks
sumanthreddy29 Sep 10, 2024
5ef9e30
update aws tfvars
sumanthreddy29 Sep 11, 2024
d4ec7e4
update aws module
sumanthreddy29 Sep 11, 2024
223771d
update aws nap
sumanthreddy29 Sep 12, 2024
d572c93
Merge branch 'main' of https://github.com/Azure/telescope into sumant…
sumanthreddy29 Sep 12, 2024
249c4af
AWS NAP test scenario.
sumanthreddy29 Sep 13, 2024
ae2dcb6
revert azure changes
sumanthreddy29 Sep 13, 2024
261e629
remove unused changes
sumanthreddy29 Sep 13, 2024
0c9a061
remove deployment file
sumanthreddy29 Sep 13, 2024
99c47af
AWS NAP support
sumanthreddy29 Sep 13, 2024
fe3925e
update aws nap test scenario
sumanthreddy29 Sep 14, 2024
f828556
update aws tfvars
sumanthreddy29 Sep 14, 2024
44ea788
fix format
sumanthreddy29 Sep 14, 2024
62360ac
update
sumanthreddy29 Sep 14, 2024
77748e9
update eks module
sumanthreddy29 Sep 14, 2024
596d7f8
Merge remote-tracking branch 'origin/main' into sumanth-Aws-nap
sumanthreddy29 Sep 19, 2024
f81bb6b
eks karpenter module
sumanthreddy29 Oct 1, 2024
c7a5af2
update arg with quotes
sumanthreddy29 Oct 1, 2024
46ad28f
update input varibles
sumanthreddy29 Oct 1, 2024
f4e29d7
update
sumanthreddy29 Oct 1, 2024
e840c76
update version
sumanthreddy29 Oct 1, 2024
8d9a311
reduce length of role name
sumanthreddy29 Oct 1, 2024
3e00178
reduce length of role name
sumanthreddy29 Oct 1, 2024
b06dcb0
update fmt
sumanthreddy29 Oct 1, 2024
d0df831
fix format
sumanthreddy29 Oct 1, 2024
6619323
revert unused changes
sumanthreddy29 Oct 1, 2024
48f2a43
update eks addon
sumanthreddy29 Oct 1, 2024
02c7f82
Merge branch 'main' of https://github.com/Azure/telescope into sumant…
sumanthreddy29 Oct 1, 2024
bd5f36c
update deletion time
sumanthreddy29 Oct 1, 2024
fde8b47
update helm uninstall
sumanthreddy29 Oct 1, 2024
a5f30ee
update
sumanthreddy29 Oct 1, 2024
086435c
fix lint errors
sumanthreddy29 Oct 1, 2024
1c0fc6d
optional string
sumanthreddy29 Oct 1, 2024
aac9114
update node count
sumanthreddy29 Oct 1, 2024
24246ae
fix format
sumanthreddy29 Oct 1, 2024
f602461
fix format
sumanthreddy29 Oct 1, 2024
ebf0a6c
update helm install
sumanthreddy29 Oct 2, 2024
e9b226e
update readme
sumanthreddy29 Oct 2, 2024
ea1328d
revert pipeline version
sumanthreddy29 Oct 2, 2024
2b5790a
update eks module
sumanthreddy29 Oct 2, 2024
386c316
update eks addon module
sumanthreddy29 Oct 2, 2024
4fd5498
test pipeline
sumanthreddy29 Oct 2, 2024
68d87cf
update cron schedule
sumanthreddy29 Oct 2, 2024
a2b575d
update cleanup steps
sumanthreddy29 Oct 2, 2024
c30c600
update script
sumanthreddy29 Oct 2, 2024
99748d1
test
sumanthreddy29 Oct 2, 2024
4563a07
Merge branch 'main' of https://github.com/Azure/telescope into sumant…
sumanthreddy29 Oct 2, 2024
4fada4c
add tags
sumanthreddy29 Oct 2, 2024
2a6de5e
update name
sumanthreddy29 Oct 2, 2024
34cb93a
delete unused file
sumanthreddy29 Oct 2, 2024
670b632
update
sumanthreddy29 Oct 2, 2024
0802485
update addons
sumanthreddy29 Oct 2, 2024
96c1cea
update terraform for karpenter
sumanthreddy29 Oct 3, 2024
9977e15
update service account syntax
sumanthreddy29 Oct 3, 2024
01abfbf
update syntax
sumanthreddy29 Oct 3, 2024
a36ed1a
update command
sumanthreddy29 Oct 3, 2024
0a6a31d
update
sumanthreddy29 Oct 3, 2024
5ca3cb5
update subnet range
sumanthreddy29 Oct 3, 2024
5022ff5
update karpenter module
sumanthreddy29 Oct 3, 2024
bc44aaf
update dependencies
sumanthreddy29 Oct 3, 2024
50a65dd
remove unused var
sumanthreddy29 Oct 3, 2024
b14c7d4
fix lint errors
sumanthreddy29 Oct 3, 2024
49fbf54
Merge branch 'main' of https://github.com/Azure/telescope into sumant…
sumanthreddy29 Oct 3, 2024
8873bfd
manage dependencies
sumanthreddy29 Oct 3, 2024
1965f80
fix lint
sumanthreddy29 Oct 3, 2024
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
9 changes: 7 additions & 2 deletions modules/terraform/aws/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ This guide covers how to manually run Terraform for AWS. All commands should be
* Install [Terraform - 1.7.3](https://developer.hashicorp.com/terraform/tutorials/azure-get-started/install-cli)
* Install [AWS CLI - 2.15.19](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html)
* Install [jq - 1.6-2.1ubuntu3](https://stedolan.github.io/jq/download/)
* Install [ Kubectl - 1.31.0](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/)
* Install [Helm - v3.16.1](https://helm.sh/docs/intro/install/)

## Define Variables

Expand All @@ -15,10 +17,11 @@ Set environment variables for a specific test scenario. In this guide, we'll use
Run the following commands from the root of the repository:
```bash
SCENARIO_TYPE=perf-eval
SCENARIO_NAME=apiserver-vn10pod100
SCENARIO_NAME=nap-c4n10p100
RUN_ID=$(date +%s)
CLOUD=aws
REGION="us-east-2"
TERRAFORM_USER_DATA_PATH=$(pwd)/scenarios/$SCENARIO_TYPE/$SCENARIO_NAME/scripts/user_data
TERRAFORM_MODULES_DIR=$(pwd)/modules/terraform/$CLOUD
TERRAFORM_INPUT_FILE=$(pwd)/scenarios/$SCENARIO_TYPE/$SCENARIO_NAME/terraform-inputs/${CLOUD}.tfvars
```
Expand Down Expand Up @@ -48,9 +51,11 @@ Set `INPUT_JSON` variable. This variable is not exhaustive and may vary dependin
INPUT_JSON=$(jq -n \
--arg run_id $RUN_ID \
--arg region $REGION \
--arg user_data_path "$TERRAFORM_USER_DATA_PATH" \
'{
run_id: $run_id,
region: $region
region: $region,
user_data_path : $user_data_path ,
}' | jq 'with_entries(select(.value != null and .value != ""))')
```
**Note**: The `jq` command will remove any null or empty values from the JSON object. So any variable surrounded by double quotes means it is optional and can be removed if not needed.
Expand Down
3 changes: 3 additions & 0 deletions modules/terraform/aws/aws_input_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
},
"region": {
"type": "string"
},
"user_data_path": {
"type": "string"
}
},
"required": [
Expand Down
338 changes: 338 additions & 0 deletions modules/terraform/aws/eks/karpenter/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,338 @@
locals {
karpenter_namespace = "kube-system"
karpenter_version = "1.0.3"
}

data "aws_caller_identity" "current" {}

data "aws_iam_role" "cluster_role" {
name = var.cluster_iam_role_name
}

resource "aws_iam_role" "karpenter_node_role" {
name = substr("KarpenterNodeRole-${var.cluster_name}", 0, 60)
tags = var.tags
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})

managed_policy_arns = [
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
"arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",
"arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
]
}

resource "aws_iam_policy" "karpenter_controller_policy" {
name = substr("KarpenterControllerPolicy-${var.cluster_name}", 0, 60)
tags = var.tags
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowScopedEC2InstanceAccessActions"
Effect = "Allow"
Resource = [
"arn:aws:ec2:${var.region}::image/*",
"arn:aws:ec2:${var.region}::snapshot/*",
"arn:aws:ec2:${var.region}:*:security-group/*",
"arn:aws:ec2:${var.region}:*:subnet/*"
]
Action = [
"ec2:RunInstances",
"ec2:CreateFleet"
]
},
{
Sid = "AllowScopedEC2LaunchTemplateAccessActions"
Effect = "Allow"
Resource = "arn:aws:ec2:${var.region}:*:launch-template/*"
Action = [
"ec2:RunInstances",
"ec2:CreateFleet"
]
Condition = {
"StringEquals" = {
"aws:ResourceTag/kubernetes.io/cluster/${var.cluster_name}" = "owned"
}
"StringLike" = {
"aws:ResourceTag/karpenter.sh/nodepool" = "*"
}
}
},
{
Sid = "AllowScopedEC2InstanceActionsWithTags"
Effect = "Allow"
Resource = [
"arn:aws:ec2:${var.region}:*:fleet/*",
"arn:aws:ec2:${var.region}:*:instance/*",
"arn:aws:ec2:${var.region}:*:volume/*",
"arn:aws:ec2:${var.region}:*:network-interface/*",
"arn:aws:ec2:${var.region}:*:launch-template/*",
]
Action = [
"ec2:RunInstances",
"ec2:CreateFleet",
"ec2:CreateLaunchTemplate"
]
Condition = {
"StringEquals" = {
"aws:RequestTag/kubernetes.io/cluster/${var.cluster_name}" = "owned",
"aws:RequestTag/eks:eks-cluster-name" = var.cluster_name
}
"StringLike" = {
"aws:RequestTag/karpenter.sh/nodepool" = "*"
}
}
},
{
Sid = "AllowScopedResourceCreationTagging"
Effect = "Allow"
Resource = [
"arn:aws:ec2:${var.region}:*:fleet/*",
"arn:aws:ec2:${var.region}:*:instance/*",
"arn:aws:ec2:${var.region}:*:volume/*",
"arn:aws:ec2:${var.region}:*:network-interface/*",
"arn:aws:ec2:${var.region}:*:launch-template/*",
]
Action = "ec2:CreateTags"
Condition = {
"StringEquals" = {
"aws:RequestTag/kubernetes.io/cluster/${var.cluster_name}" = "owned",
"aws:RequestTag/eks:eks-cluster-name" = var.cluster_name,
"ec2:CreateAction" = [
"RunInstances",
"CreateFleet",
"CreateLaunchTemplate"
]
}
"StringLike" = {
"aws:RequestTag/karpenter.sh/nodepool" = "*"
}
}
},
{
Sid = "AllowScopedResourceTagging"
Effect = "Allow"
Resource = "arn:aws:ec2:${var.region}:*:instance/*"
Action = "ec2:CreateTags"
Condition = {
"StringEquals" = {
"aws:ResourceTag/kubernetes.io/cluster/${var.cluster_name}" = "owned"
}
"StringLike" = {
"aws:ResourceTag/karpenter.sh/nodepool" = "*"
}
"StringEqualsIfExists" = {
"aws:RequestTag/eks:eks-cluster-name" = var.cluster_name
}
"ForAllValues:StringEquals" = {
"aws:TagKeys" = [
"eks:eks-cluster-name",
"karpenter.sh/nodeclaim",
"Name"
]
}
}
},
{
Sid = "AllowScopedDeletion"
Effect = "Allow"
Resource = [
"arn:aws:ec2:${var.region}:*:instance/*",
"arn:aws:ec2:${var.region}:*:launch-template/*"
]
Action = [
"ec2:TerminateInstances",
"ec2:DeleteLaunchTemplate"
]
Condition = {
"StringEquals" = {
"aws:ResourceTag/kubernetes.io/cluster/${var.cluster_name}" = "owned"
}
"StringLike" = {
"aws:ResourceTag/karpenter.sh/nodepool" = "*"
}
}
},
{
Sid = "AllowRegionalReadActions"
Effect = "Allow"
Resource = "*"
Action = [
"ec2:DescribeAvailabilityZones",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeInstanceTypeOfferings",
"ec2:DescribeInstanceTypes",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSpotPriceHistory",
"ec2:DescribeSubnets"
]
Condition = {
"StringEquals" = {
"aws:RequestedRegion" = var.region
}
}
},
{
Sid = "AllowSSMReadActions"
Effect = "Allow"
Resource = "arn:aws:ssm:${var.region}::parameter/aws/service/*"
Action = "ssm:GetParameter"
},
{
Sid = "AllowPricingReadActions"
Effect = "Allow"
Resource = "*"
Action = "pricing:GetProducts"
},
{
Sid = "AllowPassingInstanceRole"
Effect = "Allow"
Resource = [aws_iam_role.karpenter_node_role.arn, data.aws_iam_role.cluster_role.arn]
Action = "iam:PassRole"
Condition = {
"StringEquals" = {
"iam:PassedToService" = "ec2.amazonaws.com"
}
}
},
{
Sid = "AllowScopedInstanceProfileCreationActions"
Effect = "Allow"
Resource = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:instance-profile/*"
Action = [
"iam:CreateInstanceProfile"
]
Condition = {
"StringEquals" = {
"aws:RequestTag/kubernetes.io/cluster/${var.cluster_name}" = "owned",
"aws:RequestTag/eks:eks-cluster-name" = var.cluster_name,
"aws:RequestTag/topology.kubernetes.io/region" = var.region
}
"StringLike" = {
"aws:RequestTag/karpenter.k8s.aws/ec2nodeclass" = "*"
}
}
},
{
Sid = "AllowScopedInstanceProfileTagActions"
Effect = "Allow"
Resource = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:instance-profile/*"
Action = [
"iam:TagInstanceProfile"
]
Condition = {
"StringEquals" = {
"aws:ResourceTag/kubernetes.io/cluster/${var.cluster_name}" = "owned",
"aws:ResourceTag/topology.kubernetes.io/region" = var.region,
"aws:RequestTag/eks:eks-cluster-name" = var.cluster_name,
"aws:RequestTag/kubernetes.io/cluster/${var.cluster_name}" = "owned",
"aws:RequestTag/topology.kubernetes.io/region" = var.region
}
"StringLike" = {
"aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass" = "*"
}
}
},
{
Sid = "AllowScopedInstanceProfileActions"
Effect = "Allow"
Resource = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:instance-profile/*"
Action = [
"iam:AddRoleToInstanceProfile",
"iam:RemoveRoleFromInstanceProfile",
"iam:DeleteInstanceProfile"
]
Condition = {
"StringEquals" = {
"aws:ResourceTag/kubernetes.io/cluster/${var.cluster_name}" = "owned",
"aws:ResourceTag/topology.kubernetes.io/region" = var.region
}
"StringLike" = {
"aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass" = "*"
}
}
},
{
Sid = "AllowInstanceProfileReadActions"
Effect = "Allow"
Resource = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:instance-profile/*"
Action = [
"iam:GetInstanceProfile"
]
}, {
Sid = "AllowAPIServerEndpointDiscovery"
Effect = "Allow"
Resource = "arn:aws:eks:${var.region}:${data.aws_caller_identity.current.account_id}:cluster/${var.cluster_name}"
Action = "eks:DescribeCluster"
}
]
})
}

resource "aws_iam_role_policy_attachment" "karpenter_controller_policy_attachments" {
policy_arn = aws_iam_policy.karpenter_controller_policy.arn
role = var.cluster_iam_role_name
}

resource "terraform_data" "install_karpenter" {
provisioner "local-exec" {
command = <<EOT
#!/bin/bash
set -e
aws eks --region ${var.region} update-kubeconfig --name "${var.cluster_name}"
# Install Karpenter
helm registry logout public.ecr.aws || true
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter \
--version "${local.karpenter_version}" \
--namespace "${local.karpenter_namespace}" \
--set "settings.clusterName=${var.cluster_name}" \
--wait
sleep 10
envsubst < "${var.user_data_path}/NodeClass.yml" | kubectl apply -f -

EOT
environment = {
ROLE_NAME = substr("KarpenterNodeRole-${var.cluster_name}", 0, 60)
RUN_ID = var.run_id
}
}

provisioner "local-exec" {
when = destroy
command = <<EOT
#!/bin/bash
set -e
helm uninstall karpenter --namespace kube-system

EOT
}
}

resource "terraform_data" "update_aws_auth_config_map" {
provisioner "local-exec" {
command = <<EOT
#!/bin/bash
set -e
kubectl get configmaps -n kube-system aws-auth -o yaml
ROLE=" - groups:\n - system:bootstrappers\n - system:nodes\n rolearn: ${aws_iam_role.karpenter_node_role.arn}\n username: system:node:{{EC2PrivateDNSName}}"

kubectl get -n kube-system configmap/aws-auth -o yaml | awk "/mapRoles: \|/{print;print \"$ROLE\";next}1" > aws-auth-patch.yml
kubectl patch configmap/aws-auth -n kube-system --patch "$(cat aws-auth-patch.yml)"
kubectl get configmaps -n kube-system aws-auth -o yaml
EOT
}
}
Loading
Loading