CloudFORMATION Full Stack problem with AutoScallingGroup for EKS

0

Hello !

I have CF full stack for EKS, and now I change LaunchConfiguration to LaunchTemplate - but after this change AutoScallingGroups is created but cannot join cluster - can anybody show me error :/ I can't find it - thanks


AWSTemplateFormatVersion: '2010-09-09'
Description: DEV CLUSTER for eu-west-1 Region
Parameters:
  EKSClusterName:
    Type: String
    Description: DEV eu-west-1
    Default: 'eks-dev-test-eu-west-1'
  NumWorkerNodes:
    Type: Number
    Description: Number of worker nodes to create
    Default: 2
  WorkerNodesInstanceType:
    Type: String
    Description: EC2 instance type for the worker nodes
    Default: 'm5.large'
  KeyPairName:
    Type: String
    Description: Name of an existing EC2 key pair (for SSH-access to the worker node instances)
    Default: 'eks-key'  
Mappings:
  VpcIpRanges:
    Option1:
      VPC: '10.130.0.0/16'
      PublicSubnet1 : '10.130.0.0/20'
      PublicSubnet2: '10.130.16.0/20'
      PrivateSubnet1: '10.130.32.0/20'
      PrivateSubnet2: '10.130.48.0/20'
      PersistenceSubnet1: '10.130.64.0/20'
      PersistenceSubnet2: '10.130.80.0/20'
  
  EksAmiIds:    
    eu-west-1:
      Standard: ami-0c694b5f143b365a8
    
