How to Create a Kubernetes Cluster in AWS Using Kops

Pinterest LinkedIn Tumblr

In this guide, we are going to create a kubernetes cluster using kops. Kops is sa tool that allows you to manage kubernetes clusters in the cloud (AWS, Google cloud or Azure) but can als o be used to manage clusters in OpenStack.

Learn more about openstack in its github repo here


kops is a single binary application that can be installed in either Linux, Mac or Windows. Grab the latest binary for your OS in its releases page here and add it to your executable path dir. Verify the installation using this command:

kops version


I am using version 1.18.3 (git-11ec695516) for this guide.

You will also need kubectl installed.

AWS User

Create KOPS user

# Create group called kops
aws iam create-group --group-name kops

# Attach the permissions to the group
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/IAMFullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonVPCFullAccess --group-name kops

# Create user
aws iam create-user --user-name kops

# add user to the group
aws iam add-user-to-group --user-name kops --group-name kops

# Generate access key for the user
aws iam create-access-key --user-name kops

Creating cluster

Create a state bucket

aws s3 mb s3:// --region me-south-1

# Version the bucket
aws s3api put-bucket-versioning --bucket --versioning-configuration Status=Enabled

# Encrypt the bucket
aws s3api put-bucket-encryption --bucket --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'

Domain in AWS

For this to happen, you will need to have the domain in AWS working.

  • Go to Route53 -> Hosted Zone and add a hosted zone – (mine is
  • From the generated NS records, add them to your hosting provider such that the NS records for the domain just added matches the ones provided by AWS.

Verify with this:

aws route53 list-hosted-zones --output=table
dig -t NS

dig +short soa
dig +short ns


To create the cluster, use the kops create cluster command

For this guide, we are using AWS. we will need a user with

kops create cluster \
  --master-count=1 \
  --node-count=3 \
  --cloud aws \
  --cloud-labels "Environment=\"dev\",Type=\"k8s\",Role=\"node\",Provisioner=\"kops\"" \
  --node-size t3.large \
  --master-size t3.medium \
  --state=s3:// \
  --topology=private \
  --bastion=true \
  --kubernetes-version=v1.19.7 \
  --zones=me-south-1a,me-south-1b,me-south-1c \ \
  --networking=calico \
  --vpc=vpc-0b8284ea24e023548 \
  --ssh-public-key ~/.ssh/ \

Edit cluster

I am going to edit the cluster to add a node policy to allow anything matching k8s-* so services in the cluster can access aws resources.

kops edit cluster --state=s3://


    anonymousAuth: false
    authenticationTokenWebhook: true
    authorizationMode: Webhook
    node: |
          "Effect": "Allow",
          "Action": [
          "Resource": [

Since I created a VPC with private and public networks I will use those to set up cluster resources there:

  - cidr:
    name: eu-west-3a
    type: Private
    zone: eu-west-3a
    id: subnet-xxx
    egress: nat-xxx
  - cidr:
    name: utility-eu-west-3a
    type: Utility
    zone: eu-west-3a
    id: subnet-xxx

Topology being private, the private subnets have the egress as the nat gateway. The id is the subnet id and the cidr is the cidr for that private subnet.

Updating cluster

To apply changes to the cluster, use the following command:

kops update cluster --state=s3:// --yes

Other Kops commands

Edit cluster

kops edit ig nodes --state=s3://

kops edit ig master-eu-west-3a --state=s3://

Validate cluster

kops validate cluster \ \

Get cluster

kops get cluster --state=s3://
kops get cluster --state=s3:// -o yaml

kops get instancegroups --state=s3://

Export kubeconfig

Export a kubecfg file for a cluster from the state store. By default the configuration will be saved into a users $HOME/.kube/config file.

kops export kubecfg --state=s3://

# As Admin user
kops export kubecfg --state=s3:// --admin

# To a file
kops export kubecfg --state=s3:// --kubeconfig

Apply a rolling update

# --yes to apply
kops rolling-update cluster --state=s3:// --yes

Delete cluster

kops delete cluster --state=s3:// --yes

Remove state bucket

aws s3 rm s3://${STATE_BUCKET} --recursive
aws s3 rb s3://${STATE_BUCKET} --region ${REGION} --force

I am a Devops Engineer, but I would describe myself as a Tech Enthusiast who is a fan of Open Source, Linux, Automations, Cloud and Virtualization. I love learning and exploring new things so I blog in my free time about Devops related stuff, Linux, Automations and Open Source software. I can also code in Python and Golang.

Write A Comment