AWSTemplateFormatVersion: "2010-09-09" Description: Resources used by https://github.com/aws/karpenter Parameters: ClusterName: Type: String Description: "EKS cluster name" Resources: KarpenterNodeInstanceProfile: Type: "AWS::IAM::InstanceProfile" Properties: InstanceProfileName: !Sub "KarpenterNodeInstanceProfile-${ClusterName}" Path: "/" Roles: - Ref: "KarpenterNodeRole" KarpenterNodeRole: Type: "AWS::IAM::Role" Properties: RoleName: !Sub "KarpenterNodeRole-${ClusterName}" Path: / AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: !Sub "ec2.${AWS::URLSuffix}" Action: - "sts:AssumeRole" ManagedPolicyArns: - !Sub "arn:${AWS::Partition}:iam::aws:policy/AmazonEKS_CNI_Policy" - !Sub "arn:${AWS::Partition}:iam::aws:policy/AmazonEKSWorkerNodePolicy" - !Sub "arn:${AWS::Partition}:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" - !Sub "arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore" KarpenterControllerPolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: !Sub "KarpenterControllerPolicy-${ClusterName}" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Resource: "*" Action: # Write Operations - ec2:CreateFleet - ec2:CreateLaunchTemplate - ec2:CreateTags - ec2:DeleteLaunchTemplate - ec2:RunInstances - ec2:TerminateInstances # Read Operations - ec2:DescribeAvailabilityZones - ec2:DescribeImages - ec2:DescribeInstances - ec2:DescribeInstanceTypeOfferings - ec2:DescribeInstanceTypes - ec2:DescribeLaunchTemplates - ec2:DescribeSecurityGroups - ec2:DescribeSpotPriceHistory - ec2:DescribeSubnets - pricing:GetProducts - ssm:GetParameter - Effect: Allow Action: # Write Operations - sqs:DeleteMessage # Read Operations - sqs:GetQueueAttributes - sqs:GetQueueUrl - sqs:ReceiveMessage Resource: !GetAtt KarpenterInterruptionQueue.Arn - Effect: Allow Action: - iam:PassRole Resource: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/KarpenterNodeRole-${ClusterName}" - Effect: Allow Action: - eks:DescribeCluster Resource: !Sub "arn:${AWS::Partition}:eks:${AWS::Region}:${AWS::AccountId}:cluster/${ClusterName}" KarpenterInterruptionQueue: Type: AWS::SQS::Queue Properties: QueueName: !Sub "${ClusterName}" MessageRetentionPeriod: 300 KarpenterInterruptionQueuePolicy: Type: AWS::SQS::QueuePolicy Properties: Queues: - !Ref KarpenterInterruptionQueue PolicyDocument: Id: EC2InterruptionPolicy Statement: - Effect: Allow Principal: Service: - events.amazonaws.com - sqs.amazonaws.com Action: sqs:SendMessage Resource: !GetAtt KarpenterInterruptionQueue.Arn ScheduledChangeRule: Type: 'AWS::Events::Rule' Properties: EventPattern: source: - aws.health detail-type: - AWS Health Event Targets: - Id: KarpenterInterruptionQueueTarget Arn: !GetAtt KarpenterInterruptionQueue.Arn SpotInterruptionRule: Type: 'AWS::Events::Rule' Properties: EventPattern: source: - aws.ec2 detail-type: - EC2 Spot Instance Interruption Warning Targets: - Id: KarpenterInterruptionQueueTarget Arn: !GetAtt KarpenterInterruptionQueue.Arn RebalanceRule: Type: 'AWS::Events::Rule' Properties: EventPattern: source: - aws.ec2 detail-type: - EC2 Instance Rebalance Recommendation Targets: - Id: KarpenterInterruptionQueueTarget Arn: !GetAtt KarpenterInterruptionQueue.Arn InstanceStateChangeRule: Type: 'AWS::Events::Rule' Properties: EventPattern: source: - aws.ec2 detail-type: - EC2 Instance State-change Notification Targets: - Id: KarpenterInterruptionQueueTarget Arn: !GetAtt KarpenterInterruptionQueue.Arn