Resources:
  #============================================================================#
  # VPC
  #============================================================================#

  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !FindInMap [ VpcIpRanges, Option1, VPC ]
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Ref AWS::StackName
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !FindInMap [ VpcIpRanges, Option1, PublicSubnet1 ]
      # AvailabilityZone: !Select
      #   - 0
      #   - !GetAZs ""
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PublicSubnet1"
        - Key: kubernetes.io/role/elb
          Value: 1
        - Key: !Sub "kubernetes.io/cluster/${AWS::StackName}"
          Value: shared
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !FindInMap [ VpcIpRanges, Option1, PublicSubnet2 ]
      # AvailabilityZone: !Select
      #   - 1
      #   - !GetAZs ""
      AvailabilityZone: !Select [ 1, !GetAZs '' ]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PublicSubnet2"
        - Key: kubernetes.io/role/elb
          Value: 1
        - Key: !Sub "kubernetes.io/cluster/${AWS::StackName}"
          Value: shared
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !FindInMap [ VpcIpRanges, Option1, PrivateSubnet1 ]
      # AvailabilityZone: !Select
      #   - 1
      #   - !GetAZs ""
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PrivateSubnet1"
        - Key: kubernetes.io/role/internal-elb
          Value: 1
        - Key: !Sub "kubernetes.io/cluster/${AWS::StackName}"
          Value: shared
  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !FindInMap [ VpcIpRanges, Option1, PrivateSubnet2 ]
      # AvailabilityZone: !Select
      #   - 1
      #   - !GetAZs ""
      AvailabilityZone: !Select [ 1, !GetAZs '' ]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PrivateSubnet2"
        - Key: kubernetes.io/role/internal-elb
          Value: 1
        - Key: !Sub "kubernetes.io/cluster/${AWS::StackName}"
          Value: shared
  PersistenceSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !FindInMap [ VpcIpRanges, Option1, PersistenceSubnet1 ]
      # AvailabilityZone: !Select
      #   - 1
      #   - !GetAZs ""
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PersistenceSubnet1"
  PersistenceSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !FindInMap [ VpcIpRanges, Option1, PersistenceSubnet2 ]
      # AvailabilityZone: !Select
      #   - 1
      #   - !GetAZs ""
      AvailabilityZone: !Select [ 1, !GetAZs '' ]
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PersistenceSubnet2"
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Ref AWS::StackName
  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC
  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-PublicSubnets"
  InternetGatewayRoute:
    Type: AWS::EC2::Route
    # DependsOn is mandatory because route targets InternetGateway
    # See here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html#gatewayattachment
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  NatGateway1EIP:
    Type: AWS::EC2::EIP
    DependsOn: VPCGatewayAttachment
    Properties:
      Domain: vpc
  NatGateway2EIP:
    Type: AWS::EC2::EIP
    DependsOn: VPCGatewayAttachment
    Properties:
      Domain: vpc
  NatGateway1:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway1EIP.AllocationId
      SubnetId: !Ref PublicSubnet1
  NatGateway2:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway2EIP.AllocationId
      SubnetId: !Ref PublicSubnet2
  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName} Private Routes (AZ1)
  DefaultPrivateRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway1
  PrivateRouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName} Private Routes (AZ1)
  DefaultPrivateRoute2:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable2
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway2

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref RouteTable
  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref RouteTable
  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable1
  PrivateSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable2
  PersistenceSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PersistenceSubnet1
      RouteTableId: !Ref RouteTable
  PersistenceSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PersistenceSubnet2
      RouteTableId: !Ref RouteTable

  #============================================================================#
  # Control plane
  #============================================================================#

  ControlPlane:
    Type: AWS::EKS::Cluster
    Properties:
      Name: !Ref AWS::StackName
      Version: "1.27"
      RoleArn: !GetAtt ControlPlaneRole.Arn
      ResourcesVpcConfig:
        SubnetIds:
          - !Ref PrivateSubnet1
          - !Ref PrivateSubnet2 
        SecurityGroupIds:
          - !Ref ControlPlaneSecurityGroup
        EndpointPrivateAccess: true
        EndpointPublicAccess: true
      Tags:
        - Key: ClusterName
          Value: !Ref AWS::StackName
  
  ControlPlaneRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
            Effect: Allow
            Principal:
              Service:
                - eks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
        - arn:aws:iam::aws:policy/AmazonEKSServicePolicy

  #============================================================================#
  # Control plane security group
  #============================================================================#

  ControlPlaneSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for the elastic network interfaces between the control plane and the worker nodes
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-ControlPlaneSecurityGroup"

  ControlPlaneIngressFromWorkerNodesHttps:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      Description: Allow incoming HTTPS traffic (TCP/443) from worker nodes (for API server)
      GroupId: !Ref ControlPlaneSecurityGroup
      SourceSecurityGroupId: !Ref WorkerNodesSecurityGroup
      IpProtocol: tcp
      ToPort: 443
      FromPort: 443
  ControlPlaneEgressToWorkerNodesKubelet:
    Type: AWS::EC2::SecurityGroupEgress
    Properties:
      Description: Allow outgoing kubelet traffic (TCP/10250) to worker nodes
      GroupId: !Ref ControlPlaneSecurityGroup
      DestinationSecurityGroupId: !Ref WorkerNodesSecurityGroup
      IpProtocol: tcp
      FromPort: 10250
      ToPort: 10250
  ControlPlaneEgressToWorkerNodesHttps:
    Type: AWS::EC2::SecurityGroupEgress
    Properties:
      Description: Allow outgoing HTTPS traffic (TCP/442) to worker nodes (for pods running extension API servers)
      GroupId: !Ref ControlPlaneSecurityGroup
      DestinationSecurityGroupId: !Ref WorkerNodesSecurityGroup
      IpProtocol: tcp
      FromPort: 443
      ToPort: 443

  #============================================================================#
  # Worker nodes security group
  # Note: default egress rule (allow all traffic to all destinations) applies
  #============================================================================#

  WorkerNodesSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for all the worker nodes
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-WorkerNodesSecurityGroup"
        - Key: !Sub "kubernetes.io/cluster/"
          Value: "owned"
  WorkerNodesIngressFromWorkerNodes:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      Description: Allow all incoming traffic from other worker nodes
      GroupId: !Ref WorkerNodesSecurityGroup
      SourceSecurityGroupId: !Ref WorkerNodesSecurityGroup
      IpProtocol: "-1"
  WorkerNodesIngressFromControlPlaneKubelet:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      Description: Allow incoming kubelet traffic (TCP/10250) from control plane 
      GroupId: !Ref WorkerNodesSecurityGroup
      SourceSecurityGroupId: !Ref ControlPlaneSecurityGroup
      IpProtocol: tcp
      FromPort: 10250
      ToPort: 10250
  WorkerNodesIngressFromControlPlaneHttps:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      Description: Allow incoming HTTPS traffic (TCP/443) from control plane (for pods running extension API servers)
      GroupId: !Ref WorkerNodesSecurityGroup
      SourceSecurityGroupId: !Ref ControlPlaneSecurityGroup
      IpProtocol: tcp
      FromPort: 443
      ToPort: 443

  #============================================================================#
  # Worker nodes (auto-scaling group)
  #============================================================================#

  WorkerNodesAutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup 
    UpdatePolicy:
      AutoScalingRollingUpdate:
        MinInstancesInService: 1
        MaxBatchSize: 1
    Properties:
      LaunchTemplate:
        LaunchTemplateId: !Ref 'WorkerNodesLaunchTemplate'
        Version: !GetAtt 'WorkerNodesLaunchTemplate.LatestVersionNumber'
      MinSize: !Ref NumWorkerNodes
      MaxSize: !Ref NumWorkerNodes
      VPCZoneIdentifier:
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-WorkerNodesAutoScalingGroup"
          PropagateAtLaunch: true
        # Without this tag, worker nodes are unable to join the cluster:
        - Key: !Sub "kubernetes.io/cluster/${AWS::StackName}"
          Value: "owned"
          PropagateAtLaunch: true
  
  WorkerNodesRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          Effect: Allow
          Principal:
            Service:
              - ec2.amazonaws.com
          Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
        - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly

  # IMPORTANT NOTE: We have to define NodeGroup (type: AWS::EKS::Nodegroup), without this no woker nodes will be attach to cluster
  WorkerNodegroup:
    Type: AWS::EKS::Nodegroup
    DependsOn: ControlPlane
    Properties:
      ClusterName: !Sub "${AWS::StackName}"
      NodeRole: !GetAtt WorkerNodesRole.Arn
      ScalingConfig:
        MinSize:
          Ref: NumWorkerNodes
        DesiredSize:
          Ref: NumWorkerNodes
        MaxSize:
          Ref: NumWorkerNodes
      Subnets:
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2
            #Tags:
      #  - Key: Name
      #    Value: "WorkerNodesAutoScalingGroup"
  
  WorkerNodesLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    DependsOn: ControlPlane
    Properties:
      LaunchTemplateName: !Sub "${AWS::StackName}-WorkerNodesLaunchTemplate"
      LaunchTemplateData:
        TagSpecifications: 
          -
            ResourceType: instance
            Tags:
              - Key: Name
                Value: !Sub "${AWS::StackName}-WorkerNodesAutoScalingGroup"
              - Key: KubernetesCluster
                Value: !Sub ${AWS::StackName}
              - Key: !Sub 'kubernetes.io/cluster/${AWS::StackName}'
                Value: 'owned'

        ImageId: !FindInMap
        - EksAmiIds
        - !Ref AWS::Region
        - Standard
        InstanceType: !Ref WorkerNodesInstanceType
        KeyName: !Ref KeyPairName
        IamInstanceProfile: 
          Arn: !GetAtt WorkerNodesInstanceProfile.Arn
        SecurityGroupIds:

No Answers

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions