--- AWSTemplateFormatVersion: '2010-09-09' Description: 'Amazon EKS - Node Group - Released 2018-08-30 with addition for Spot' Metadata: Author: Description: Madhuri Peri Shawn OConnor License: Description: 'Copyright 2017 Amazon.com, Inc. and its affiliates. All Rights Reserved. Licensed under the Amazon Software License (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/asl/ or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.' Parameters: KeyName: Description: The EC2 Key Pair to allow SSH access to the instances Type: AWS::EC2::KeyPair::KeyName NodeImageId: Type: AWS::EC2::Image::Id Description: Find the latest AMI id here - https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html NodeInstanceRole: Description: Use the Role associated with existing EKS Worker Nodes Type: String SpotPrice: Description: Spot Price (Only Spot market price is charged, up to max of On-Demand price. Value here is only used to prevent EC2 instance launch if Spot market price exceeds this value.) Type: String Default: 1 SpotNode1InstanceType: Description: EC2 instance type for the spot instances. Type: String Default: m4.large AllowedValues: - t2.small - t2.medium - t2.large - t2.xlarge - t2.2xlarge - m3.medium - m3.large - m3.xlarge - m3.2xlarge - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge - m5.12xlarge - m5.24xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - c5.large - c5.xlarge - c5.2xlarge - c5.4xlarge - c5.9xlarge - c5.18xlarge - i3.large - i3.xlarge - i3.2xlarge - i3.4xlarge - i3.8xlarge - i3.16xlarge - r3.xlarge - r3.2xlarge - r3.4xlarge - r3.8xlarge - r4.large - r4.xlarge - r4.2xlarge - r4.4xlarge - r4.8xlarge - r4.16xlarge - x1.16xlarge - x1.32xlarge - p2.xlarge - p2.8xlarge - p2.16xlarge - p3.2xlarge - p3.8xlarge - p3.16xlarge ConstraintDescription: Must be a valid EC2 instance type SpotNode2InstanceType: Description: EC2 instance type for the spot instances. Type: String Default: t2.medium AllowedValues: - t2.small - t2.medium - t2.large - t2.xlarge - t2.2xlarge - m3.medium - m3.large - m3.xlarge - m3.2xlarge - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge - m5.12xlarge - m5.24xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - c5.large - c5.xlarge - c5.2xlarge - c5.4xlarge - c5.9xlarge - c5.18xlarge - i3.large - i3.xlarge - i3.2xlarge - i3.4xlarge - i3.8xlarge - i3.16xlarge - r3.xlarge - r3.2xlarge - r3.4xlarge - r3.8xlarge - r4.large - r4.xlarge - r4.2xlarge - r4.4xlarge - r4.8xlarge - r4.16xlarge - x1.16xlarge - x1.32xlarge - p2.xlarge - p2.8xlarge - p2.16xlarge - p3.2xlarge - p3.8xlarge - p3.16xlarge ConstraintDescription: Must be a valid EC2 instance type OnDemandNodeInstanceType: Description: EC2 instance type for the node instances. Type: String Default: m4.large AllowedValues: - t2.small - t2.medium - t2.large - t2.xlarge - t2.2xlarge - m3.medium - m3.large - m3.xlarge - m3.2xlarge - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge - m5.12xlarge - m5.24xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - c5.large - c5.xlarge - c5.2xlarge - c5.4xlarge - c5.9xlarge - c5.18xlarge - i3.large - i3.xlarge - i3.2xlarge - i3.4xlarge - i3.8xlarge - i3.16xlarge - r3.xlarge - r3.2xlarge - r3.4xlarge - r3.8xlarge - r4.large - r4.xlarge - r4.2xlarge - r4.4xlarge - r4.8xlarge - r4.16xlarge - x1.16xlarge - x1.32xlarge - p2.xlarge - p2.8xlarge - p2.16xlarge - p3.2xlarge - p3.8xlarge - p3.16xlarge ConstraintDescription: Must be a valid EC2 instance type NodeAutoScalingGroupMinSize: Type: Number Description: Minimum size of Node Group ASG. Default: 1 NodeAutoScalingGroupMaxSize: Type: Number Description: Maximum size of Node Group ASG. Default: 8 NodeVolumeSize: Type: Number Description: Node volume size Default: 20 ClusterName: Description: The cluster name provided when the cluster was created. If it is incorrect, nodes will not be able to join the cluster. Type: String Default: 'eksworkshop-eksctl' SpotBootstrapArguments: Description: Sets Node Labels to set lifecycle as Ec2Spot Type: String OnDemandBootstrapArguments: Description: Sets Node Labels to set lifecycle as OnDemand Type: String SpotNode1GroupName: Description: Unique identifier for the first Spot Node Group. Type: String Default: 'SpotNodeGroup1' SpotNode2GroupName: Description: Unique identifier for the second Spot Node Group. Type: String Default: 'SpotNodeGroup2' OnDemandNodeGroupName: Description: Unique identifier for the OnDemand Node Group. Type: String Default: 'OnDemandNodeGroup' ClusterControlPlaneSecurityGroup: Description: The security group of the cluster control plane. Type: AWS::EC2::SecurityGroup::Id VpcId: Description: The VPC of the worker instances Type: AWS::EC2::VPC::Id Subnets: Description: The subnets where workers can be created. Type: List Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "EKS Cluster" Parameters: - ClusterName - ClusterControlPlaneSecurityGroup - Label: default: "Spot Worker 1 Node Configuration" Parameters: - SpotNode1GroupName - SpotNode1InstanceType - NodeAutoScalingGroupMinSize - NodeAutoScalingGroupMaxSize - NodeImageId - NodeInstanceRole - NodeVolumeSize - KeyName - BootstrapArguments - Label: default: "Spot Worker 2 Node Configuration" Parameters: - SpotNode2GroupName - SpotNode2InstanceType - NodeAutoScalingGroupMinSize - NodeAutoScalingGroupMaxSize - NodeImageId - NodeInstanceRole - NodeVolumeSize - KeyName - BootstrapArguments - Label: default: "OnDemand Worker Node Configuration" Parameters: - OnDemandNodeGroupName - OnDemandNodeInstanceType - NodeAutoScalingGroupMinSize - NodeAutoScalingGroupMaxSize - NodeImageId - NodeInstanceRole - NodeVolumeSize - KeyName - BootstrapArguments - Label: default: "Worker Network Configuration" Parameters: - VpcId - Subnets Resources: NodeInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: "/" Roles: - !Ref NodeInstanceRole NodeSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for all nodes in the cluster VpcId: !Ref VpcId Tags: - Key: !Sub "kubernetes.io/cluster/${ClusterName}" Value: 'owned' NodeSecurityGroupIngress: Type: AWS::EC2::SecurityGroupIngress DependsOn: NodeSecurityGroup Properties: Description: Allow node to communicate with each other GroupId: !Ref NodeSecurityGroup SourceSecurityGroupId: !Ref NodeSecurityGroup IpProtocol: '-1' FromPort: 0 ToPort: 65535 NodeSecurityGroupFromControlPlaneIngress: Type: AWS::EC2::SecurityGroupIngress DependsOn: NodeSecurityGroup Properties: Description: Allow worker Kubelets and pods to receive communication from the cluster control plane GroupId: !Ref NodeSecurityGroup SourceSecurityGroupId: !Ref ClusterControlPlaneSecurityGroup IpProtocol: tcp FromPort: 1025 ToPort: 65535 AllowHTTPSFromControlPlaneIngress: Type: AWS::EC2::SecurityGroupIngress DependsOn: NodeSecurityGroup Properties: Description: Allow worker Kubelets and pods to receive HTTPS communication from the cluster control plane GroupId: !Ref NodeSecurityGroup SourceSecurityGroupId: !Ref ClusterControlPlaneSecurityGroup IpProtocol: tcp FromPort: 443 ToPort: 443 ControlPlaneEgressToNodeSecurityGroup: Type: AWS::EC2::SecurityGroupEgress DependsOn: NodeSecurityGroup Properties: Description: Allow the cluster control plane to communicate with worker Kubelet and pods GroupId: !Ref ClusterControlPlaneSecurityGroup DestinationSecurityGroupId: !Ref NodeSecurityGroup IpProtocol: tcp FromPort: 1025 ToPort: 65535 ControlPlaneEgressToNodeSecurityGroupOn443: Type: AWS::EC2::SecurityGroupEgress DependsOn: NodeSecurityGroup Properties: Description: Allow the cluster control plane to communicate with pods running extension API servers on port 443 GroupId: !Ref ClusterControlPlaneSecurityGroup DestinationSecurityGroupId: !Ref NodeSecurityGroup IpProtocol: tcp FromPort: 443 ToPort: 443 ClusterControlPlaneSecurityGroupIngress: Type: AWS::EC2::SecurityGroupIngress DependsOn: NodeSecurityGroup Properties: Description: Allow pods to communicate with the cluster API Server GroupId: !Ref ClusterControlPlaneSecurityGroup SourceSecurityGroupId: !Ref NodeSecurityGroup IpProtocol: tcp ToPort: 443 FromPort: 443 SpotNode1Group: Type: AWS::AutoScaling::AutoScalingGroup Properties: DesiredCapacity: !Ref NodeAutoScalingGroupMinSize LaunchConfigurationName: !Ref SpotNode1LaunchConfig MinSize: !Ref NodeAutoScalingGroupMinSize MaxSize: !Ref NodeAutoScalingGroupMaxSize VPCZoneIdentifier: !Ref Subnets Tags: - Key: Name Value: !Sub "${ClusterName}-${SpotNode1GroupName}-Node" PropagateAtLaunch: 'true' - Key: !Sub 'kubernetes.io/cluster/${ClusterName}' Value: 'owned' PropagateAtLaunch: 'true' - Key: Spot Value: 'true' PropagateAtLaunch: 'true' UpdatePolicy: AutoScalingRollingUpdate: MinInstancesInService: '1' MaxBatchSize: '1' SpotNode2Group: Type: AWS::AutoScaling::AutoScalingGroup Properties: DesiredCapacity: !Ref NodeAutoScalingGroupMinSize LaunchConfigurationName: !Ref SpotNode2LaunchConfig MinSize: !Ref NodeAutoScalingGroupMinSize MaxSize: !Ref NodeAutoScalingGroupMaxSize VPCZoneIdentifier: !Ref Subnets Tags: - Key: Name Value: !Sub "${ClusterName}-${SpotNode2GroupName}-Node" PropagateAtLaunch: 'true' - Key: !Sub 'kubernetes.io/cluster/${ClusterName}' Value: 'owned' PropagateAtLaunch: 'true' - Key: Spot Value: 'true' PropagateAtLaunch: 'true' UpdatePolicy: AutoScalingRollingUpdate: MinInstancesInService: '1' MaxBatchSize: '1' OnDemandNodeGroup: Type: AWS::AutoScaling::AutoScalingGroup Properties: DesiredCapacity: !Ref NodeAutoScalingGroupMinSize LaunchConfigurationName: !Ref OnDemandNodeLaunchConfig MinSize: !Ref NodeAutoScalingGroupMinSize MaxSize: !Ref NodeAutoScalingGroupMaxSize VPCZoneIdentifier: !Ref Subnets Tags: - Key: Name Value: !Sub "${ClusterName}-${OnDemandNodeGroupName}-Node" PropagateAtLaunch: 'true' - Key: !Sub 'kubernetes.io/cluster/${ClusterName}' Value: 'owned' PropagateAtLaunch: 'true' - Key: Spot Value: 'false' PropagateAtLaunch: 'true' UpdatePolicy: AutoScalingRollingUpdate: MinInstancesInService: '1' MaxBatchSize: '1' SpotNode1LaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration Properties: AssociatePublicIpAddress: 'true' IamInstanceProfile: !Ref NodeInstanceProfile ImageId: !Ref NodeImageId InstanceType: !Ref SpotNode1InstanceType KeyName: !Ref KeyName SpotPrice: !Ref SpotPrice SecurityGroups: - !Ref NodeSecurityGroup BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: !Ref NodeVolumeSize VolumeType: gp2 DeleteOnTermination: true UserData: Fn::Base64: !Sub | #!/bin/bash set -o xtrace /etc/eks/bootstrap.sh ${ClusterName} ${SpotBootstrapArguments} /opt/aws/bin/cfn-signal --exit-code $? \ --stack ${AWS::StackName} \ --resource SpotNode1Group \ --region ${AWS::Region} SpotNode2LaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration Properties: AssociatePublicIpAddress: 'true' IamInstanceProfile: !Ref NodeInstanceProfile ImageId: !Ref NodeImageId InstanceType: !Ref SpotNode2InstanceType KeyName: !Ref KeyName SpotPrice: !Ref SpotPrice SecurityGroups: - !Ref NodeSecurityGroup BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: !Ref NodeVolumeSize VolumeType: gp2 DeleteOnTermination: true UserData: Fn::Base64: !Sub | #!/bin/bash set -o xtrace /etc/eks/bootstrap.sh ${ClusterName} ${SpotBootstrapArguments} /opt/aws/bin/cfn-signal --exit-code $? \ --stack ${AWS::StackName} \ --resource SpotNode2Group \ --region ${AWS::Region} OnDemandNodeLaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration Properties: AssociatePublicIpAddress: 'true' IamInstanceProfile: !Ref NodeInstanceProfile ImageId: !Ref NodeImageId InstanceType: !Ref OnDemandNodeInstanceType KeyName: !Ref KeyName SecurityGroups: - !Ref NodeSecurityGroup BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: !Ref NodeVolumeSize VolumeType: gp2 DeleteOnTermination: true UserData: Fn::Base64: !Sub | #!/bin/bash set -o xtrace /etc/eks/bootstrap.sh ${ClusterName} ${OnDemandBootstrapArguments} /opt/aws/bin/cfn-signal --exit-code $? \ --stack ${AWS::StackName} \ --resource OnDemandNodeGroup \ --region ${AWS::Region}