Skip to content

Commit

Permalink
add eks node group module with examples
Browse files Browse the repository at this point in the history
  • Loading branch information
marcincuber committed Jan 24, 2020
1 parent 0701041 commit 6ef8cf3
Show file tree
Hide file tree
Showing 9 changed files with 642 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.DS_Store
errored.tfstate
.terraform
crash.log
terraform.tfstate
*.tfstate*
terraform.tfvars
11 changes: 11 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
38 changes: 38 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
ifneq (,)
.error This Makefile requires GNU Make.
endif

.PHONY: gen _gen-main _update-tf-docs

CURRENT_DIR = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
TF_EXAMPLES = $(sort $(dir $(wildcard $(CURRENT_DIR)examples/*/)))
TF_DOCS_VERSION = 0.6.0

# Adjust your delimiter here or overwrite via make arguments
DELIM_START = <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
DELIM_CLOSE = <!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

gen: _update-tf-docs
@echo "################################################################################"
@echo "# Terraform-docs generate"
@echo "################################################################################"
@$(MAKE) --no-print-directory _gen-main

_gen-main:
@echo "------------------------------------------------------------"
@echo "# Main module"
@echo "------------------------------------------------------------"
@if docker run --rm \
-v $(CURRENT_DIR):/data \
-e DELIM_START='$(DELIM_START)' \
-e DELIM_CLOSE='$(DELIM_CLOSE)' \
cytopia/terraform-docs:$(TF_DOCS_VERSION) \
terraform-docs-replace-012 --sort-inputs-by-required --with-aggregate-type-defaults md README.md; then \
echo "OK"; \
else \
echo "Failed"; \
exit 1; \
fi

_update-tf-docs:
docker pull cytopia/terraform-docs:$(TF_DOCS_VERSION)
85 changes: 85 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,87 @@
# terraform-aws-eks-node-group
Terraform module to provision EKS Managed Node Group

## Resources created

This module will create EKS managed Node Group that will join your existing Kubernetes cluster.

## Terraform versions

Terraform 0.12. Pin module version to `~> v1.0`. Submit pull-requests to `master` branch.

## Usage

```hcl
module "eks-node-group" {
source = "umotif-public/eks-node-group/aws"
version = "~> 1.0"
cluster_name = aws_eks_cluster.cluster.id
subnet_ids = ["subnet-1","subnet-2","subnet-3"]
desired_size = 1
min_size = 1
max_size = 1
instance_types = ["t3.large"]
ec2_ssh_key = "eks-test"
kubernetes_labels = {
lifecycle = "OnDemand"
}
tags = {
Environment = "test"
}
}
```

## Assumptions

Module is to be used with Terraform > 0.12.

## Examples

* [EKS Node Group- single](https://github.com/umotif-public/terraform-aws-eks-node-group/tree/master/examples/single-node-group)
* [EKS Node Group- multiple az setup](https://github.com/umotif-public/terraform-aws-eks-node-group/tree/master/examples/multiaz-node-group)

## Authors

Module managed by [Marcin Cuber](https://github.com/marcincuber) [LinkedIn](https://www.linkedin.com/in/marcincuber/).

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| cluster\_name | The name of the EKS cluster | string | n/a | yes |
| desired\_size | Desired number of worker nodes | number | n/a | yes |
| max\_size | Maximum number of worker nodes | number | n/a | yes |
| min\_size | Minimum number of worker nodes | number | n/a | yes |
| subnet\_ids | A list of subnet IDs to launch resources in | list(string) | n/a | yes |
| ami\_release\_version | AMI version of the EKS Node Group. Defaults to latest version for Kubernetes version | string | `"null"` | no |
| ami\_type | Type of Amazon Machine Image (AMI) associated with the EKS Node Group. Defaults to `AL2_x86_64`. Valid values: `AL2_x86_64`, `AL2_x86_64_GPU`. Terraform will only perform drift detection if a configuration value is provided | string | `"AL2_x86_64"` | no |
| disk\_size | Disk size in GiB for worker nodes. Defaults to 20. Terraform will only perform drift detection if a configuration value is provided | number | `"20"` | no |
| ec2\_ssh\_key | SSH key name that should be used to access the worker nodes | string | `"null"` | no |
| instance\_types | Set of instance types associated with the EKS Node Group. Defaults to ["t3.medium"]. Terraform will only perform drift detection if a configuration value is provided | list(string) | `[ "t3.medium" ]` | no |
| kubernetes\_labels | Key-value mapping of Kubernetes labels. Only labels that are applied with the EKS API are managed by this argument. Other Kubernetes labels applied to the EKS Node Group will not be managed | map(string) | `{}` | no |
| kubernetes\_version | Kubernetes version. Defaults to EKS Cluster Kubernetes version. Terraform will only perform drift detection if a configuration value is provided | string | `"null"` | no |
| node\_role\_arn | IAM role arn that will be used by managed node group | string | `""` | no |
| source\_security\_group\_ids | Set of EC2 Security Group IDs to allow SSH access (port 22) from on the worker nodes. If you specify `ec2_ssh_key`, but do not specify this configuration when you create an EKS Node Group, port 22 on the worker nodes is opened to the Internet (0.0.0.0/0) | list(string) | `[]` | no |
| tags | A map of tags (key-value pairs) passed to resources. | map(string) | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| iam\_role\_arn | IAM role ARN used by node group. |
| iam\_role\_id | IAM role ID used by node group. |
| node\_group | Outputs from EKS node group. See `aws_eks_node_group` Terraform documentation for values |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## License

See LICENSE for full details.
201 changes: 201 additions & 0 deletions examples/multiaz-node-group/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
provider "aws" {
region = "eu-west-1"
}

#####
# VPC and subnets
#####
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "2.21.0"

name = "simple-vpc"

cidr = "10.0.0.0/16"

azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

private_subnet_tags = {
"kubernetes.io/role/internal-elb" = "1"
}

public_subnet_tags = {
"kubernetes.io/role/elb" = "1"
}

enable_dns_hostnames = true
enable_dns_support = true
enable_nat_gateway = true
enable_vpn_gateway = true
single_nat_gateway = true
one_nat_gateway_per_az = false

tags = {
"kubernetes.io/cluster/eks" = "shared",
Environment = "test"
}
}

#####
# EKS Cluster
#####

resource "aws_eks_cluster" "cluster" {
enabled_cluster_log_types = []
name = "eks"
role_arn = aws_iam_role.cluster.arn
version = "1.14"

vpc_config {
subnet_ids = flatten([module.vpc.public_subnets, module.vpc.private_subnets])
security_group_ids = []
endpoint_private_access = "true"
endpoint_public_access = "true"
}
}

resource "aws_iam_role" "cluster" {
name = "eks-cluster-role"

assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}

resource "aws_iam_role_policy_attachment" "cluster_AmazonEKSClusterPolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.cluster.name
}

resource "aws_iam_role_policy_attachment" "cluster_AmazonEKSServicePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy"
role = aws_iam_role.cluster.name
}

#####
# EKS Node Group per availability zone
# If you are running a stateful application across multiple Availability Zones that is backed by Amazon EBS volumes and using the Kubernetes Cluster Autoscaler,
# you should configure multiple node groups, each scoped to a single Availability Zone. In addition, you should enable the --balance-similar-node-groups feature.
#
# In this setup you can configure a single IAM Role that is attached to multiple node groups.
#####

resource "aws_iam_role" "main" {
name = "eks-managed-group-node-role"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow"
}
]
}
EOF
}

resource "aws_iam_role_policy_attachment" "main_AmazonEKSWorkerNodePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.main.name
}

resource "aws_iam_role_policy_attachment" "main_AmazonEKS_CNI_Policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.main.name
}

resource "aws_iam_role_policy_attachment" "main_AmazonEC2ContainerRegistryReadOnly" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.main.name
}

module "eks-node-group-a" {
source = "../../"

cluster_name = aws_eks_cluster.cluster.id
node_role_arn = aws_iam_role.main.arn
subnet_ids = [module.vpc.private_subnets[0]]

desired_size = 1
min_size = 1
max_size = 1

instance_types = ["t3.large"]

ec2_ssh_key = "eks-test"

kubernetes_labels = {
lifecycle = "OnDemand"
az = "eu-west-1a"
}

tags = {
Environment = "test"
}
}

module "eks-node-group-b" {
source = "../../"

cluster_name = aws_eks_cluster.cluster.id
node_role_arn = aws_iam_role.main.arn
subnet_ids = [module.vpc.private_subnets[1]]

desired_size = 1
min_size = 1
max_size = 1

instance_types = ["t2.large"]

ec2_ssh_key = "eks-test"

kubernetes_labels = {
lifecycle = "OnDemand"
az = "eu-west-1b"
}

tags = {
Environment = "test"
}
}

module "eks-node-group-c" {
source = "../../"

cluster_name = aws_eks_cluster.cluster.id
node_role_arn = aws_iam_role.main.arn
subnet_ids = [module.vpc.private_subnets[2]]

desired_size = 1
min_size = 1
max_size = 1

ec2_ssh_key = "eks-test"

kubernetes_labels = {
lifecycle = "OnDemand"
az = "eu-west-1c"
}

tags = {
Environment = "test"
}
}
Loading

0 comments on commit 6ef8cf3

Please sign in to comment.