Skip to content

Commit

Permalink
Bottlerocket OS nodegroup module added
Browse files Browse the repository at this point in the history
  • Loading branch information
vara-bonthu committed Apr 18, 2021
1 parent e98ee53 commit 4a47c5e
Show file tree
Hide file tree
Showing 10 changed files with 440 additions and 29 deletions.
64 changes: 44 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,33 @@ EKS Terraform accelerator module helps you to provision **EKS clusters**, **Mana
This folder contains `backend.conf` and `base.tfvars` which are used to create a unique Terraform state for each cluster environment.
Terraform backend configuration can be updated in `backend.conf` and cluster common configuration variables in `base.tfvars`

* **source** folder contains main driver file `main.tf`
* **modules** folder contains all the AWS resource modules
* **helm** folder contains all the Helm chart modules
* **examples** folder contains sample template files with `base.tfvars` which can be used to deploy clusters with multiple add-on options
* `source` folder contains main driver file `main.tf`
* `modules` folder contains all the AWS resource modules
* `helm` folder contains all the Helm chart modules
* `examples` folder contains sample template files with `base.tfvars` which can be used to deploy clusters with multiple add-on options

# EKS Cluster Deployment Options
This module helps you to provision the following EKS resources

1. VPC, Subnets(Public and Private) and VPC endpoints for fully private EKS Clusters (Optional)
2. EKS Cluster with multiple networking options
2.1 Fully private EKS Cluster
2.2 Public + Private EKS Cluster
2.3 Public Cluster
3. AWS Managed Node Groups with on-demand and Spot instances, self-managed node groups and Fargate profiles
4. AWS Managed node groups with launch templates
5. AWS SSM agent deployed through launch templates
6. RBAC for Developers and Administrators with IAM roles
7. Kubernetes Addons using Helm Charts
8. Metrics Server
9. Cluster Autoscaler
10. AWS LB Ingress Controller
11. Traefik Ingress Controller
12. FluentBit to Cloudwatch for Managed Node groups
13. FluentBit to Cloudwatch for Fargate Containers
1. [VPC and Subnets(Public and Private)](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html)
2. [VPC endpoints for fully private EKS Clusters](https://docs.aws.amazon.com/eks/latest/userguide/private-clusters.html)
3. [EKS Cluster with multiple networking options](https://aws.amazon.com/blogs/containers/de-mystifying-cluster-networking-for-amazon-eks-worker-nodes/)
1. Fully Private EKS Cluster
2. Public + Private EKS Cluster
3. Public Cluster
4. [Managed Node Groups with On-Demand](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) - AWS Managed Node Groups with On-Demand Instances
5. [Managed Node Groups with Spot](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) - AWS Managed Node Groups with Spot Instances
6. [Fargate Profiles](https://docs.aws.amazon.com/eks/latest/userguide/fargate-profile.html)
7. [SSM agent](https://aws.amazon.com/blogs/containers/introducing-launch-template-and-custom-ami-support-in-amazon-eks-managed-node-groups/) deployed through launch templates to Managed Node Groups
8. [Bottlerocket OS](https://github.com/bottlerocket-os/bottlerocket) - Managed Node Groups with Bottlerocket OS and Launch Templates
9. [RBAC](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html) for Developers and Administrators with IAM roles
10. Kubernetes Addons using [Helm Charts](https://helm.sh/docs/topics/charts/)
11. [Metrics Server](https://github.com/kubernetes-sigs/metrics-server)
12. [Cluster Autoscaler](https://github.com/kubernetes/autoscaler)
13. [AWS LB Ingress Controller](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html)
14. [Traefik Ingress Controller](https://doc.traefik.io/traefik/providers/kubernetes-ingress/)
15. [FluentBit to Cloudwatch for Managed Node groups](https://github.com/aws/aws-for-fluent-bit)
16. [FluentBit to Cloudwatch for Fargate Containers](https://aws.amazon.com/blogs/containers/fluent-bit-for-amazon-eks-on-aws-fargate-is-here/)

# Helm Charts Modules
Helm Chart Module within this framework allows you to deploy kubernetes apps using Terraform helm chart provider with **enabled** conditional parameter in `base.tfvars`.
Expand Down Expand Up @@ -85,6 +88,27 @@ This modules ships the Fargate Continaer logs to CloudWatch

`fargate_fluent_bit_enable = true`

# Bottlerocket OS

Bottlerocket is an open source operating system specifically designed for running containers. Bottlerocket build system is based on Rust. It's a container host OS and doesn't have additional softwares or package managers other than what is needed for running contianers hence its very light weight and secure. Container optimized operating systems are ideal when you need to run applications in Kubernetes with minimal setup and do not want to worry about security or updates, or want OS support from cloud provider. Container operating systems does updates transactionally.

Bottlerocket has two contianer runtimes running. Control container **on** by default used for AWS Systems manager and remote API access. Admin container **off** by default for deep debugging and exploration.

Bottlerocket [Launch templates userdata](modules/launch-templates/templates/bottlerocket-userdata.sh.tpl) uses the TOML format with Key-value pairs. Remote API access API via SSM agent. You can launch trouble shooting continaer via user data `[settings.host-containers.admin] enabled = true`.

### Features
* [Secure](https://github.com/bottlerocket-os/bottlerocket/blob/develop/SECURITY_FEATURES.md) - Opninionated, specialized and highly secured
* **Flexible** - Multi cloud and multi orchestrator
* **Transactional** - Image basesd upgraded and roll backs
* **Isolated** - Seprate Contianer Runtimes

### Updates
Bottlerocket can be updated automatically via Kubernetes Operator

$ kubectl apply -f Bottlerocket_k8s.csv.yaml
$ kubectl get ClusterServiceVersion Bottlerocket_k8s | jq.'status'


# How to Deploy

## Pre-requisites:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: MIT-0
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#---------------------------------------------------------#
# EKS CLUSTER CORE VARIABLES
#---------------------------------------------------------#
#Following fields used in tagging resources and building the name of the cluster
#e.g., eks cluster name will be {tenant}-{environment}-{zone}-{resource}
#---------------------------------------------------------#
org = "aws" # Organization Name. Used to tag resources
tenant = "aws001" # AWS account name or unique id for tenant
environment = "preprod" # Environment area eg., preprod or prod
zone = "dev" # Environment with in one sub_tenant or business unit
terraform_version = "Terraform v0.14.9"
#---------------------------------------------------------#
# VPC and PRIVATE SUBNET DETAILS for EKS Cluster
#---------------------------------------------------------#
#This provides two options Option1 and Option2. You should choose either of one to provide VPC details to the EKS cluster
#Option1: Creates a new VPC, private Subnets and VPC Endpoints by taking the inputs of vpc_cidr_block and private_subnets_cidr. VPC Endpoints are S3, SSM , EC2, ECR API, ECR DKR, KMS, CloudWatch Logs, STS, Elastic Load Balancing, Autoscaling
#Option2: Provide an existing vpc_id and private_subnet_ids

#---------------------------------------------------------#
# OPTION 1
#---------------------------------------------------------#
create_vpc = true
vpc_cidr_block = "10.1.0.0/18"
private_subnets_cidr = ["10.1.0.0/22", "10.1.4.0/22", "10.1.8.0/22"]
enable_public_subnets = true
public_subnets_cidr = ["10.1.12.0/22", "10.1.16.0/22", "10.1.20.0/22"]

#---------------------------------------------------------#
# OPTION 2
#---------------------------------------------------------#
//create_vpc = false
//vpc_id = "xxxxxx"
//private_subnet_ids = ['xxxxxx','xxxxxx','xxxxxx']

#---------------------------------------------------------#
# EKS CONTROL PLANE VARIABLES
#---------------------------------------------------------#
kubernetes_version = "1.19"
endpoint_private_access = true
endpoint_public_access = true
enable_irsa = true

enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
cluster_log_retention_period = 7

#---------------------------------------------------------#
# MANAGED WORKER NODE INPUT VARIABLES FOR ON DEMAND INSTANCES - Worker Group1
#---------------------------------------------------------#
on_demand_node_group_name = "mg-m5-on-demand"
on_demand_ami_type = "AL2_x86_64"
on_demand_disk_size = 50
on_demand_instance_type = ["m5.xlarge"]
on_demand_desired_size = 3
on_demand_max_size = 3
on_demand_min_size = 3

#---------------------------------------------------------#
# BOTTLEROCKET - Worker Group3
#---------------------------------------------------------#
# Amazon EKS optimized Bottlerocket AMI ID for a region and Kubernetes version.
bottlerocket_node_group_name = "mg-m5-bottlerocket"
bottlerocket_ami = "ami-0326716ad575410ab"
bottlerocket_disk_size = 50
bottlerocket_instance_type = ["m5.large"]
bottlerocket_desired_size = 3
bottlerocket_max_size = 3
bottlerocket_min_size = 3
#---------------------------------------------------------#
# MANAGED WORKER NODE INPUT VARIABLES FOR SPOT INSTANCES - Worker Group2
#---------------------------------------------------------#
spot_node_group_name = "mg-m5-spot"
spot_instance_type = ["m5.large", "m5a.large"]
spot_ami_type = "AL2_x86_64"
spot_desired_size = 3
spot_max_size = 6
spot_min_size = 3

#---------------------------------------------------------#
# Creates a Fargate profile for default namespace
#---------------------------------------------------------#
fargate_profile_namespace = "default"

#---------------------------------------------------------#
# ENABLE HELM MODULES
# Please note that you may need to download the docker images for each
# helm module and push it to ECR if you create fully private EKS Clusters with no access to internet to fetch docker images.
# README with instructions available in each HELM module under helm/
#---------------------------------------------------------#
# Enable this if worker Node groups has access to internet to download the docker images

public_docker_repo = true

#---------------------------------------------------------#
# ENABLE METRICS SERVER
#---------------------------------------------------------#
metrics_server_enable = true

#---------------------------------------------------------#
# ENABLE CLUSTER AUTOSCALER
#---------------------------------------------------------#
cluster_autoscaler_enable = true


//---------------------------------------------------------//
// ENABLE ALB INGRESS CONTROLLER
//---------------------------------------------------------//
lb_ingress_controller_enable = true

#---------------------------------------------------------#
# ENABLE AWS_FLUENT-BIT
#---------------------------------------------------------#
aws_for_fluent_bit_enable = true
fargate_fluent_bit_enable = true

ekslog_retention_in_days = 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bottlerocket-app1-nginx-deployment
labels:
app: bottlerocket-app1-nginx
WorkerType: ON_DEMAND_BOTTLEROCKET
spec:
replicas: 2
selector:
matchLabels:
app: bottlerocket-app1-nginx
template:
metadata:
labels:
app: bottlerocket-app1-nginx
WorkerType: ON_DEMAND_BOTTLEROCKET
spec:
containers:
- name: app1-nginx
image: stacksimplify/kube-nginxapp1:1.0.0
# image: 958351136353.dkr.ecr.eu-west-1.amazonaws.com/stacksimplify/kube-nginxapp:1.0.0
ports:
- containerPort: 80
nodeSelector:
WorkerType: ON_DEMAND_BOTTLEROCKET
---
apiVersion: v1
kind: Service
metadata:
name: bottlerocket-app1-nginx-nodeport-service
labels:
app: bottlerocket-app1-nginx
WorkerType: ON_DEMAND_BOTTLEROCKET
annotations:
#Important Note: Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer
alb.ingress.kubernetes.io/healthcheck-path: /app1/index.html
spec:
type: NodePort
selector:
app: bottlerocket-app1-nginx
WorkerType: ON_DEMAND_BOTTLEROCKET
ports:
- port: 80
targetPort: 80
---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx-path-based
labels:
app: ingress-nginx-path-based
annotations:
# Ingress Core Settings
kubernetes.io/ingress.class: "alb"
alb.ingress.kubernetes.io/scheme: internet-facing
# Health Check Settings
alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
alb.ingress.kubernetes.io/healthcheck-port: traffic-port
#Important Note: Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer
#alb.ingress.kubernetes.io/healthcheck-path: /usermgmt/health-status
alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
alb.ingress.kubernetes.io/success-codes: '200'
alb.ingress.kubernetes.io/healthy-threshold-count: '2'
alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
# This is required for bottlerocket
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- http:
paths:
- path: /app1/*
pathType: Prefix
backend:
service:
name: bottlerocket-app1-nginx-nodeport-service
port:
number: 80
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

# This service can be accessed using NLB DNS e.g., http://<NLB DNS name>>:8000/bottlerocket-greeting
---
apiVersion: v1
kind: Service
metadata:
name: bottlerocket-greeting-service
namespace: default
spec:
selector:
app: bottlerocket-greeting-pod
ports:
- name: web
port: 8000
targetPort: 8080
#type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bottlerocket-greeting
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: bottlerocket-greeting-pod
template:
metadata:
labels:
app: bottlerocket-greeting-pod
spec:
containers:
- name: bottlerocket-greeting-pod
# NOTE: If you are deploying this to private cluster without Internet access then pull the docker image locally and push it to ECR. refer ECR image location below
# image: 439595162109.dkr.ecr.eu-west-1.amazonaws.com/bottlerocket-greeting:latest
image: pahud/greeting
ports:
- containerPort: 8080
nodeSelector:
WorkerType: ON_DEMAND_BOTTLEROCKET

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bottlerocket-greeting-ingress
namespace: default
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.pathmatcher: PathPrefix
spec:
rules:
- http:
paths:
- path: "/bottlerocket-greeting"
pathType: Prefix
backend:
service:
name: bottlerocket-greeting-service
port:
number: 8000

15 changes: 11 additions & 4 deletions live/preprod/eu-west-1/application/dev/base.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ on_demand_desired_size = 3
on_demand_max_size = 3
on_demand_min_size = 3

#---------------------------------------------------------#
# BOTTLEROCKET - Worker Group3
#---------------------------------------------------------#
# Amazon EKS optimized Bottlerocket AMI ID for a region and Kubernetes version.
bottlerocket_node_group_name = "mg-m5-bottlerocket"
bottlerocket_ami = "ami-0326716ad575410ab"
bottlerocket_disk_size = 50
bottlerocket_instance_type = ["m5.large"]
bottlerocket_desired_size = 3
bottlerocket_max_size = 3
bottlerocket_min_size = 3
#---------------------------------------------------------#
# MANAGED WORKER NODE INPUT VARIABLES FOR SPOT INSTANCES - Worker Group2
#---------------------------------------------------------#
Expand Down Expand Up @@ -120,7 +131,3 @@ aws_for_fluent_bit_enable = true
fargate_fluent_bit_enable = true

ekslog_retention_in_days = 1




Loading

0 comments on commit 4a47c5e

Please sign in to comment.