AWS Cloudformation is a robust Infrastructure-As-Code tool. It's well-supported and allows us to write templates in JSON or YAML. And it is also used behind the scenes by a number of tools in the cloud native ecosystem. For example kops. But more importantly for this post - it's used by eksctl
!
In my previous post I used eksctl
to spin up a cluster complete with Karpenter and a few more add-ons.
So for this post - instead of starting from scratch I decided to just reuse the stack template created by eksctl
.
Yes, I could have used one of the quickstart stacks provided by AWS but this repo has so many options that I got lost reading the docs.
So instead I just opted to export the template from the existing stack. That's the cheating part :)
This article is part of series "How to Spin Up an AWS Cluster".
Take a look at the different methods:
Way 1 - Create an EKS Cluster in AWS Management Console
Way 2 - Create an EKS Cluster in AWS cli
Way 3 - Create an EKS Cluster with eksctl
Way 4 - Create an EKS Cluster with CloudFormation
Way 5 - Create an EKS Cluster with python and boto3
Way 6 - Create an EKS Cluster with AWS CDK
Way 7 - Create an EKS Cluster with Terraform
Way 8 - Create an EKS Cluster with Pulumi
Way 9 - Create an EKS Cluster with Crossplane
Exporting the CloudFormation template
But how does one export a CloudFormation template from eksctl
? As I found out - this was requested repeatedly, but never implemented. See here for example.
So instead I went to the CloudFormation console in AWS, clicked on the stacks the I wanted (the ones eksctl
generated) and went to the 'Template' tab.
But as you can notice - this only gives us JSON. Now I'm a YAML engineer, so I wanted yaml. For which I clicked on 'View in Application Composer' - and when there - 'Template' and switched the toggle to 'YAML'. Voila - I can now copy the template text and continue editing it on my laptop.
In its basic form eksctl
creates 2 stacks:
- one for the EKS control plane
- another one for the managed nodegroup
I could've bundled both stacks into one file but this separation actually makes a lot of sense. We may want more than one node group in our EKS, or we may decide to let go of node groups and opt to manage nodes with Karpenter. (You should!)
So I created 2 template files - eks.yaml (for the control plane) and ng.yaml (for the node group).
I've edited them both so they have no hard-coded resource names. Everything is based on the stack name you chose.
Second stack receives the name of the first stack as a parameter and uses some of its exports like this:
I'm also defining SSH access to the nodes with an imported SSH key.
You could of course skip the whole SSH stuff, but I tend to believe it's important - especially when bringing up clusters for learning purposes.
Spinning Up EKS iwth CloudFormation
Here's how to use this:
1. Clone the example repo:
2. Change into the cloudformation folder:
3. Generate an ssh key:
4. Insert the public key into the node group template: I'm saving the original file with bak extension.
The result should look something like (ng.yaml line 15):
5. And finally run the deploy.sh script with 2 parameters - the desired name of the cluster and the AWS region:
Inside the script this is translated into the following 2 CFN (cloudformation) invocations:
Things to note here: the necessary capability CAPABILITY_NAMED_IAM
and the parameter named ClusterStack that I'm passing to the second stack.
After a short while we can verify the state of our stacks:
If this returns the names of our 2 stacks:
then we're great! If not - proceed to the CloudFormation UI in AWS console to find the reasons why your stack creation failed.
Summary
CloudFormation is a great IaC tool if you're fine with AWS vendor-lock. It's definitely possible to create an EKS cluster with CloudFormation and that's what such tools as kops
and eksctl
do under the hood.
While writing CloudFormation from scratch is no fun - we can use the templates generated by eksctl
- as I did. Or we can build the templates ourselves in the AWS Application Composer. But then we need to take into the account everything necessary for the cluster operation - security groups, gateways, routing rules, IAM policies. And that's a lot to take care of.
Are you using pure CloudFormation as your IaC tool?