Skip to content

Commit e137bc7

Browse files
committed
Add EKS Cluster CloudFormation example.
1 parent 4e474fa commit e137bc7

File tree

8 files changed

+484
-0
lines changed

8 files changed

+484
-0
lines changed

cluster-aws-eks/README.md

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# AWS EKS Kubernetes Cluster Example
2+
3+
This example demonstrates the setup of a highly-available AWS EKS Kubernetes cluster using Ansible to manage multiple CloudFormation templates.
4+
5+
## Usage
6+
7+
Prerequisites:
8+
9+
- You must have an AWS account to run this example.
10+
- You must use an IAM account with privileges to create VPCs, Internet Gateways, EKS Clusters, Security Groups, etc.
11+
- This IAM account will inherit the `system:master` permissions in the cluster, and only that account will be able to make the initial changes to the cluster via `kubectl` or Ansible.
12+
- In your AWS account, you must have an EC2 Key Pair named `eks-example` (or change the name of the `aws_key_name` in `vars/main.yml` to a Key Pair you'd like to use).
13+
14+
### Build the Cluster via CloudFormation Templates with Ansible
15+
16+
Make sure you have the `boto` Python library installed (e.g. via Pip with `pip3 install boto`), and then run the playbook to build the EKS cluster and nodegroup:
17+
18+
$ ansible-playbook -i inventory main.yml
19+
20+
> Note: EKS Cluster creation is a slow operation, and could take 10-20 minutes.
21+
22+
After the cluster and nodegroup are created, you should see one EKS cluster and three EC2 instances running, and you can start to manage the cluster with Ansible.
23+
24+
### Set up authentication to the cluster via `kubeconfig`
25+
26+
1. Install the `aws-iam-authenticator` following [these directions](https://docs.aws.amazon.com/eks/latest/userguide/install-aws-iam-authenticator.html).
27+
2. Create a `kubeconfig` file for EKS following [these directions](https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html):
28+
29+
```
30+
$ aws eks --region us-east-1 update-kubeconfig --name eks-example --kubeconfig ~/.kube/eks-example
31+
```
32+
33+
This creates a `kubeconfig` file located in `~/kube/eks-example`.
34+
3. Tell `kubectl` where to find the `kubeconfig`:
35+
36+
```
37+
$ export KUBECONFIG=~/.kube/eks-example
38+
```
39+
4. Test that `kubectl` can see the cluster:
40+
41+
```
42+
$ kubectl get svc
43+
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
44+
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 19m
45+
```
46+
47+
## Managing the EKS Cluster with Ansible
48+
49+
TODO.
50+
51+
## Delete the cluster and resources
52+
53+
After you're finished testing the cluster, run the `delete.yml` playbook:
54+
55+
$ ansible-playbook -i inventory delete.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
AWSTemplateFormatVersion: '2010-09-09'
3+
Description: 'EKS Cluster definition.'
4+
5+
Parameters:
6+
7+
VpcId:
8+
Type: String
9+
Description: VPC ID.
10+
11+
Subnets:
12+
Type: CommaDelimitedList
13+
Description: List of subnets in the VPC.
14+
15+
ClusterName:
16+
Type: String
17+
Description: EKS Kubernetes cluster name.
18+
19+
KubernetesVersion:
20+
Type: String
21+
Description: EKS Kubernetes cluster version.
22+
23+
Resources:
24+
25+
ClusterRole:
26+
Description: Allows EKS to manage clusters on your behalf.
27+
Type: AWS::IAM::Role
28+
Properties:
29+
AssumeRolePolicyDocument:
30+
Version: 2012-10-17
31+
Statement:
32+
Effect: Allow
33+
Principal:
34+
Service:
35+
- eks.amazonaws.com
36+
Action: sts:AssumeRole
37+
ManagedPolicyArns:
38+
- arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
39+
- arn:aws:iam::aws:policy/AmazonEKSServicePolicy
40+
41+
ClusterControlPlaneSecurityGroup:
42+
Type: AWS::EC2::SecurityGroup
43+
Properties:
44+
GroupDescription: Cluster communication with worker nodes.
45+
VpcId: !Ref VpcId
46+
47+
Cluster:
48+
Type: "AWS::EKS::Cluster"
49+
Properties:
50+
Name: !Ref ClusterName
51+
Version: !Ref KubernetesVersion
52+
RoleArn: !GetAtt ClusterRole.Arn
53+
ResourcesVpcConfig:
54+
SecurityGroupIds:
55+
- !Ref ClusterControlPlaneSecurityGroup
56+
SubnetIds: !Ref Subnets
57+
58+
Outputs:
59+
60+
ClusterName:
61+
Value: !Ref ClusterName
62+
Description: Cluster Name
63+
Export:
64+
Name:
65+
Fn::Sub: "${AWS::StackName}-ClusterName"
66+
67+
ClusterArn:
68+
Value: !GetAtt Cluster.Arn
69+
Description: Cluster Arn
70+
Export:
71+
Name:
72+
Fn::Sub: "${AWS::StackName}-ClusterArn"
73+
74+
ClusterEndpoint:
75+
Value: !GetAtt Cluster.Endpoint
76+
Description: Cluster Endpoint
77+
Export:
78+
Name:
79+
Fn::Sub: "${AWS::StackName}-ClusterEndpoint"
80+
81+
ClusterControlPlaneSecurityGroup:
82+
Value: !Ref ClusterControlPlaneSecurityGroup
83+
Description: ClusterControlPlaneSecurityGroup
84+
Export:
85+
Name:
86+
Fn::Sub: "${AWS::StackName}-ClusterControlPlaneSecurityGroup"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
AWSTemplateFormatVersion: "2010-09-09"
2+
Description: 'EKS Nodegroup definition.'
3+
4+
Parameters:
5+
6+
ClusterName:
7+
Type: String
8+
Description: The EKS cluster name.
9+
10+
NodeGroupName:
11+
Type: String
12+
Description: Unique identifier for the Node Group.
13+
14+
NodeInstanceType:
15+
Type: String
16+
Default: t3.medium
17+
Description: EC2 instance type for the node instances.
18+
19+
NodeGroupDesiredCapacity:
20+
Type: Number
21+
Default: 3
22+
Description: Desired capacity of Node Group ASG.
23+
24+
Subnets:
25+
Type: "List<AWS::EC2::Subnet::Id>"
26+
Description: The subnets where workers can be created.
27+
28+
VpcId:
29+
Type: "AWS::EC2::VPC::Id"
30+
Description: The VPC of the worker instances.
31+
32+
Resources:
33+
34+
NodeInstanceRole:
35+
Type: "AWS::IAM::Role"
36+
Properties:
37+
AssumeRolePolicyDocument:
38+
Version: "2012-10-17"
39+
Statement:
40+
- Effect: Allow
41+
Principal:
42+
Service:
43+
- ec2.amazonaws.com
44+
Action:
45+
- "sts:AssumeRole"
46+
ManagedPolicyArns:
47+
- "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
48+
- "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
49+
- "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
50+
Path: /
51+
52+
NodeGroup:
53+
Type: 'AWS::EKS::Nodegroup'
54+
Properties:
55+
NodegroupName: !Ref NodeGroupName
56+
ClusterName: !Ref ClusterName
57+
NodeRole: !GetAtt NodeInstanceRole.Arn
58+
InstanceTypes:
59+
- !Ref NodeInstanceType
60+
ScalingConfig:
61+
MinSize: 2
62+
DesiredSize: !Ref NodeGroupDesiredCapacity
63+
MaxSize: 5
64+
Subnets: !Ref Subnets
+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Description: Configure networking and a VPC for an EKS cluster.
3+
4+
Parameters:
5+
6+
Region:
7+
Type: String
8+
Default: us-east-1
9+
Description: AWS Region for the VPC.
10+
11+
Resources:
12+
13+
Subnet1a:
14+
Type: AWS::EC2::Subnet
15+
Properties:
16+
VpcId: !Ref VPC
17+
AvailabilityZone:
18+
Fn::Sub: '${Region}a'
19+
CidrBlock: 172.16.0.0/18
20+
Tags:
21+
- Key: Name
22+
Value: eks-example-a
23+
24+
Subnet1aRouteTableAssociation:
25+
Type: AWS::EC2::SubnetRouteTableAssociation
26+
Properties:
27+
SubnetId: !Ref Subnet1a
28+
RouteTableId: !Ref RouteTable
29+
30+
Subnet1aNetworkAclAssociation:
31+
Type: AWS::EC2::SubnetNetworkAclAssociation
32+
Properties:
33+
SubnetId: !Ref Subnet1a
34+
NetworkAclId: !Ref NetworkAcl
35+
DependsOn: NetworkAcl
36+
37+
Subnet1b:
38+
Type: AWS::EC2::Subnet
39+
Properties:
40+
VpcId: !Ref VPC
41+
AvailabilityZone:
42+
Fn::Sub: '${Region}b'
43+
CidrBlock: 172.16.64.0/18
44+
Tags:
45+
- Key: Name
46+
Value: eks-example-b
47+
48+
Subnet1bRouteTableAssociation:
49+
Type: AWS::EC2::SubnetRouteTableAssociation
50+
Properties:
51+
SubnetId: !Ref Subnet1b
52+
RouteTableId: !Ref RouteTable
53+
54+
Subnet1bNetworkAclAssociation:
55+
Type: AWS::EC2::SubnetNetworkAclAssociation
56+
Properties:
57+
SubnetId: !Ref Subnet1b
58+
NetworkAclId: !Ref NetworkAcl
59+
DependsOn: NetworkAcl
60+
61+
Subnet1c:
62+
Type: AWS::EC2::Subnet
63+
Properties:
64+
VpcId: !Ref VPC
65+
AvailabilityZone:
66+
Fn::Sub: '${Region}c'
67+
CidrBlock: 172.16.128.0/18
68+
Tags:
69+
- Key: Name
70+
Value: eks-example-c
71+
72+
Subnet1cRouteTableAssociation:
73+
Type: AWS::EC2::SubnetRouteTableAssociation
74+
Properties:
75+
SubnetId: !Ref Subnet1c
76+
RouteTableId: !Ref RouteTable
77+
78+
Subnet1cNetworkAclAssociation:
79+
Type: AWS::EC2::SubnetNetworkAclAssociation
80+
Properties:
81+
SubnetId: !Ref Subnet1c
82+
NetworkAclId: !Ref NetworkAcl
83+
DependsOn: NetworkAcl
84+
85+
VPC:
86+
Type: AWS::EC2::VPC
87+
Properties:
88+
CidrBlock: 172.16.0.0/16
89+
EnableDnsSupport: 'true'
90+
EnableDnsHostnames: 'true'
91+
Tags:
92+
- Key: Name
93+
Value: eks-example
94+
95+
InternetGateway:
96+
Type: AWS::EC2::InternetGateway
97+
Properties:
98+
Tags:
99+
- Key: Name
100+
Value: eks-example
101+
102+
AttachGateway:
103+
Type: AWS::EC2::VPCGatewayAttachment
104+
Properties:
105+
VpcId: !Ref VPC
106+
InternetGatewayId: !Ref InternetGateway
107+
108+
RouteTable:
109+
Type: AWS::EC2::RouteTable
110+
Properties:
111+
VpcId: !Ref VPC
112+
Tags:
113+
- Key: Name
114+
Value: eks-example
115+
116+
Route:
117+
Type: AWS::EC2::Route
118+
Properties:
119+
RouteTableId: !Ref RouteTable
120+
DestinationCidrBlock: 0.0.0.0/0
121+
GatewayId: !Ref InternetGateway
122+
DependsOn: AttachGateway
123+
124+
NetworkAcl:
125+
Type: AWS::EC2::NetworkAcl
126+
Properties:
127+
VpcId: !Ref VPC
128+
Tags:
129+
- Key: Name
130+
Value: eks-example
131+
132+
InboundNetworkAclEntrySSH:
133+
Type: AWS::EC2::NetworkAclEntry
134+
Properties:
135+
NetworkAclId: !Ref NetworkAcl
136+
RuleNumber: '100'
137+
RuleAction: allow
138+
Protocol: '-1'
139+
Egress: 'false'
140+
CidrBlock: 0.0.0.0/0
141+
PortRange:
142+
From: '22'
143+
To: '22'
144+
DependsOn: NetworkAcl
145+
146+
OutboundNetworkAclEntryAll:
147+
Type: AWS::EC2::NetworkAclEntry
148+
Properties:
149+
NetworkAclId: !Ref NetworkAcl
150+
RuleNumber: '101'
151+
RuleAction: allow
152+
Protocol: '-1'
153+
Egress: 'true'
154+
CidrBlock: 0.0.0.0/0
155+
PortRange:
156+
From: '0'
157+
To: '65535'
158+
DependsOn: NetworkAcl
159+
160+
Outputs:
161+
162+
VpcId:
163+
Description: VPC id
164+
Value: !Ref VPC
165+
166+
AvailabilityZones:
167+
Description: List of Availability Zones available in the VPC
168+
Value: us-east-1a,us-east-1b,us-east-1c
169+
170+
Subnets:
171+
Description: List of Subnets in the VPC
172+
Value:
173+
Fn::Sub: '${Subnet1a},${Subnet1b},${Subnet1c}'

0 commit comments

Comments
 (0)