Skip to content

Multi-Cluster Management

Multi-cluster management refers to the strategies associated with managing and updating cluster configuration across many Amazon EKS clusters. Infrastructure as code (IaC) tools like the AWS CDK provides the ability to bring automation and consistency when deploying your clusters. You need the ability to apply the same configurations to as many of your clusters as necessary and by defining all of your resources via Infrastructure as Code (IaC), it removes the problem of having to generate or apply custom YAML files for each one of your clusters allowing your teams to move faster. Defining your clusters resources using the AWS CDK allows your teams to focus on the underlying workloads as the infrastructure components will be taken care of via the AWS CDK.

The main benefits organizations can see using the AWS CDK to manage their Amazon EKS clusters can be summarized as follows: - Consistency across all clusters and environments - Streamlining access control across your organization - Ease of management for multiple clusters - Access to GitOps methodologies and best practices - Automated lifecycle management for cluster deployment

The Amazon EKS Blueprints Quick Start references the eks-blueprints-patterns repository repository that includes examples of different deployment patterns and options which includes patterns for multi-cluster that can be deployed across multiple regions. If you take a look at the main.ts file in the patterns repository, you will notice that the stacks that define our Amazon EKS clusters and associated pipelines that are deployed to different regions as shown in the snippet below:

#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
const app = new cdk.App();
//-------------------------------------------
// Single Cluster with multiple teams.
//-------------------------------------------
import MultiTeamConstruct from '../lib/multi-team-construct'
new MultiTeamConstruct(app, 'multi-team');
//-------------------------------------------
// Multiple clusters, multiple regions.
//-------------------------------------------
import MultiRegionConstruct from '../lib/multi-region-construct'
new MultiRegionConstruct(app, 'multi-region');
//-------------------------------------------
// Single Fargate cluster.
//-------------------------------------------
import FargateConstruct from '../lib/fargate-construct'
new FargateConstruct(app, 'fargate');
//-------------------------------------------
// Multiple clusters with deployment pipeline.
//-------------------------------------------
import PipelineStack from '../lib/pipeline-stack'
const account = process.env.CDK_DEFAULT_ACCOUNT
const region = process.env.CDK_DEFAULT_REGION
const env = { account, region }
new PipelineStack(app, 'pipeline', { env });

Using the AWS CDK, you can define the specific region to deploy your clusters using environment variables as a construct in Typescript as shown in the example above. If you were to deploy all the stacks in your main.ts file you would be able to view your running clusters by region by running the following command

aws eks list-cluster --region <insert region>

If for example you chose the region us-west-2, you would get a similar output:

{
    "clusters": [
        "all clusters in this region"
    ]
}

Multi-Region Management

In a production environment, it is common to have clusters that reside in different locations. This could be in different regions, on-prem, or follow a hybrid cloud model. Some of the common design patterns that come in to play when it comes to multi-cluster management across these different operational models include things like high availability, data replication, networking, traffic routing, and the underlying management of those clusters. In the eks-blueprints-patterns/lib/multi-region-construct directory, you will find the index.ts file which shows a concrete example of how to deploy multiple clusters to different regions as shown below

import * as cdk from 'aws-cdk-lib';
// Blueprints Lib
import * as blueprints from '@aws-quickstart/eks-blueprints'
// Team implementations
import * as team from '../teams'
export default class MultiRegionConstruct extends cdk.Construct {
    constructor(scope: cdk.Construct, id: string) {
        super(scope, id);
        // Setup platform team
        const accountID = process.env.CDK_DEFAULT_ACCOUNT!
        const platformTeam = new team.TeamPlatform(accountID)
        const teams: Array<blueprints.Team> = [platformTeam];
        const version = "auto";
        // AddOns for the cluster.
        const addOns: Array<blueprints.ClusterAddOn> = [
            new blueprints.addons.NginxAddOn,
            new blueprints.addons.ArgoCDAddOn,
            new blueprints.addons.MetricsServerAddOn,
            new blueprints.addons.ClusterAutoScalerAddOn,
            new blueprints.addons.ContainerInsightsAddOn,
            new blueprints.addons.VpcCniAddOn(),
            new blueprints.addons.CoreDnsAddOn(),
            new blueprints.addons.KubeProxyAddOn()
        ];
        const east = 'blueprint-us-east-2'
        new blueprints.EksBlueprint(scope, { id: `${id}-${east}`, addOns, teams, version}, {
            env: { region: east }
        });
        const central = 'blueprint-us-central-2'
        new blueprints.EksBlueprint(scope, { id: `${id}-${central}`, addOns, teams, version }, {
            env: { region: central }
        });
        const west = 'blueprint-us-west-2'
        new blueprints.EksBlueprint(scope, { id: `${id}-${west}`, addOns, teams, version }, {
            env: { region: west }
        });
    }
}
This construct imports all of the core components of the EKS Blueprints framework, Teams construct, and Addons as modules which then deploys our clusters to different regions. The main point to take away from this is that we are adding automation and consistency to our clusters as we deploy multiple clusters to multiple regions since all of our components have already been defined in the EKS Blueprints library along with Teams and Addons.