AWSTemplateFormatVersion: 2010-09-09 Description: This template creates an EC2 instance which is used to run eksctl and kubectl. (qs-1tss294hj) Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: IAM role configuration Parameters: - RoleName - Label: default: Boot node configuration Parameters: - BootNodeName - EKSClusterName - LatestAmiId - Label: default: Network configuration Parameters: - PublicSubnet1ID - PublicSubnet2ID - PublicSubnet3ID - PrivateSubnet1ID - PrivateSubnet2ID - PrivateSubnet3ID - AvailabilityZone1 - AvailabilityZone2 - AvailabilityZone3 ParameterLabels: RoleName: default: Role name BootNodeName: default: Boot node name PublicSubnet1ID: default: Public subnet 1 ID PublicSubnet2ID: default: Public subnet 2 ID PublicSubnet3ID: default: Public subnet 3 ID PrivateSubnet1ID: default: Private subnet 1 ID PrivateSubnet2ID: default: Private subnet 2 ID PrivateSubnet3ID: default: Private subnet 3 ID AvailabilityZone1: default: Availability Zone 1 ID AvailabilityZone2: default: Availability Zone 2 ID AvailabilityZone3: default: Availability Zone 3 ID EKSClusterName: default: EKS cluster name LatestAmiId: default: Latest AMI ID Parameters: RoleName: Description: The name of the role to attach to the boot node. Type: String BootNodeName: Description: The name of the boot node. Type: String PublicSubnet1ID: Description: The ID of the public subnet in Availability Zone 1 for the boot node and EKS cluster (for example, "subnet-9bc642ac"). Type: String PublicSubnet2ID: Description: The ID of the public subnet in Availability Zone 2 for the EKS cluster (for example, "subnet-9bc642ac"). Type: String PublicSubnet3ID: Description: The ID of the public subnet in Availability Zone 3 for the EKS cluster (for example, "subnet-9bc642ac"). Type: String PrivateSubnet1ID: Description: The ID of the private subnet in Availability Zone 1 for the EKS cluster (for example, "subnet-9bc642ac"). Type: String PrivateSubnet2ID: Description: The ID of the private subnet in Availability Zone 2 for the EKS cluster (for example, "subnet-9bc642ac"). Type: String PrivateSubnet3ID: Description: The ID of the private subnet in Availability Zone 3 for the EKS cluster (for example, "subnet-9bc642ac"). Type: String AvailabilityZone1: Description: The name of the Availability Zone 1 for the EKS cluster (for example, "ca-central-1a"). Type: String AvailabilityZone2: Description: The name of the Availability Zone 2 for the EKS cluster (for example, "ca-central-1b"). Type: String AvailabilityZone3: Description: The name of the Availability Zone 3 for the EKS cluster (for example, "ca-central-1c"). Type: String EKSClusterName: Type: String Description: Name of the new EKS cluster (length 2-250) (required). The name must start with a letter and contain only lowercase letters, numbers, hyphens, underscores, periods, and forward slashes. MinLength: 2 MaxLength: 250 AllowedPattern: (?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)* ConstraintDescription: The name must start with a letter and can only contain lowercase letters, numbers, hyphens, underscores, periods and forward slashes. LatestAmiId: Description: Latest Amazon Linux 2 AMI ID from SSM Parameter Store. Type: 'AWS::SSM::Parameter::Value' Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' Resources: BootNodeProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref RoleName Path: / BootNode: Type: AWS::EC2::Instance Metadata: AWS::CloudFormation::Init: configSets: Required: - StackPropertiesFile StackPropertiesFile: commands: 01_create_opt_ibm: command: mkdir -p /opt/ibm test: test ! -d /opt/ibm files: /opt/ibm/cluster.yaml: mode: '000755' owner: root group: root content: !Sub - | apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: ${ClusterName} region: ${AWS::Region} vpc: subnets: private: ${AZ1}: { id: ${PrivateSubnet1ID} } ${AZ2}: { id: ${PrivateSubnet2ID} } ${AZ3}: { id: ${PrivateSubnet3ID} } public: ${AZ1}: { id: ${PublicSubnet1ID} } ${AZ2}: { id: ${PublicSubnet2ID} } ${AZ3}: { id: ${PublicSubnet3ID} } managedNodeGroups: - name: ng-1-workers instanceType: m5.large desiredCapacity: 3 - AZ1: !Ref AvailabilityZone1 AZ2: !Ref AvailabilityZone2 AZ3: !Ref AvailabilityZone3 PrivateSubnet1ID: !Ref PrivateSubnet1ID PrivateSubnet2ID: !Ref PrivateSubnet2ID PrivateSubnet3ID: !Ref PrivateSubnet3ID PublicSubnet1ID: !Ref PublicSubnet1ID PublicSubnet2ID: !Ref PublicSubnet2ID PublicSubnet3ID: !Ref PublicSubnet3ID ClusterName: !Ref EKSClusterName Properties: ImageId: !Ref LatestAmiId InstanceType: t2.micro IamInstanceProfile: !Ref BootNodeProfile SubnetId: !Ref PublicSubnet1ID Tags: - Key: "Name" Value: !Ref BootNodeName UserData: Fn::Base64: !Sub | #!/bin/bash /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource BootNode --configsets Required --region ${AWS::Region} i=0 while [ ! -f /opt/ibm/cluster.yaml ]; do echo "/opt/ibm/cluster.yaml isn't available yet, waiting" sleep 5 i=$[$i+1] if [ $i -ge 12 ]; then echo "Timed out waiting 60 seconds for /opt/ibm/cluster.yaml to be available" break; fi echo "/opt/ibm/cluster.yaml ready:" cat /opt/ibm/cluster.yaml done /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource BootNode --region ${AWS::Region} Outputs: InstanceId: Description: The instance ID of the boot node Value: !Ref BootNode InstanceName: Description: The name of the boot node Value: !Ref BootNodeName User: Description: The user of the boot node Value: "ec2-user"