AWSTemplateFormatVersion: '2010-09-09' Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "<<<<< Deploy EC2 : kops-ec2 >>>>>" Parameters: - KeyName - MyIamUserAccessKeyID - MyIamUserSecretAccessKey - SgIngressSshCidr - LatestAmiId - Label: default: "<<<<< AWS kOps Config >>>>>" Parameters: - KubernetesVersion - ClusterBaseName - S3StateStore - MasterNodeInstanceType - WorkerNodeInstanceType - WorkerNodeCount - VpcBlock - Label: default: "<<<<< Region & AZ >>>>>" Parameters: - TargetRegion - AvailabilityZone1 - AvailabilityZone2 Parameters: KeyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the instances. Linked to AWS Parameter Type: AWS::EC2::KeyPair::KeyName ConstraintDescription: must be the name of an existing EC2 KeyPair. MyIamUserAccessKeyID: Description: IAM User - AWS Access Key ID (won't be echoed) Type: String NoEcho: true MyIamUserSecretAccessKey: Description: IAM User - AWS Secret Access Key (won't be echoed) Type: String NoEcho: true SgIngressSshCidr: Description: The IP address range that can be used to communicate to the EC2 instances Type: String MinLength: '9' MaxLength: '18' Default: 0.0.0.0/0 AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. LatestAmiId: Description: (DO NOT CHANGE) Type: 'AWS::SSM::Parameter::Value' Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' AllowedValues: - /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 KubernetesVersion: Description: Enter Kubernetes Version, 1.23.Y ~ 1.25.Y Type: String Default: 1.24.11 ClusterBaseName: Type: String Default: 'pkos.k8s.local' Description: AWS kOps ClusterName , My DomainName S3StateStore: Type: String Description: S3 Bucket Name (KOPS_STATE_STORE) Default: 'pkos-kops-s3-mybucket' MasterNodeInstanceType: Description: Enter EC2 Instance Type. Default is t3.medium. Type: String Default: t3.medium WorkerNodeInstanceType: Description: Enter EC2 Instance Type. Default is t3.medium. Type: String Default: t3.medium WorkerNodeCount: Description: Worker Node Counts Type: String Default: 2 VpcBlock: Type: String Default: 172.30.0.0/16 Description: AWS kOps VPC CIDR TargetRegion: Type: String Default: ap-northeast-2 AvailabilityZone1: Type: String Default: ap-northeast-2a AvailabilityZone2: Type: String Default: ap-northeast-2c # Resources Resources: MyVPC: Type: AWS::EC2::VPC Properties: EnableDnsSupport: true EnableDnsHostnames: true CidrBlock: 10.0.0.0/16 Tags: - Key: Name Value: My-VPC MyIGW: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: My-IGW MyIGWAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref MyIGW VpcId: !Ref MyVPC MyPublicRT: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref MyVPC Tags: - Key: Name Value: My-Public-RT DefaultPublicRoute: Type: AWS::EC2::Route DependsOn: MyIGWAttachment Properties: RouteTableId: !Ref MyPublicRT DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref MyIGW MyPublicSN: Type: AWS::EC2::Subnet Properties: VpcId: !Ref MyVPC AvailabilityZone: !Select [ 0, !GetAZs '' ] CidrBlock: 10.0.0.0/24 Tags: - Key: Name Value: My-Public-SN MyPublicSNRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref MyPublicRT SubnetId: !Ref MyPublicSN KOPSEC2SG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: kops ec2 Security Group VpcId: !Ref MyVPC Tags: - Key: Name Value: KOPS-EC2-SG SecurityGroupIngress: - IpProtocol: tcp FromPort: '22' ToPort: '22' CidrIp: !Ref SgIngressSshCidr - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: !Ref SgIngressSshCidr # Deploy EC2 KOPSEC2: Type: AWS::EC2::Instance Properties: InstanceType: t3.small ImageId: !Ref LatestAmiId KeyName: !Ref KeyName Tags: - Key: Name Value: kops-ec2 NetworkInterfaces: - DeviceIndex: 0 SubnetId: !Ref MyPublicSN GroupSet: - !Ref KOPSEC2SG AssociatePublicIpAddress: true PrivateIpAddress: 10.0.0.10 UserData: Fn::Base64: !Sub | #!/bin/bash hostnamectl --static set-hostname kops-ec2 # Change Timezone ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime # Install Packages cd /root yum -y install tree jq git htop curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl curl -Lo kops https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64 chmod +x kops mv kops /usr/local/bin/kops curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip >/dev/null 2>&1 sudo ./aws/install export PATH=/usr/local/bin:$PATH source ~/.bash_profile complete -C '/usr/local/bin/aws_completer' aws ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa echo 'alias vi=vim' >> /etc/profile echo 'sudo su -' >> /home/ec2-user/.bashrc curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash wget https://github.com/andreazorzetto/yh/releases/download/v0.4.0/yh-linux-amd64.zip unzip yh-linux-amd64.zip mv yh /usr/local/bin/ # K8S Version export KUBERNETES_VERSION=${KubernetesVersion} echo "export KUBERNETES_VERSION=${KubernetesVersion}" >> /etc/profile # IAM User Credentials export AWS_ACCESS_KEY_ID=${MyIamUserAccessKeyID} export AWS_SECRET_ACCESS_KEY=${MyIamUserSecretAccessKey} export AWS_DEFAULT_REGION=${AWS::Region} export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text) echo "export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> /etc/profile echo "export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> /etc/profile echo "export AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION" >> /etc/profile echo 'export AWS_PAGER=""' >>/etc/profile echo "export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)" >> /etc/profile # CLUSTER_NAME export KOPS_CLUSTER_NAME=${ClusterBaseName} echo "export KOPS_CLUSTER_NAME=$KOPS_CLUSTER_NAME" >> /etc/profile # S3 State Store Bucket Name export KOPS_STATE_STORE=s3://${S3StateStore} echo "export KOPS_STATE_STORE=s3://${S3StateStore}" >> /etc/profile # Git Clone git clone https://github.com/gasida/PKOS.git /root/pkos # Install krew curl -LO https://github.com/kubernetes-sigs/krew/releases/download/v0.4.3/krew-linux_amd64.tar.gz tar zxvf krew-linux_amd64.tar.gz ./krew-linux_amd64 install krew export PATH="$PATH:/root/.krew/bin" echo 'export PATH="$PATH:/root/.krew/bin"' >> /etc/profile # Install kube-ps1 echo 'source <(kubectl completion bash)' >> /etc/profile echo 'alias k=kubectl' >> /etc/profile echo 'complete -F __start_kubectl k' >> /etc/profile git clone https://github.com/jonmosco/kube-ps1.git /root/kube-ps1 cat <<"EOT" >> /root/.bash_profile source /root/kube-ps1/kube-ps1.sh KUBE_PS1_SYMBOL_ENABLE=false function get_cluster_short() { echo "$1" | cut -d . -f1 } KUBE_PS1_CLUSTER_FUNCTION=get_cluster_short KUBE_PS1_SUFFIX=') ' PS1='$(kube_ps1)'$PS1 EOT # Install krew plugin kubectl krew install ctx ns get-all ktop # df-pv mtail tree # Install Docker amazon-linux-extras install docker -y systemctl start docker && systemctl enable docker # AWS kOps Create kops create cluster --zones=${AvailabilityZone1},${AvailabilityZone2} --networking amazonvpc --cloud aws \ --master-size ${MasterNodeInstanceType} --node-size ${WorkerNodeInstanceType} --node-count=${WorkerNodeCount} \ --network-cidr ${VpcBlock} --ssh-public-key ~/.ssh/id_rsa.pub --kubernetes-version "${KubernetesVersion}" --dry-run \ --output yaml > kops.yaml # kOps Addon cat < addon.yaml certManager: enabled: true awsLoadBalancerController: enabled: true externalDns: provider: external-dns metricsServer: enabled: true kubeProxy: metricsBindAddress: 0.0.0.0 kubeDNS: provider: CoreDNS nodeLocalDNS: enabled: true memoryRequest: 5Mi cpuRequest: 25m EOT sed -i -n -e '/aws$/r addon.yaml' -e '1,$p' kops.yaml # max-pod per node cat < maxpod.yaml maxPods: 100 EOT sed -i -n -e '/anonymousAuth/r maxpod.yaml' -e '1,$p' kops.yaml sed -i 's/amazonvpc: {}/amazonvpc:/g' kops.yaml cat < awsvpc.yaml env: - name: ENABLE_PREFIX_DELEGATION value: "true" EOT sed -i -n -e '/amazonvpc/r awsvpc.yaml' -e '1,$p' kops.yaml cat kops.yaml | kops create -f - kops update cluster --name $KOPS_CLUSTER_NAME --ssh-public-key ~/.ssh/id_rsa.pub --yes # kops kubeconfig echo "kops export kubeconfig --admin" >> /etc/profile Outputs: KOPSEC2IP: Value: !GetAtt KOPSEC2.PublicIp