--- AWSTemplateFormatVersion: "2010-09-09" Description: GitLab EKS Cluster Parameters: KubernetesVersion: Description: The Kubernetes version to install Type: String Default: "1.20" AllowedValues: - "1.16" - "1.17" - "1.18" - "1.19" - "1.20" KeyName: Description: The EC2 Key Pair to allow SSH access to the node instances Type: AWS::EC2::KeyPair::KeyName NodeImageIdSSMParam: Type: "AWS::SSM::Parameter::Value" Default: /aws/service/eks/optimized-ami/1.17/amazon-linux-2/recommended/image_id Description: AWS Systems Manager Parameter Store parameter of the AMI ID for the worker node instances. NodeInstanceType: Description: EC2 instance type for the node instances Type: String Default: t3.medium ConstraintDescription: Must be a valid EC2 instance type AllowedValues: - t2.small - t2.medium - t2.large - t2.xlarge - t2.2xlarge - t3.nano - t3.micro - t3.small - t3.medium - t3.large - t3.xlarge - t3.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 - p3dn.24xlarge - r5.large - r5.xlarge - r5.2xlarge - r5.4xlarge - r5.12xlarge - r5.24xlarge - r5d.large - r5d.xlarge - r5d.2xlarge - r5d.4xlarge - r5d.12xlarge - r5d.24xlarge - z1d.large - z1d.xlarge - z1d.2xlarge - z1d.3xlarge - z1d.6xlarge - z1d.12xlarge NodeAutoScalingGroupDesiredCapacity: Description: Desired capacity of Node Group ASG. Type: Number Default: 3 NodeVolumeSize: Description: Node volume size Type: Number Default: 20 ClusterName: Description: Unique name for your Amazon EKS cluster. Type: String ClusterRole: Description: The IAM Role to allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf. Type: String ClusterControlPlaneSecurityGroup: Description: The security groups to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets. Type: AWS::EC2::SecurityGroup::Id VpcId: Description: The VPC to use for your EKS Cluster resources. Type: AWS::EC2::VPC::Id Subnets: Description: The subnets in your VPC where your worker nodes will run. Type: List Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: EKS Cluster Parameters: - ClusterName - ClusterRole - KubernetesVersion - ClusterControlPlaneSecurityGroup - Label: default: Worker Node Configuration Parameters: - NodeAutoScalingGroupDesiredCapacity - NodeInstanceType - NodeImageIdSSMParam - NodeVolumeSize - KeyName - Label: default: Worker Network Configuration Parameters: - VpcId - Subnets Resources: Cluster: Type: AWS::EKS::Cluster Properties: Name: !Sub ${ClusterName} Version: !Sub ${KubernetesVersion} RoleArn: !Sub ${ClusterRole} ResourcesVpcConfig: SecurityGroupIds: - !Ref ClusterControlPlaneSecurityGroup SubnetIds: !Ref Subnets NodeInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: "/" Roles: - !Ref NodeInstanceRole NodeInstanceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: "/" ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 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 nodes 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 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 NodeSecurityGroupFromControlPlaneOn443Ingress: Type: AWS::EC2::SecurityGroupIngress DependsOn: NodeSecurityGroup Properties: Description: Allow pods running extension API servers on port 443 to receive communication from cluster control plane GroupId: !Ref NodeSecurityGroup SourceSecurityGroupId: !Ref ClusterControlPlaneSecurityGroup IpProtocol: tcp FromPort: 443 ToPort: 443 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 NodeGroup: Type: AWS::AutoScaling::AutoScalingGroup DependsOn: Cluster Properties: DesiredCapacity: !Ref NodeAutoScalingGroupDesiredCapacity LaunchConfigurationName: !Ref NodeLaunchConfig MinSize: !Ref NodeAutoScalingGroupDesiredCapacity MaxSize: !Ref NodeAutoScalingGroupDesiredCapacity VPCZoneIdentifier: !Ref Subnets Tags: - Key: Name Value: !Sub ${ClusterName}-node PropagateAtLaunch: true - Key: !Sub kubernetes.io/cluster/${ClusterName} Value: owned PropagateAtLaunch: true UpdatePolicy: AutoScalingRollingUpdate: MaxBatchSize: 1 MinInstancesInService: !Ref NodeAutoScalingGroupDesiredCapacity PauseTime: PT5M NodeLaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration Properties: AssociatePublicIpAddress: true IamInstanceProfile: !Ref NodeInstanceProfile ImageId: !Ref NodeImageIdSSMParam InstanceType: !Ref NodeInstanceType 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}" /opt/aws/bin/cfn-signal --exit-code $? \ --stack ${AWS::StackName} \ --resource NodeGroup \ --region ${AWS::Region} Outputs: NodeInstanceRole: Description: The node instance role Value: !GetAtt NodeInstanceRole.Arn ClusterCertificate: Description: The cluster certificate Value: !GetAtt Cluster.CertificateAuthorityData ClusterEndpoint: Description: The cluster endpoint Value: !GetAtt Cluster.Endpoint