A custom-build terraform module, leveraging terraform-aws-eks to create a managed Kubernetes cluster on AWS EKS. In addition to provisioning simply an EKS cluster, this module alongside additional components to complete an entire end-to-end base stack for a functional kubernetes cluster for development and production level environments, including a base set of software that can/should be commonly used across all clusters. Primary integrated sub-modules include:
- You want to create an EKS cluster and an autoscaling group of workers for the cluster.
- You want these resources to exist within security groups that allow communication and coordination.
- You want to generate an accompanying Virtual Private Cloud (VPC) and subnets where the EKS resources will reside. The VPC satisfies EKS requirements.
- You want specific security provisions in place, including the use of private subnets for all nodes.
- The base ingress controller to be used is Nginx-Ingress Controller with internet-facing AWS network load balancers instead of being controlled by more reactive AWS Application Load Balancers.
The cluster_version
is the required variable. Kubernetes is evolving a lot, and each major version includes new features, fixes, or changes.
Always check Kubernetes Release Notes before updating the major version.
You also need to ensure your applications and add ons are updated, or workloads could fail after the upgrade is complete. For action, you may need to take before upgrading, see the steps in the EKS documentation.
An example of harming update was the removal of several commonly used, but deprecated APIs, in Kubernetes 1.16. More information on the API removals, see the Kubernetes blog post.
For windows users, please read the following doc.
- Once AWS Credentials (see notes below) are set up on your local machine, it is recommended to follow docker-compose command in order to initialise terraform state within the context of Gitlab. However, you can also manage terraform state in other ways. An example of initialising terraform with a gitlab-managed state is shown here:
export TF_ADDRESS=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${TF_VAR_app_name}-${TF_VAR_app_namespace}-${TF_VAR_tfenv} && \
terraform init \
-backend-config="address=${TF_ADDRESS}" \
-backend-config="lock_address=${TF_ADDRESS}/lock" \
-backend-config="unlock_address=${TF_ADDRESS}/lock" \
-backend-config="username=${TF_VAR_gitlab_username}" \
-backend-config="password=${TF_VAR_gitlab_token}" \
-backend-config="lock_method=POST" \
-backend-config="unlock_method=DELETE" \
-backend-config="retry_wait_min=5"
terraform plan
terraform apply
terraform destroy
- Autoscaling: How to enable worker node autoscaling.
- Enable Docker Bridge Network: How to enable the docker bridge network when using the EKS-optimized AMI, which disables it by default.
- Spot instances: How to use spot instances with this module.
- IAM Permissions: Minimum IAM permissions needed to setup EKS Cluster.
- FAQ: Frequently Asked Questions
Code formatting and documentation for variables and outputs is generated using pre-commit-terraform hooks which uses terraform-docs.
Follow these instructions to install pre-commit locally.
And install terraform-docs
with go get github.com/segmentio/terraform-docs
or brew install terraform-docs
.
Report issues/questions/feature requests on in the issues section.
Full contributing guidelines are covered here.
- The changelog captures all important release notes from 1.1.17
Created by Aaron Baideme - [email protected]
Supported by Ronel Cartas - [email protected]
MIT Licensed. See LICENSE for full details.
Name | Version |
---|---|
terraform | >= 1.1 |
aws | ~> 4.5 |
gitlab | ~> 3.4 |
helm | ~> 2.0 |
kubectl | ~> 1.14.0 |
kubernetes | ~> 2.11.0 |
Name | Version |
---|---|
aws | ~> 4.5 |
aws.secondary | ~> 4.5 |
kubectl | ~> 1.14.0 |
kubernetes | ~> 2.11.0 |
local | n/a |
random | n/a |
Name | Source | Version |
---|---|---|
argocd | ./provisioning/kubernetes/argocd | n/a |
aws-cluster-autoscaler | ./aws-cluster-autoscaler | n/a |
aws-support | ./aws-support | n/a |
certmanager | ./provisioning/kubernetes/certmanager | n/a |
consul | ./provisioning/kubernetes/hashicorp-consul | n/a |
eks | terraform-aws-modules/eks/aws | ~> 18.23.0 |
eks-vpc | terraform-aws-modules/vpc/aws | ~> 3.14 |
eks-vpc-endpoints | terraform-aws-modules/vpc/aws//modules/vpc-endpoints | ~> 3.14 |
eks_managed_node_group | terraform-aws-modules/eks/aws//modules/eks-managed-node-group | ~> 18.23.0 |
elastic-stack | ./provisioning/kubernetes/elastic-stack | n/a |
gitlab-k8s-agent | ./provisioning/kubernetes/gitlab-kubernetes-agent | n/a |
kubernetes-dashboard | ./provisioning/kubernetes/kubernetes-dashboard | n/a |
metrics-server | ./provisioning/kubernetes/metrics-server | n/a |
monitoring-stack | ./provisioning/kubernetes/monitoring | n/a |
nginx-controller-ingress | ./provisioning/kubernetes/nginx-controller | n/a |
stakater-reloader | ./provisioning/kubernetes/stakater-reloader | n/a |
subnet_addrs | hashicorp/subnets/cidr | 1.0.0 |
vault | ./provisioning/kubernetes/hashicorp-vault | n/a |
vault-operator | ./provisioning/kubernetes/bonzai-vault-operator | n/a |
vault-secrets-webhook | ./provisioning/kubernetes/bonzai-vault-secrets-webhook | n/a |
Name | Type |
---|---|
aws_iam_policy.node_additional | resource |
aws_iam_role_policy_attachment.additional | resource |
aws_kms_alias.eks | resource |
aws_kms_key.eks | resource |
aws_kms_replica_key.eks | resource |
aws_route53_zone.hosted_zone | resource |
aws_vpc_endpoint.rds | resource |
kubectl_manifest.aws-auth | resource |
kubernetes_namespace.cluster | resource |
kubernetes_secret.regcred | resource |
random_integer.cidr_vpc | resource |
aws_availability_zones.available_azs | data source |
aws_caller_identity.current | data source |
aws_eks_cluster.cluster | data source |
aws_eks_cluster_auth.cluster | data source |
aws_ssm_parameter.regcred_password | data source |
aws_ssm_parameter.regcred_username | data source |
local_file.infrastructure-terraform-eks-version | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
app_name | Application Name | string |
"eks" |
no |
app_namespace | Tagged App Namespace | any |
n/a | yes |
autoscaling_configuration | n/a | object({ |
{ |
no |
aws_installations | AWS Support Components including Cluster Autoscaler, EBS/EFS Storage Classes, etc. | object({ |
{ |
no |
aws_profile | AWS Profile | string |
"" |
no |
aws_region | AWS Region for all primary configurations | any |
n/a | yes |
aws_secondary_region | Secondary Region for certain redundant AWS components | any |
n/a | yes |
billingcustomer | Which Billingcustomer, aka Cost Center, is responsible for this infra provisioning | any |
n/a | yes |
cluster_addons | An add-on is software that provides supporting operational capabilities to Kubernetes applications, but is not specific to the application: coredns, kube-proxy, vpc-cni | any |
{ |
no |
cluster_endpoint_public_access_cidrs | If the cluster endpoint is to be exposed to the public internet, specify CIDRs here that it should be restricted to | list(string) |
[] |
no |
cluster_name | Optional override for cluster name instead of standard {name}-{namespace}-{env} | string |
"" |
no |
cluster_root_domain | Domain root where all kubernetes systems are orchestrating control | object({ |
n/a | yes |
cluster_version | Kubernetes Cluster Version | string |
"1.21" |
no |
create_launch_template | enable launch template on node group | bool |
false |
no |
custom_aws_s3_support_infra | Adding the ability to provision additional support infrastructure required for certain EKS Helm chart/App-of-App Components | list(object({ |
[] |
no |
custom_namespaces | Adding namespaces to a default cluster provisioning process | list(string) |
[] |
no |
default_ami_type | Default AMI used for node provisioning | string |
"AL2_x86_64" |
no |
default_capacity_type | Default capacity configuraiton used for node provisioning. Valid values: ON_DEMAND, SPOT |
string |
"ON_DEMAND" |
no |
eks_managed_node_groups | Override default 'single nodegroup, on a private subnet' with more advaned configuration archetypes | any |
[] |
no |
elastic_ip_custom_configuration | By default, this module will provision new Elastic IPs for the VPC's NAT Gateways; however, one can also override and specify separate, pre-existing elastic IPs as needed in order to preserve IPs that are whitelisted; reminder that the list of EIPs should have the same count as nat gateways created. | object({ |
{ |
no |
gitlab_kubernetes_agent_config | Configuration for Gitlab Kubernetes Agent | object({ |
{ |
no |
google_authDomain | Used for Infrastructure OAuth: Google Auth Domain | any |
n/a | yes |
google_clientID | Used for Infrastructure OAuth: Google Auth Client ID | any |
n/a | yes |
google_clientSecret | Used for Infrastructure OAuth: Google Auth Client Secret | any |
n/a | yes |
helm_configurations | n/a | object({ |
{ |
no |
helm_installations | n/a | object({ |
{ |
no |
instance_desired_size | Count of instances to be spun up within the context of a kubernetes cluster. Minimum: 2 | number |
2 |
no |
instance_max_size | Count of instances to be spun up within the context of a kubernetes cluster. Minimum: 2 | number |
4 |
no |
instance_min_size | Count of instances to be spun up within the context of a kubernetes cluster. Minimum: 2 | number |
1 |
no |
instance_type | AWS Instance Type for provisioning | string |
"c5a.medium" |
no |
ipv6 | n/a | object({ |
{ |
no |
map_accounts | Additional AWS account numbers to add to the aws-auth configmap. | list(string) |
[] |
no |
map_roles | Additional IAM roles to add to the aws-auth configmap. | list(object({ |
[] |
no |
map_users | Additional IAM users to add to the aws-auth configmap. | list(object({ |
[] |
no |
nat_gateway_custom_configuration | Override the default NAT Gateway configuration, which configures a single NAT gateway for non-prod, while one per AZ on tfenv=prod | object({ |
{ |
no |
node_key_name | EKS Node Key Name | string |
"" |
no |
node_public_ip | assign public ip on the nodes | bool |
false |
no |
operator_domain_name | Domain root of operator cluster | string |
"" |
no |
registry_credentials | Create list of registry credential for different namespaces, username and password are fetched from AWS parameter store | list(object({ |
[] |
no |
root_vol_size | Root Volume Size | string |
"50" |
no |
tech_email | Tech Contact E-Mail for services such as LetsEncrypt | any |
n/a | yes |
tfenv | Environment | any |
n/a | yes |
vpc_flow_logs | Manually enable or disable VPC flow logs; Please note, for production, these are enabled by default otherwise they will be disabled; setting a value for this object will override all defaults regardless of environment | object({ |
{} |
no |
vpc_subnet_configuration | Configure VPC CIDR and relative subnet intervals for generating a VPC. If not specified, default values will be generated. | object({ |
{ |
no |
Name | Description |
---|---|
aws_profile | n/a |
aws_region | # ----------- ## Region and AWS Profile Checks # ----------- |
base_cidr_block | n/a |
eks_managed_node_groups | n/a |
kubernetes-cluster-auth | n/a |
kubernetes-cluster-certificate-authority-data | # ----------- # MODULE: EKS # ----------- |
kubernetes-cluster-endpoint | n/a |
kubernetes-cluster-id | n/a |
private_route_table_ids | n/a |
private_subnet_ids | n/a |
private_subnets_cidr_blocks | n/a |
public_subnet_ids | n/a |
public_subnets_cidr_blocks | n/a |
vpc_id | # ----------- # MODULE: VPC # ----------- |