@@ -52,8 +52,10 @@ data "aws_vpc" "vpc" {
5252 id = var. vpc_id
5353}
5454
55+ data "aws_caller_identity" "current" {}
56+
5557resource "aws_eks_cluster" "cluster" {
56- name = " ${ var . prefix } -cluster "
58+ name = local . cluster_name
5759 role_arn = aws_iam_role. cluster . arn
5860 vpc_config {
5961 subnet_ids = aws_subnet. public [* ]. id
@@ -166,11 +168,131 @@ resource "aws_iam_role_policy_attachment" "ecr" {
166168 policy_arn = " arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
167169}
168170
169- // See https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#iam-policy
170- resource "aws_iam_role_policy" "node" {
171- name = " ${ var . prefix } -node"
172- role = aws_iam_role. node . id
173- policy = << EOF
171+ variable "autoscaler_name" {
172+ type = string
173+ description = " The name of the autoscaler to use. Valid values are karpenter and cluster-autoscaler"
174+ default = " cluster-autoscaler"
175+ }
176+
177+ locals {
178+ cluster_name = " ${ var . prefix } -cluster"
179+ aws_account_id = data. aws_caller_identity . current . account_id
180+ node_policy_ka = << EOF
181+ {
182+ "Statement": [
183+ {
184+ "Action": [
185+ "ssm:GetParameter",
186+ "ec2:DescribeImages",
187+ "ec2:RunInstances",
188+ "ec2:DescribeSubnets",
189+ "ec2:DescribeSecurityGroups",
190+ "ec2:DescribeLaunchTemplates",
191+ "ec2:DescribeInstances",
192+ "ec2:DescribeInstanceTypes",
193+ "ec2:DescribeInstanceTypeOfferings",
194+ "ec2:DescribeAvailabilityZones",
195+ "ec2:DeleteLaunchTemplate",
196+ "ec2:CreateTags",
197+ "ec2:CreateLaunchTemplate",
198+ "ec2:CreateFleet",
199+ "ec2:DescribeSpotPriceHistory",
200+ "pricing:GetProducts"
201+ ],
202+ "Effect": "Allow",
203+ "Resource": "*",
204+ "Sid": "Karpenter"
205+ },
206+ {
207+ "Action": "ec2:TerminateInstances",
208+ "Condition": {
209+ "StringLike": {
210+ "ec2:ResourceTag/karpenter.sh/nodepool": "*"
211+ }
212+ },
213+ "Effect": "Allow",
214+ "Resource": "*",
215+ "Sid": "ConditionalEC2Termination"
216+ },
217+ {
218+ "Effect": "Allow",
219+ "Action": "iam:PassRole",
220+ "Resource": "arn:aws:iam::${ local . aws_account_id } :role/KarpenterNodeRole-${ local . cluster_name } ",
221+ "Sid": "PassNodeIAMRole"
222+ },
223+ {
224+ "Effect": "Allow",
225+ "Action": "eks:DescribeCluster",
226+ "Resource": "arn:aws:eks:${ var . region } :${ local . aws_account_id } :cluster/${ local . cluster_name } ",
227+ "Sid": "EKSClusterEndpointLookup"
228+ },
229+ {
230+ "Sid": "AllowScopedInstanceProfileCreationActions",
231+ "Effect": "Allow",
232+ "Resource": "*",
233+ "Action": [
234+ "iam:CreateInstanceProfile"
235+ ],
236+ "Condition": {
237+ "StringEquals": {
238+ "aws:RequestTag/kubernetes.io/cluster/${ local . cluster_name } ": "owned",
239+ "aws:RequestTag/topology.kubernetes.io/region": "${ var . region } "
240+ },
241+ "StringLike": {
242+ "aws:RequestTag/karpenter.k8s.aws/ec2nodeclass": "*"
243+ }
244+ }
245+ },
246+ {
247+ "Sid": "AllowScopedInstanceProfileTagActions",
248+ "Effect": "Allow",
249+ "Resource": "*",
250+ "Action": [
251+ "iam:TagInstanceProfile"
252+ ],
253+ "Condition": {
254+ "StringEquals": {
255+ "aws:ResourceTag/kubernetes.io/cluster/${ local . cluster_name } ": "owned",
256+ "aws:ResourceTag/topology.kubernetes.io/region": "${ var . region } ",
257+ "aws:RequestTag/kubernetes.io/cluster/${ local . cluster_name } ": "owned",
258+ "aws:RequestTag/topology.kubernetes.io/region": "${ var . region } "
259+ },
260+ "StringLike": {
261+ "aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass": "*",
262+ "aws:RequestTag/karpenter.k8s.aws/ec2nodeclass": "*"
263+ }
264+ }
265+ },
266+ {
267+ "Sid": "AllowScopedInstanceProfileActions",
268+ "Effect": "Allow",
269+ "Resource": "*",
270+ "Action": [
271+ "iam:AddRoleToInstanceProfile",
272+ "iam:RemoveRoleFromInstanceProfile",
273+ "iam:DeleteInstanceProfile"
274+ ],
275+ "Condition": {
276+ "StringEquals": {
277+ "aws:ResourceTag/kubernetes.io/cluster/${ local . cluster_name } ": "owned",
278+ "aws:ResourceTag/topology.kubernetes.io/region": "${ var . region } "
279+ },
280+ "StringLike": {
281+ "aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass": "*"
282+ }
283+ }
284+ },
285+ {
286+ "Sid": "AllowInstanceProfileReadActions",
287+ "Effect": "Allow",
288+ "Resource": "*",
289+ "Action": "iam:GetInstanceProfile"
290+ }
291+ ],
292+ "Version": "2012-10-17"
293+ }
294+ EOF
295+ node_policy_ca = << EOF
174296{
175297 "Statement": [
176298 {
@@ -201,6 +323,15 @@ resource "aws_iam_role_policy" "node" {
201323 "Version": "2012-10-17"
202324}
203325EOF
326+
327+ node_policy = var. autoscaler_name == " karpenter" ? local. node_policy_ka : local. node_policy_ca
328+ }
329+
330+ // See https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#iam-policy
331+ resource "aws_iam_role_policy" "node" {
332+ name = " ${ var . prefix } -node-ca"
333+ role = aws_iam_role. node . id
334+ policy = local. node_policy
204335}
205336
206337// Give nodes AmazonEKSWorkerNodePolicy
0 commit comments