Create EKS Cluster with eksctl
In this pos I will show you how you can install an AWS managed Elastic Kubernetes Service with ekscli.
Create an AWS KMS Custom Managed Key
Create a CMK for the EKS cluster to use when encrypting your Kubernetes secrets:
aws kms create-alias --alias-name alias/devopstales --target-key-id $(aws kms create-key --query KeyMetadata.Arn --output text)
Create EKS Cluster with eksctl
eksctl
is a simple CLI tool for creating clusters on EKS. To download the latest release, run:
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
# Let’s start by setting a few environment variables:
export AWS_REGION=eu-central-1
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
export EKS_CLUSTER_NAME=eks-devopstales
# Get the KMS Custom Managed Key resource name:
export MASTER_ARN=$(aws kms describe-key --key-id alias/devopstales --query KeyMetadata.Arn --output text)
# Create a cluster
eksctl create cluster \
--name $EKS_CLUSTER_NAME \
--region $AWS_REGION \
--managed
If ylou need mor advanced configuration You can create a deployment file for eksctl
:
cat << EOF > eks_devopstales.yaml
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: eks-devopstales
region: ${AWS_REGION}
version: "1.21"
availabilityZones: ["eu-central-1a"]
managedNodeGroups:
- name: workers
labels:
role: workers
environment: poc
desiredCapacity: 1
instanceType: t3.small
volumeEncrypted: true
volumeSize: 30
ssh:
enableSsm: true
secretsEncryption:
keyARN: ${MASTER_ARN}
# To enable all of the control plane logs, uncomment below:
# cloudWatch:
# clusterLogging:
# enableTypes: ["*"]
EOF
Next, use the file you created as the input for the eksctl cluster creation:
eksctl create cluster -f eks_devopstales.yaml
Test The cluster
kubectl get nodes
Using IAM Groups to manage Kubernetes cluster access
We are going to create 3 roles:
- k8sAdmin role which will have admin rights in our EKS cluster
- k8sDev role which will give access to the developers namespace in our EKS cluster
- k8sInteg role which will give access to the integration namespace in our EKS cluster
Create the roles:
POLICY=$(echo -n '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::'; echo -n "$ACCOUNT_ID"; echo -n ':root"},"Action":"sts:AssumeRole","Condition":{}}]}')
echo ACCOUNT_ID=$ACCOUNT_ID
echo POLICY=$POLICY
aws iam create-role \
--role-name k8sAdmin \
--description "Kubernetes administrator role (for AWS IAM Authenticator for Kubernetes)." \
--assume-role-policy-document "$POLICY" \
--output text \
--query 'Role.Arn'
aws iam create-role \
--role-name k8sDev \
--description "Kubernetes developer role (for AWS IAM Authenticator for Kubernetes)." \
--assume-role-policy-document "$POLICY" \
--output text \
--query 'Role.Arn'
aws iam create-role \
--role-name k8sInteg \
--description "Kubernetes role for integration namespace in quick cluster." \
--assume-role-policy-document "$POLICY" \
--output text \
--query 'Role.Arn'
We will define 3 groups:
- k8sAdmin - users from this group will have admin rights on the kubernetes cluster
- k8sDe - users from this group will have full access only in the development namespace of the cluster
- k8sInteg - users from this group will have access to integration namespace.
Create k8sAdmin IAM Group:
aws iam create-group --group-name k8sAdmin
ADMIN_GROUP_POLICY=$(echo -n '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAssumeOrganizationAccountRole",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::'; echo -n "$ACCOUNT_ID"; echo -n ':role/k8sAdmin"
}
]
}')
echo ADMIN_GROUP_POLICY=$ADMIN_GROUP_POLICY
aws iam put-group-policy \
--group-name k8sAdmin \
--policy-name k8sAdmin-policy \
--policy-document "$ADMIN_GROUP_POLICY"
Create k8sDev IAM Group:
aws iam create-group --group-name k8sDev
DEV_GROUP_POLICY=$(echo -n '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAssumeOrganizationAccountRole",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::'; echo -n "$ACCOUNT_ID"; echo -n ':role/k8sDev"
}
]
}')
echo DEV_GROUP_POLICY=$DEV_GROUP_POLICY
aws iam put-group-policy \
--group-name k8sDev \
--policy-name k8sDev-policy \
--policy-document "$DEV_GROUP_POLICY"
Create k8sInteg IAM Group:
aws iam create-group --group-name k8sInteg
INTEG_GROUP_POLICY=$(echo -n '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAssumeOrganizationAccountRole",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::'; echo -n "$ACCOUNT_ID"; echo -n ':role/k8sInteg"
}
]
}')
echo INTEG_GROUP_POLICY=$INTEG_GROUP_POLICY
aws iam put-group-policy \
--group-name k8sInteg \
--policy-name k8sInteg-policy \
--policy-document "$INTEG_GROUP_POLICY"
Create IAM Users and add to the groups:
aws iam create-user --user-name PaulAdmin
aws iam create-user --user-name JeanDev
aws iam create-user --user-name PierreInteg
aws iam add-user-to-group --group-name k8sAdmin --user-name PaulAdmin
aws iam add-user-to-group --group-name k8sDev --user-name JeanDev
aws iam add-user-to-group --group-name k8sInteg --user-name PierreInteg
# Get Access key for the users
aws iam create-access-key --user-name PaulAdmin | tee /tmp/PaulAdmin.json
aws iam create-access-key --user-name JeanDev | tee /tmp/JeanDev.json
aws iam create-access-key --user-name PierreInteg | tee /tmp/PierreInteg.json
Configure Kubernetes RBAC
kubectl create namespace integration
kubectl create namespace development
Configuring access to development namespace:
cat << EOF | kubectl apply -f - -n development
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dev-role
rules:
- apiGroups:
- ""
- "apps"
- "batch"
- "extensions"
resources:
- "configmaps"
- "cronjobs"
- "deployments"
- "events"
- "ingresses"
- "jobs"
- "pods"
- "pods/attach"
- "pods/exec"
- "pods/log"
- "pods/portforward"
- "secrets"
- "services"
verbs:
- "create"
- "delete"
- "describe"
- "get"
- "list"
- "patch"
- "update"
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dev-role-binding
subjects:
- kind: User
name: dev-user
roleRef:
kind: Role
name: dev-role
apiGroup: rbac.authorization.k8s.io
EOF
Configuring access to integration namespace:
cat << EOF | kubectl apply -f - -n integration
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: integ-role
rules:
- apiGroups:
- ""
- "apps"
- "batch"
- "extensions"
resources:
- "configmaps"
- "cronjobs"
- "deployments"
- "events"
- "ingresses"
- "jobs"
- "pods"
- "pods/attach"
- "pods/exec"
- "pods/log"
- "pods/portforward"
- "secrets"
- "services"
verbs:
- "create"
- "delete"
- "describe"
- "get"
- "list"
- "patch"
- "update"
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: integ-role-binding
subjects:
- kind: User
name: integ-user
roleRef:
kind: Role
name: integ-role
apiGroup: rbac.authorization.k8s.io
EOF
Gives Access to our IAM Roles to EKS Cluster:
eksctl create iamidentitymapping \
--cluster eksworkshop-eksctl \
--arn arn:aws:iam::${ACCOUNT_ID}:role/k8sDev \
--username dev-user
eksctl create iamidentitymapping \
--cluster eksworkshop-eksctl \
--arn arn:aws:iam::${ACCOUNT_ID}:role/k8sInteg \
--username integ-user
eksctl create iamidentitymapping \
--cluster eksworkshop-eksctl \
--arn arn:aws:iam::${ACCOUNT_ID}:role/k8sAdmin \
--username admin \
--group system:masters