Skip to main content

Command Palette

Search for a command to run...

2.1. Automation: Deploying Your Infrastructure with AWS CloudFormation (Template Deep Dive)

Updated
5 min read
2.1. Automation: Deploying Your Infrastructure with AWS CloudFormation (Template Deep Dive)

Kubernetes on AWS: Automating Your Infrastructure with CloudFormation (Template Deep Dive)

Okay, you've decided to dive into Kubernetes on AWS. Great choice! But setting up all the necessary infrastructure - VPCs, subnets, security groups, EC2 instances, etc. - can be a daunting task. Doing it manually is time-consuming and prone to errors. That's where automation comes to the rescue.

And when it comes to automating infrastructure on AWS, CloudFormation is your best friend.

Think of CloudFormation as a recipe book for your infrastructure. You write a recipe (the template), give it to AWS, and CloudFormation magically cooks up all the ingredients (the resources) and assembles them according to your instructions.

In this post, we'll deep dive into a CloudFormation template example specifically tailored for deploying the foundational infrastructure needed for a Kubernetes cluster on AWS.

What is CloudFormation?

CloudFormation is an Infrastructure as Code (IaC) service provided by AWS. It allows you to define your infrastructure in a declarative way using a template file. This template describes the desired state of your infrastructure, and CloudFormation provisions and manages the resources accordingly.

Why Use CloudFormation for Kubernetes?

  • Repeatability: Deploy the same infrastructure consistently across different environments (dev, staging, production).

  • Consistency: Eliminate configuration drift and ensure all resources are set up correctly.

  • Version Control: Treat your infrastructure as code, track changes, and revert to previous configurations.

  • Efficiency: Automate the entire deployment process, saving time and effort.

Deep Dive: A Basic Kubernetes CloudFormation Template

Let's look at a simplified example of a CloudFormation template. While a complete Kubernetes deployment would be much more complex, this template will give you a good understanding of the basics. We'll focus on creating a simple VPC, subnets, and an internet gateway.

AWSTemplateFormatVersion: '2010-09-09'
Description:  A basic CloudFormation template for a VPC, Subnets, and an Internet Gateway

Parameters:
  VpcCIDR:
    Type: String
    Description: CIDR block for the VPC
    Default: 10.0.0.0/16

  PublicSubnet1CIDR:
    Type: String
    Description: CIDR block for the Public Subnet 1
    Default: 10.0.1.0/24

  PublicSubnet2CIDR:
    Type: String
    Description: CIDR block for the Public Subnet 2
    Default: 10.0.2.0/24

Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      Tags:
        - Key: Name
          Value: MyKubernetesVPC

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: !Ref PublicSubnet1CIDR
      MapPublicIpOnLaunch: 'true'  # Important for nodes to get public IPs
      AvailabilityZone: !Select [ 0, !GetAZs '' ] # Automatically gets the first AZ in the region
      Tags:
        - Key: Name
          Value: MyKubernetesPublicSubnet1

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: !Ref PublicSubnet2CIDR
      MapPublicIpOnLaunch: 'true'  # Important for nodes to get public IPs
      AvailabilityZone: !Select [ 1, !GetAZs '' ] # Automatically gets the second AZ in the region
      Tags:
        - Key: Name
          Value: MyKubernetesPublicSubnet2

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: MyKubernetesInternetGateway

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref InternetGateway

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
        - Key: Name
          Value: MyKubernetesPublicRouteTable

  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0  # Route all traffic
      GatewayId: !Ref InternetGateway

  Subnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  Subnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

Outputs:
  VPCId:
    Description: The ID of the VPC
    Value: !Ref MyVPC
    Export:
      Name: !Sub "${AWS::StackName}-VPCId"

  PublicSubnet1Id:
    Description: The ID of the Public Subnet 1
    Value: !Ref PublicSubnet1
    Export:
      Name: !Sub "${AWS::StackName}-PublicSubnet1Id"

  PublicSubnet2Id:
    Description: The ID of the Public Subnet 2
    Value: !Ref PublicSubnet2
    Export:
      Name: !Sub "${AWS::StackName}-PublicSubnet2Id"

Breaking Down the Template:

  • AWSTemplateFormatVersion: Specifies the version of the CloudFormation template format.

  • Description: A brief description of what the template does.

  • Parameters: Allows you to customize the template by providing values when you create the stack. Think of these as customizable ingredients in your recipe. Here, we define parameters for the VPC CIDR block and subnet CIDR blocks.

  • Resources: This is the heart of the template. It defines the AWS resources you want to create. Each resource has a Type (e.g., AWS::EC2::VPC for a VPC, AWS::EC2::Subnet for a subnet) and Properties (e.g., CidrBlock for the VPC, VpcId for the subnet).

    • !Ref: This intrinsic function refers to the logical ID of another resource. For example, !Ref MyVPC refers to the VPC resource defined earlier. It's like saying "add a cup of the VPC you just made" in your recipe.

    • !GetAZs '': Gets a list of Availability Zones in the current region.

    • !Select [ 0, ... ]: Selects an item from a list. In this case, it selects the first and second Availability Zone for the subnets.

  • Outputs: Defines values that are returned after the stack is created. These values can be used by other CloudFormation templates or applications. The Export section is crucial for cross-stack referencing, allowing other stacks (like your Kubernetes cluster stack) to use resources created in this stack.

Real-World Example: Building a Kubernetes Control Plane

This basic VPC template forms the foundation for your Kubernetes cluster. You can then create another CloudFormation template to deploy the Kubernetes control plane (master nodes) within this VPC and these subnets. This second template would import the VPC and Subnet IDs using the Outputs section of the first template, referencing them in the Properties of the EC2 instances that will act as your Kubernetes masters.

Challenge: Hardcoding Availability Zones

One challenge is hardcoding Availability Zones (AZs). What if you want to deploy to a different region where the AZs are different?

Solution: Dynamic AZ Selection

Instead of hardcoding the AZs, use the !GetAZs intrinsic function and !Select to dynamically select them:

AvailabilityZone: !Select [ 0, !GetAZs '' ]  # Selects the first AZ in the region

This ensures your template will work in any region without modification.

Architectural Diagram:

+-----------------------+
|  CloudFormation       |
|   (Template)          |
+-----------------------+
         |
         |  (Creates/Updates)
         V
+-----------------------+   +-----------------------+
|       AWS VPC         |---|   AWS Subnets        |
|  (MyKubernetesVPC)    |   |  (PublicSubnet1, 2)  |
+-----------------------+   +-----------------------+
         |                  |       ^       ^
         |                  |       |       |
         +------------------>-------+-------+
         |
         V
+-----------------------+
|   Internet Gateway     |
| (MyKubernetesInternetGateway)|
+-----------------------+

Key Takeaways:

  • CloudFormation automates infrastructure provisioning on AWS.

  • Templates define the desired state of your infrastructure.

  • Resources, Parameters, and Outputs are key sections of a CloudFormation template.

  • CloudFormation allows you to build reusable and scalable infrastructure for your Kubernetes deployments.

By using CloudFormation, you can significantly simplify the process of deploying and managing your Kubernetes clusters on AWS. Start with small, modular templates and gradually build up to more complex deployments. Happy automating!

More from this blog

TechZen

136 posts