This module is responsible for the EKS Control Plane in the EKS cluster topology. You must
launch worker nodes in order to be able to schedule pods on your cluster. See the eks-cluster-workers
module for managing EKS worker nodes.
How do you use this module?
See the root README for instructions on using Terraform modules.
You will need to install kubectl to follow the
instructions.
If you wish to use the automatic configuration, you will need
kubergrunt. Refer to the kubergrunt documentation for installation
instructions.
What is the EKS Control Plane?
The EKS Control Plane is a managed service entrirely managed by AWS. This contains the resources and endpoint to run and
access the Kubernetes master components.
The resources are deployed into your VPC so that they inherit the network rules you configure for your VPC.
Specifically, the control plane consists of:
etcd: A distributed key value store used by Kubernetes to hold the metadata and cluster
state.
kube-apiserver: Web service that exposes the Kubernetes API. This is the main entrypoint for interacting with the
Kubernetes cluster.
kube-scheduler: This component is responsible for watching for newly created Pods on the cluster, and scheduling
them on to the available worker nodes.
kube-controller-manager: This component is responsible for executing the controller logic. Controllers are
responsible for managing the Pods on the cluster. For example, you can use a
Deployment controller to ensure that a
specified number of replicas of a Pod is running on the cluster.
cloud-controller-manager: This component is responsible for managing cloud components that Kubernetes will manage.
This includes resources like the
LoadBalancers.
You can read more about the different components of EKS in the project README.
What security group rules are created?
This module will create a security group for the EKS cluster master nodes to allow them to function as a Kubernetes
cluster. The rules are based on the recommendations provided by
AWS for configuring an EKS cluster.
<a name="how-to-extend-security-group"></a>How do you add additional security group rules?
To add additional security group rules to the EKS cluster master nodes, you can use the
aws_security_group_rule resource, and set its
security_group_id argument to the Terraform output of this module called eks_master_security_group_id. For example, here is how you can allow the master nodes
in this cluster to allow incoming HTTPS requests on port 443 from an additional security group that is not the workers:
What IAM policies are attached to the EKS Cluster?
This module will create IAM roles for the EKS cluster master nodes with the minimum set of policies necessary
for the cluster to function as a Kubernetes cluster. The policies attached to the roles are the same as those documented
in the AWS getting started guide for EKS.
How do you add additional IAM policies?
To add additional IAM policies to the EKS cluster master nodes, you can use the
aws_iam_role_policy or
aws_iam_policy_attachment resources, and set
the IAM role id to the Terraform output of this module called eks_master_iam_role_name for the master nodes. For
example, here is how you can allow the master nodes in this cluster to access an S3 bucket:
NOTE: This configuration depends on kubergrunt, minimum version 0.5.3
If using a compatible Kubernetes version (1.13+) and AWS provider (2.28.0+), this module will set up the OpenID Connect
Provider that can be used with the IAM Roles for Service
Accounts feature. When this
feature is enabled, you can exchange the Kubernetes Service Account Tokens for IAM role credentials using the
sts:AssumeRoleWithWebIdentity AWS API in the STS service.
To allow Kubernetes Service Accounts to assume the roles, you need to grant the proper assume role IAM policies to the
role that is being assumed. Specifically, you need to:
Allow the OpenID Connect Provider to assume the role.
Specify any conditions on assuming the role. You can restrict by:
Service Accounts that can assume the role
Which Namespaces have full access to assume the role (meaning, all Service Accounts in the Namespace can assume
that role).
Once you have an IAM Role that can be assumed by the Kubernetes Service Account, you can configure your Pods to exchange
them for IAM role credentials. EKS will automatically configure the correct environment variables that the SDK expects
on the Pods when you annotate the associated Service Account with the role it should assume.
The following shows an example Kubernetes manifest that configures the Service Account to assume the IAM role arn:aws:iam::123456789012:role/myrole:
Note that the AWS SDK will automatically assume the role if you are using a compatible version. The following is a list
of the minimum SDK version for various platforms that support the AWS_WEB_IDENTITY_TOKEN_FILE environment variable
used by IRSA:
By design, AWS does not allow you to SSH into the master nodes of an EKS cluster.
API Access and Networking
By default the Kubernetes API is accessible from the internet. This is to make operations easier when making requests to
the EKS cluster control plane. However, this module supports restricting access to only be allowed from within the VPC.
You can restrict public access by setting the endpoint_public_access input variable to false.
Control Plane Logging
EKS supports exporting various logs to CloudWatch. By default, none of the logging options are enabled by this module.
To enable logs, you can pass in the relevant type strings to the enabled_cluster_log_types input variable. For
example, to enable API server and audit logs, you can pass in the list ["api", "audit"]. See the official
documentation for a list of available log
types.
How do I deploy Pods on Fargate?
AWS Fargate is an AWS managed infrastructure for running ECS Tasks and EKS Pods
without any worker nodes. With Fargate, your EKS Pods will automatically be assigned a node from a shared pool of VMs
that are fully managed by AWS. This means that you can focus entirely on the application you are deploying and not have
to worry about servers, clusters, and the underlying infrastructure as a whole.
To use Fargate with your EKS Pods, you need to create a Fargate Profile to select the Pods that you want to run. You can
use Namespaces and Labels to restrict which Pods of the EKS cluster will run on Fargate. This means that Pods that match
the specifications of the Fargate Profile will automatically be deployed to Fargate without any further configuration.
Some additional notes on using Fargate:
Fargate Profiles require a Pod Execution Role, which is an IAM role that will be assigned to the underlying
kubelet of the Fargate instance. At a minimum, this role must be given enough permissions to pull the images
used by the Pod. Note that this role is NOT made available to the Pods! Use the IAM Role for Service Accounts
(IRSA) feature of EKS to assign IAM roles for use by the Pods themselves.
If you set the input variable fargate_only on this module, the module will automatically allocate a Fargate
Profile that selects all Pods in the kube-system and default Namespaces. To deploy to Fargate for other
Namespaces, you must manually create additional Fargate Profiles that select those Pods (use the
aws_eks_fargate_profile resource to
provision Fargate Profiles with Terraform). The Pod Execution Role created by the module may be reused for other
Fargate Profiles.
Fargate does not support DaemonSets. This means that you can't rely on the
eks-cloudwatch-container-logs module to forward logs to CloudWatch. Instead, you
need to manually configure a sidecar fluentd container that forwards the log entries to CloudWatch Logs.
How do I upgrade the Kubernetes Version of the cluster?
To upgrade the minor version of Kubernetes deployed on the EKS cluster, you need to update the kubernetes_version
input variable. You must upgrade one minor version at a time, as EKS does not support upgrading by more than one
minor version.
When you bump minor versions, the module will automatically update the deployed Kubernetes components as described in
the official upgrade guide. This is handled
with the provided upgrade_cluster python binary, which will look up the deployed Kubernetes version and make the
required kubectl calls to deploy the updated components.
Note that you must update the nodes to use the corresponding kubelet version as well. This means that when you update
minor versions, you will also need to update the AMIs used by the worker nodes to match the version and rotate the
workers. For more information on rotating worker nodes, refer to How do I roll out an update to the
instances? in the eks-cluster-workers
module README.
Python Helper Scripts
This module contains various python helper scripts that are used to achieve enhanced functionality not available in
Terraform. All these scripts are intended to be used as part of local-exec
provisioner. In order to support disabling the scripts, we
use a null_resource to wrap the provisioner. See this
module's main.tf file for example usage.
Since this is a python script, The operator machine must have a valid python interpreter available in the PATH under
the name python. The scripts support python versions 2.7, 3.5, 3.6, 3.7, and 3.8, on Mac OSX or Linux.
Below is an overview of the scripts:
upgrade_cluster: Update the core Kubernetes applications deployed on to an EKS cluster to ensure that the versions
match with the expected versions deployed for the configured Kubernetes version.
cleanup_cluster_resources: Clean up any residual resources managed by the EKS cluster that may be remaining after
the cluster is destroyed. This is used to workaround terraform and kubernetes limitations that may leave managed
resources behind.
Building the script environment
Dealing with python requirements in a portable manner is tricky. On one hand, we can have everyone install the necessary
requirements using pip. On the other hand, adding this extra step for a tool like terraform is difficult and we
certainly don't want to pollute a user's existing python setup. To workaround this, we use a utility called
pex. Pex will package the python script with all its
requirements into a single binary as a virtual environment that is unpacked at runtime. This Pex environment can also be
made to be compatible with multiple versions of python and multiple OS platforms, making it a portable python runtime
environment for all our scripts. This module distributes the Pex binary so that it is available to terraform when the
module is invoked.
Since the Pex binary only contains the requirements, the binary only needs to be built when the requirements change. You
do not need to rebuild the binary for any changes to the source files in the upgrade_cluster or
cleanup_cluster_resources library.
To build the binary, you will need the following:
A working python environment with all compatible versions of python setup (so that you can build binaries for all
versions)
tox and pex installed (use pip install -r dev_requirements.txt)
You can then build the binary using the helper script build.sh which will build the binary and copy it to the bin
directory for distribution. After that, you just need to check in the updated binaries.
It is recommended to use pyenv to help setup an environment with multiple python
interpreters. The latest binaries are built with the following python environment:
pyenv shell 2.7.153.5.23.6.63.7.03.8.1
Questions? Ask away.
We're here to talk about our services, answer any questions, give advice, or just to chat.
{"treedata":{"name":"root","toggled":true,"children":[{"name":".circleci","children":[{"name":"config.yml","path":".circleci/config.yml","sha":"e634c582e53ab8c0571118cebf8033c4f558cee3"}]},{"name":".gitignore","path":".gitignore","sha":"7f6cf4bc746bbfd6da4c7a21dbcf1a2296aa0c10"},{"name":".pre-commit-config.yaml","path":".pre-commit-config.yaml","sha":"b008949ef10a7bad93ab93e8821da77577a30c5c"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"db8a871849f2583384d581e2a4c35eb5d2c50625"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","sha":"a7cc7bd94443c252390564fa988755dbbe80d87d"},{"name":"GRUNTWORK_PHILOSOPHY.md","path":"GRUNTWORK_PHILOSOPHY.md","sha":"02d9873a74c99fe6d9b6b26bd9f8eb4a7a699c32"},{"name":"LICENSE.md","path":"LICENSE.md","sha":"a2cf01ecdd725fddd718ab91c80c115882c94f3c"},{"name":"README.adoc","path":"README.adoc","sha":"5ed02a037b64e33fe15e8a022c97f39d7e6242c2"},{"name":"_docs","children":[{"name":"eks-architecture.png","path":"_docs/eks-architecture.png","sha":"b4c9c46f88ed465c5575e915af54ad9920b56941"},{"name":"eks-icon.png","path":"_docs/eks-icon.png","sha":"83a29dc46e7bc6234ba5bb825e8ae283c56229a0"}]},{"name":"core-concepts.md","path":"core-concepts.md","sha":"3c504a547fc55ecff5536141534a32ed8a4a4ae7"},{"name":"examples","children":[{"name":"README.md","path":"examples/README.md","sha":"a70f3adc0c888e07b0b03cb32fbd156547c354da"},{"name":"eks-cluster-managed-workers","children":[{"name":"README.md","path":"examples/eks-cluster-managed-workers/README.md","sha":"21acaeb73c1d8a1819480bc7a8d1c35b8fa69081"},{"name":"dependencies.tf","path":"examples/eks-cluster-managed-workers/dependencies.tf","sha":"cf1b48a0d58571356ce788dda915332a48bb45c2"},{"name":"main.tf","path":"examples/eks-cluster-managed-workers/main.tf","sha":"cd7f3fbb03ddd663b552eb852a5f2befc379add0"},{"name":"outputs.tf","path":"examples/eks-cluster-managed-workers/outputs.tf","sha":"431bebd71e3f9d5c299c1740ba16b2eef717cbf0"},{"name":"variables.tf","path":"examples/eks-cluster-managed-workers/variables.tf","sha":"e4a9d5b2da436ca317a0380b03d8a85bce549472"}]},{"name":"eks-cluster-with-iam-role-mappings","children":[{"name":"README.md","path":"examples/eks-cluster-with-iam-role-mappings/README.md","sha":"6479e81678f2e08df477d467f2124f5dc53e9e53"},{"name":"dependencies.tf","path":"examples/eks-cluster-with-iam-role-mappings/dependencies.tf","sha":"df21d64c3435ff2859c4099ce0b854e98483f624"},{"name":"main.tf","path":"examples/eks-cluster-with-iam-role-mappings/main.tf","sha":"e445741db6fefdf7ddd0850f6820644c2a98348d"},{"name":"outputs.tf","path":"examples/eks-cluster-with-iam-role-mappings/outputs.tf","sha":"3876c30890ffef1726d533a869c23e66fa244e6c"},{"name":"user-data","children":[{"name":"user-data.sh","path":"examples/eks-cluster-with-iam-role-mappings/user-data/user-data.sh","sha":"b10c34bfe4c9d10101472b47edbc3b7dff42a88e"}]},{"name":"variables.tf","path":"examples/eks-cluster-with-iam-role-mappings/variables.tf","sha":"7b3d2c4949848e51a7676269d419b85dc7ccfa4b"}]},{"name":"eks-cluster-with-supporting-services","children":[{"name":"README.md","path":"examples/eks-cluster-with-supporting-services/README.md","sha":"1af610f60977f2f05bb6917c8a3040449028ddd5"},{"name":"core-services","children":[{"name":"README.md","path":"examples/eks-cluster-with-supporting-services/core-services/README.md","sha":"e0bac13c7fd97d206766cbe3db0e7f269f7f0126"},{"name":"dependencies.tf","path":"examples/eks-cluster-with-supporting-services/core-services/dependencies.tf","sha":"8ef506ceacdd4b57bcdea3ad91c84c3c2544ba03"},{"name":"main.tf","path":"examples/eks-cluster-with-supporting-services/core-services/main.tf","sha":"35ecbae3c848a60de5e7e2d07a517bad76fdca3e"},{"name":"outputs.tf","path":"examples/eks-cluster-with-supporting-services/core-services/outputs.tf","sha":"35eb7dffb12786d50f580e64fa4a6ef496c160e8"},{"name":"variables.tf","path":"examples/eks-cluster-with-supporting-services/core-services/variables.tf","sha":"e43a616334814e86479287150cfc822187226708"}]},{"name":"eks-cluster","children":[{"name":"README.md","path":"examples/eks-cluster-with-supporting-services/eks-cluster/README.md","sha":"8a60a01004a93bbbf2091b730f0207f6dd2cc07e"},{"name":"dependencies.tf","path":"examples/eks-cluster-with-supporting-services/eks-cluster/dependencies.tf","sha":"fdc70a25511df461747927bc6874cff7bc787def"},{"name":"main.tf","path":"examples/eks-cluster-with-supporting-services/eks-cluster/main.tf","sha":"e662e9cc615234b62f7c8a2b4489124d52db0c37"},{"name":"outputs.tf","path":"examples/eks-cluster-with-supporting-services/eks-cluster/outputs.tf","sha":"534f5957ab5d9225aebf863e7849baec0da96dbb"},{"name":"user-data","children":[{"name":"app_worker_user_data.sh","path":"examples/eks-cluster-with-supporting-services/eks-cluster/user-data/app_worker_user_data.sh","sha":"c5fdd13d5bb04f765f1c90e9f12d23c48e94a252"},{"name":"core_worker_user_data.sh","path":"examples/eks-cluster-with-supporting-services/eks-cluster/user-data/core_worker_user_data.sh","sha":"0fa26153108b3d030ceeaae777aeb0a7e115404e"}]},{"name":"variables.tf","path":"examples/eks-cluster-with-supporting-services/eks-cluster/variables.tf","sha":"225ad92a427b38a0cf3fd4cd02e7c0ada2c0eccb"}]},{"name":"nginx-service","children":[{"name":"README.md","path":"examples/eks-cluster-with-supporting-services/nginx-service/README.md","sha":"58b899364432605520b890c407d1bcd0fafc8b27"},{"name":"dependencies.tf","path":"examples/eks-cluster-with-supporting-services/nginx-service/dependencies.tf","sha":"a2819acb9c726887612d04e224c9473cb7e293fd"},{"name":"main.tf","path":"examples/eks-cluster-with-supporting-services/nginx-service/main.tf","sha":"24d8cbbff07b1aa3e5a4ef7eae83851a0e895a3f"},{"name":"templates","children":[{"name":"values.yaml","path":"examples/eks-cluster-with-supporting-services/nginx-service/templates/values.yaml","sha":"298435e01df9fa495b15d512073c62662d292cd3"}]},{"name":"variables.tf","path":"examples/eks-cluster-with-supporting-services/nginx-service/variables.tf","sha":"36ea6f8a36b19e34dbeeb25ae7e5fcf30c956b0f"}]},{"name":"packer","children":[{"name":"README.md","path":"examples/eks-cluster-with-supporting-services/packer/README.md","sha":"6a974a7fd5da7ac13309d9e0c4aaba7bd8cb46c7"},{"name":"build.json","path":"examples/eks-cluster-with-supporting-services/packer/build.json","sha":"34760ce3ea4fe41078097d7a34092e2c6bf3ee43"}]}]},{"name":"eks-fargate-cluster-with-irsa","children":[{"name":"README.md","path":"examples/eks-fargate-cluster-with-irsa/README.md","sha":"7dfcee13140ca3df3baf9f61e666a45dde71a98a"},{"name":"dependencies.tf","path":"examples/eks-fargate-cluster-with-irsa/dependencies.tf","sha":"b422b2aa58d724243115464cebd86dfc9d22de19"},{"name":"main.tf","path":"examples/eks-fargate-cluster-with-irsa/main.tf","sha":"7f2e1bc01b84948b28c554f9d8d08776168490c4"},{"name":"outputs.tf","path":"examples/eks-fargate-cluster-with-irsa/outputs.tf","sha":"f059d7b74ffbfb06a0868d6d0a5d1831c8f45f10"},{"name":"variables.tf","path":"examples/eks-fargate-cluster-with-irsa/variables.tf","sha":"431b95593cc36fafc2a0072391d5e039a3d53c19"}]},{"name":"eks-fargate-cluster-with-supporting-services","children":[{"name":"README.md","path":"examples/eks-fargate-cluster-with-supporting-services/README.md","sha":"e597364fdf056051daa5b24e43afb02b22d8ec5c"},{"name":"core-services","children":[{"name":"README.md","path":"examples/eks-fargate-cluster-with-supporting-services/core-services/README.md","sha":"e0bac13c7fd97d206766cbe3db0e7f269f7f0126"},{"name":"dependencies.tf","path":"examples/eks-fargate-cluster-with-supporting-services/core-services/dependencies.tf","sha":"c8a0975403bb81f5c9e8c2cddea1666df0adb8b0"},{"name":"main.tf","path":"examples/eks-fargate-cluster-with-supporting-services/core-services/main.tf","sha":"6476d1e073caffbe5999320b9609d1dbba2aa7a0"},{"name":"outputs.tf","path":"examples/eks-fargate-cluster-with-supporting-services/core-services/outputs.tf","sha":"35eb7dffb12786d50f580e64fa4a6ef496c160e8"},{"name":"variables.tf","path":"examples/eks-fargate-cluster-with-supporting-services/core-services/variables.tf","sha":"da657291959044d32535597ed3d384ddaa6f83bd"}]},{"name":"eks-cluster","children":[{"name":"dependencies.tf","path":"examples/eks-fargate-cluster-with-supporting-services/eks-cluster/dependencies.tf","sha":"c1fa9e2c0d794ed6a8bf8afe6773d9645ea161d8"},{"name":"main.tf","path":"examples/eks-fargate-cluster-with-supporting-services/eks-cluster/main.tf","sha":"8fa3a3d6b84684f20307962ff9831ccc94bccb01"},{"name":"outputs.tf","path":"examples/eks-fargate-cluster-with-supporting-services/eks-cluster/outputs.tf","sha":"db0e767fd7ed3a0bcad5628a0c13b6208a442f13"},{"name":"variables.tf","path":"examples/eks-fargate-cluster-with-supporting-services/eks-cluster/variables.tf","sha":"cad45b14637d265dd23de69acc03ff6152ea1814"}]},{"name":"nginx-service","children":[{"name":"dependencies.tf","path":"examples/eks-fargate-cluster-with-supporting-services/nginx-service/dependencies.tf","sha":"3165e5c71fb1642d39a60f544be708d547825e7f"},{"name":"main.tf","path":"examples/eks-fargate-cluster-with-supporting-services/nginx-service/main.tf","sha":"d66648b4557bfb3ed32b094248fc137f41e98975"},{"name":"templates","children":[{"name":"values.yaml","path":"examples/eks-fargate-cluster-with-supporting-services/nginx-service/templates/values.yaml","sha":"655914f91177135cb7c5f15b62166cfc82a62a91"}]},{"name":"variables.tf","path":"examples/eks-fargate-cluster-with-supporting-services/nginx-service/variables.tf","sha":"d3c166441cdc556b0839930fbc281b7e8a1bd57f"}]}]},{"name":"eks-fargate-cluster","children":[{"name":"README.md","path":"examples/eks-fargate-cluster/README.md","sha":"df681cdbe945d0592ca57bd3a8eb9ae5d88c2f4a"},{"name":"dependencies.tf","path":"examples/eks-fargate-cluster/dependencies.tf","sha":"b422b2aa58d724243115464cebd86dfc9d22de19"},{"name":"main.tf","path":"examples/eks-fargate-cluster/main.tf","sha":"0094f34dbeb874c57ce20bcd9e3582f930d63cf2"},{"name":"outputs.tf","path":"examples/eks-fargate-cluster/outputs.tf","sha":"5115288e4192921035aba980990103fe4c4b7150"},{"name":"terraform.tfvars.back","path":"examples/eks-fargate-cluster/terraform.tfvars.back","sha":"6cb73f75cc7828c6b3efdc2a9b1787f75ed276d1"},{"name":"user-data","children":[{"name":"user-data.sh","path":"examples/eks-fargate-cluster/user-data/user-data.sh","sha":"b10c34bfe4c9d10101472b47edbc3b7dff42a88e"}]},{"name":"variables.tf","path":"examples/eks-fargate-cluster/variables.tf","sha":"eea40e3144f3037c3b3451d61e1eeab2b871cce5"}]}]},{"name":"modules","children":[{"name":"eks-alb-ingress-controller-iam-policy","children":[{"name":"README.md","path":"modules/eks-alb-ingress-controller-iam-policy/README.md","sha":"d85eecf670ea161dcfe4b69c09926f31eef55c73"},{"name":"iampolicy.json","path":"modules/eks-alb-ingress-controller-iam-policy/iampolicy.json","sha":"5cba0c1500ee2520d72e8d47b86e318958e4dbc7"},{"name":"main.tf","path":"modules/eks-alb-ingress-controller-iam-policy/main.tf","sha":"a79f5a2e6a0ba72562c5a87182db516d8824ed21"},{"name":"outputs.tf","path":"modules/eks-alb-ingress-controller-iam-policy/outputs.tf","sha":"b551b0bcc6eb1b43bfff1606696566658564cfb4"},{"name":"variables.tf","path":"modules/eks-alb-ingress-controller-iam-policy/variables.tf","sha":"250152e6bfeb02a16bed4151ffc7156636db1bd9"}]},{"name":"eks-alb-ingress-controller","children":[{"name":"README.md","path":"modules/eks-alb-ingress-controller/README.md","sha":"f85f8d19d71b230c56f71d085d300c3135284a1e"},{"name":"main.tf","path":"modules/eks-alb-ingress-controller/main.tf","sha":"a9afcdabc54036bc7626ce8604523d802de21a3b"},{"name":"templates","children":[{"name":"node_affinity.yaml","path":"modules/eks-alb-ingress-controller/templates/node_affinity.yaml","sha":"c6eaf8e94fa7c893857cc009df954443239a8fe0"},{"name":"values.yaml","path":"modules/eks-alb-ingress-controller/templates/values.yaml","sha":"e2a11271abc9ec1937a082db6bef91a5e0d69a6c"}]},{"name":"variables.tf","path":"modules/eks-alb-ingress-controller/variables.tf","sha":"35941c1c6bdac42f50c810e61edee43829247d52"}]},{"name":"eks-cloudwatch-container-logs","children":[{"name":"README.md","path":"modules/eks-cloudwatch-container-logs/README.md","sha":"047fb9b3b97437261911c3fa4acec0cb419b1f1b"},{"name":"main.tf","path":"modules/eks-cloudwatch-container-logs/main.tf","sha":"f26b582dc8dad236cdf723d68fcd475285a29b8d"},{"name":"outputs.tf","path":"modules/eks-cloudwatch-container-logs/outputs.tf","sha":"7061ed458fec528c8b8b587291f0eccb4324fb72"},{"name":"templates","children":[{"name":"node_affinity.yaml","path":"modules/eks-cloudwatch-container-logs/templates/node_affinity.yaml","sha":"cf47b63d7c2b9699e0ab1e36e9a8dadad3a7f4c0"},{"name":"values.yaml","path":"modules/eks-cloudwatch-container-logs/templates/values.yaml","sha":"56bb63870ca40f0b60a3e1eb68dee108b59dae16"}]},{"name":"variables.tf","path":"modules/eks-cloudwatch-container-logs/variables.tf","sha":"e1b89a574ff63017bd992278048e690e1db6faf9"}]},{"name":"eks-cluster-control-plane","children":[{"name":"README.md","path":"modules/eks-cluster-control-plane/README.md","sha":"ad4be099d1da290902dc2290fd5c44439c1ca0ef","toggled":true},{"name":"control_plane_scripts","children":[{"name":"bin","children":[{"name":"control_plane_scripts_py27_env.pex","path":"modules/eks-cluster-control-plane/control_plane_scripts/bin/control_plane_scripts_py27_env.pex","sha":"3b75ea0e3f39c5a2be32f1d17c370826fe062fcf"},{"name":"control_plane_scripts_py3_env.pex","path":"modules/eks-cluster-control-plane/control_plane_scripts/bin/control_plane_scripts_py3_env.pex","sha":"f5602767c99f0addee9cdf1ea1f1bfb7a26bfbc9"}]},{"name":"build.sh","path":"modules/eks-cluster-control-plane/control_plane_scripts/build.sh","sha":"33b5e9231babdb0c2c0997b04a964c27b98a4e13"},{"name":"cleanup_cluster_resources","children":[{"name":"__init__.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/cleanup_cluster_resources/__init__.py","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"},{"name":"global_vars.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/cleanup_cluster_resources/global_vars.py","sha":"47920d25645a8c168f196beb76eb37da60055dd3"},{"name":"main.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/cleanup_cluster_resources/main.py","sha":"21dfb38d1bf8f4d15a03da5e09ae3ba575eb4501"},{"name":"vpc.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/cleanup_cluster_resources/vpc.py","sha":"76d1c2084906d1ce04c2e2e527859f47eddc6530"}]},{"name":"control_plane_scripts_utils","children":[{"name":"__init__.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/control_plane_scripts_utils/__init__.py","sha":"37d050d1afd8ebb0c9d6916cff61fa674e6ac8a3"},{"name":"project_logging.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/control_plane_scripts_utils/project_logging.py","sha":"c29bfb0dfe0a3d4e04aeaabff0b2e58387ccf12b"}]},{"name":"dev_requirements.txt","path":"modules/eks-cluster-control-plane/control_plane_scripts/dev_requirements.txt","sha":"430b91474dc8220624012e70d8c2e43582f17161"},{"name":"requirements.txt","path":"modules/eks-cluster-control-plane/control_plane_scripts/requirements.txt","sha":"0ae8cdb74f4c793658c5dfdd13ce1ec723f7b2a1"},{"name":"upgrade_cluster","children":[{"name":"__init__.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/upgrade_cluster/__init__.py","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"},{"name":"eks.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/upgrade_cluster/eks.py","sha":"d0aca412ffa983300df0d8926bee8829e148f85e"},{"name":"exceptions.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/upgrade_cluster/exceptions.py","sha":"c35893a0f70e2c0d86dd64b7bce8d092e84355b3"},{"name":"global_vars.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/upgrade_cluster/global_vars.py","sha":"e223eefafed2576c8988a708395d92f6908b3f49"},{"name":"k8s.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/upgrade_cluster/k8s.py","sha":"83b3a0d7419d4a21872d9416f7b76d589650895d"},{"name":"k8s_version_map.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/upgrade_cluster/k8s_version_map.py","sha":"ed3b86c032b7829ba2983c1363efe936d85e4328"},{"name":"main.py","path":"modules/eks-cluster-control-plane/control_plane_scripts/upgrade_cluster/main.py","sha":"af8d29a692f2530b74b9581464aca7bd06c255cd"}]}]},{"name":"dependencies.tf","path":"modules/eks-cluster-control-plane/dependencies.tf","sha":"ff5c5efe0c1f84b9b17b995462f08d609ec454e6"},{"name":"main.tf","path":"modules/eks-cluster-control-plane/main.tf","sha":"3a7f2c315a2591e0f384063096950cd2c10cbe48"},{"name":"outputs.tf","path":"modules/eks-cluster-control-plane/outputs.tf","sha":"a68f4000d7524e2f2db24d3c12d2a3bac273a42a"},{"name":"templates","children":[{"name":"kubectl_config.tpl","path":"modules/eks-cluster-control-plane/templates/kubectl_config.tpl","sha":"083a5e914505363541190db3ee412d8d9e15b4ec"}]},{"name":"variables.tf","path":"modules/eks-cluster-control-plane/variables.tf","sha":"1c1d3d4b8827311c96c885464ecf3acda6959d3c"}],"toggled":true},{"name":"eks-cluster-managed-workers","children":[{"name":"README.md","path":"modules/eks-cluster-managed-workers/README.md","sha":"7c02b6cb8463d50ab1f7f0d64ede5617be7b8b71"},{"name":"main.tf","path":"modules/eks-cluster-managed-workers/main.tf","sha":"13454d6ece32b306cc703c23fa7dad39d99107b3"},{"name":"outputs.tf","path":"modules/eks-cluster-managed-workers/outputs.tf","sha":"ff528cd4101033d79defb8e8a6a9616a8b427849"},{"name":"variables.tf","path":"modules/eks-cluster-managed-workers/variables.tf","sha":"d8f332eaa8b195a7a7923f79d8ec05ccb2bc6539"}]},{"name":"eks-cluster-workers-cross-access","children":[{"name":"README.md","path":"modules/eks-cluster-workers-cross-access/README.md","sha":"6c4e50bda62acc6c06d836488ef54f7119f27aee"},{"name":"main.tf","path":"modules/eks-cluster-workers-cross-access/main.tf","sha":"30885a053867992d0c3ee3804ba6833ae463c116"},{"name":"outputs.tf","path":"modules/eks-cluster-workers-cross-access/outputs.tf","sha":"c6c7f7a89007c55be5470ffd639c05c3fb052ad7"},{"name":"variables.tf","path":"modules/eks-cluster-workers-cross-access/variables.tf","sha":"d64aab893b6e909416189e985f072dd8809dfa2f"}]},{"name":"eks-cluster-workers","children":[{"name":"README.md","path":"modules/eks-cluster-workers/README.md","sha":"9ea880ffa5b67ca8e135157476135054d8f152ea"},{"name":"main.tf","path":"modules/eks-cluster-workers/main.tf","sha":"8c4bc978bf1cd62b7c6255218a6d5bdcb38955a9"},{"name":"outputs.tf","path":"modules/eks-cluster-workers/outputs.tf","sha":"a9c37412a97c287000f2000c9c092b87e2487c11"},{"name":"variables.tf","path":"modules/eks-cluster-workers/variables.tf","sha":"d4b78bd1444cc595bce91006e7f02d6921a7ed96"}]},{"name":"eks-iam-role-assume-role-policy-for-service-account","children":[{"name":"README.md","path":"modules/eks-iam-role-assume-role-policy-for-service-account/README.md","sha":"efbbbd70fea3661c662750768facb7950239ffa3"},{"name":"main.tf","path":"modules/eks-iam-role-assume-role-policy-for-service-account/main.tf","sha":"be2fefe5e1a29a2582d1dcdc0b700b74f198cfc9"},{"name":"outputs.tf","path":"modules/eks-iam-role-assume-role-policy-for-service-account/outputs.tf","sha":"c2910cec89910bb06a157311ac8c4bf72835dfe5"},{"name":"variables.tf","path":"modules/eks-iam-role-assume-role-policy-for-service-account/variables.tf","sha":"dc660ddf84158851145289f6036a0fc19fbf7ce4"}]},{"name":"eks-k8s-cluster-autoscaler-iam-policy","children":[{"name":"README.md","path":"modules/eks-k8s-cluster-autoscaler-iam-policy/README.md","sha":"cfd86f6261a849f9204b0b7c80e96f9b03efd79d"},{"name":"main.tf","path":"modules/eks-k8s-cluster-autoscaler-iam-policy/main.tf","sha":"c743f0e3523119155e2f2a6434e6f634d659aaee"},{"name":"outputs.tf","path":"modules/eks-k8s-cluster-autoscaler-iam-policy/outputs.tf","sha":"a053ab9f76af3a83301a0a67eeedac9683ee5bc4"},{"name":"variables.tf","path":"modules/eks-k8s-cluster-autoscaler-iam-policy/variables.tf","sha":"be3db9023160b3754187f2f21ce77772b43ced53"}]},{"name":"eks-k8s-cluster-autoscaler","children":[{"name":"README.md","path":"modules/eks-k8s-cluster-autoscaler/README.md","sha":"6f2a76b27d33ffbd760ae7c8a40ab9e56853479d"},{"name":"main.tf","path":"modules/eks-k8s-cluster-autoscaler/main.tf","sha":"f877c9a88c0c82656675f40556dcb8c2774e265f"},{"name":"templates","children":[{"name":"node_affinity.yaml","path":"modules/eks-k8s-cluster-autoscaler/templates/node_affinity.yaml","sha":"c6eaf8e94fa7c893857cc009df954443239a8fe0"},{"name":"values.yaml","path":"modules/eks-k8s-cluster-autoscaler/templates/values.yaml","sha":"51e4cf44a9d8f054c1eced5d7b422255c5c9a481"}]},{"name":"variables.tf","path":"modules/eks-k8s-cluster-autoscaler/variables.tf","sha":"5b21aece34f5fd6f68ce9a88535de6b0b790b07d"}]},{"name":"eks-k8s-external-dns-iam-policy","children":[{"name":"README.md","path":"modules/eks-k8s-external-dns-iam-policy/README.md","sha":"aa9431f2e6f81e507d73482adb339d543b9d1051"},{"name":"main.tf","path":"modules/eks-k8s-external-dns-iam-policy/main.tf","sha":"b346bd0324c30907dd62ac89f93fe9cc7799fd4d"},{"name":"outputs.tf","path":"modules/eks-k8s-external-dns-iam-policy/outputs.tf","sha":"21604a63b741b94ea9ebffd20b18772131020fcf"},{"name":"variables.tf","path":"modules/eks-k8s-external-dns-iam-policy/variables.tf","sha":"250152e6bfeb02a16bed4151ffc7156636db1bd9"}]},{"name":"eks-k8s-external-dns","children":[{"name":"README.md","path":"modules/eks-k8s-external-dns/README.md","sha":"851e8d68beb5998b33d20f1e8cb56ee2f93c6bc2"},{"name":"main.tf","path":"modules/eks-k8s-external-dns/main.tf","sha":"39070bbbd47829cf3c82af84dd3c3092cee76c6c"},{"name":"templates","children":[{"name":"node_affinity.yaml","path":"modules/eks-k8s-external-dns/templates/node_affinity.yaml","sha":"c6eaf8e94fa7c893857cc009df954443239a8fe0"},{"name":"values.yaml","path":"modules/eks-k8s-external-dns/templates/values.yaml","sha":"233c10fd4723c4e515fed2870c778c4d8bf2e29f"}]},{"name":"variables.tf","path":"modules/eks-k8s-external-dns/variables.tf","sha":"8f6ef907c965091277e215b5d003d3a365f952ed"}]},{"name":"eks-k8s-role-mapping","children":[{"name":"README.md","path":"modules/eks-k8s-role-mapping/README.md","sha":"2359880e60bf9051ff9178cc13bbb9507a1aa456"},{"name":"aws_auth_configmap_generator","children":[{"name":"aws_auth_configmap_generator","children":[{"name":"__init__.py","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/aws_auth_configmap_generator/__init__.py","sha":"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"},{"name":"generator.py","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/aws_auth_configmap_generator/generator.py","sha":"4057d70cebc26cb56e95d861618eda4629e41b19"},{"name":"global_vars.py","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/aws_auth_configmap_generator/global_vars.py","sha":"31c2b91932d79d37e284bdf708e506faf0a59649"},{"name":"main.py","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/aws_auth_configmap_generator/main.py","sha":"e69d8517efe23c680e9e67dc48dbd0478723b88f"},{"name":"utils.py","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/aws_auth_configmap_generator/utils.py","sha":"0874f15d63301e4f32cb0517817a515fb18f113e"}]},{"name":"bin","children":[{"name":"aws_auth_configmap_generator_py27_env.pex","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/bin/aws_auth_configmap_generator_py27_env.pex","sha":"d00c0aff5ef5ea8b7ad9a0ce9318e7e5e7a6da9f"},{"name":"aws_auth_configmap_generator_py3_env.pex","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/bin/aws_auth_configmap_generator_py3_env.pex","sha":"c4500959687a373596395a4c275bab61029ea2a9"}]},{"name":"build_scripts","children":[{"name":"build.sh","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/build_scripts/build.sh","sha":"34f496ada6fdc2d33028c6b8df7d3ba172a3dbdd"}]},{"name":"dev_requirements.txt","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/dev_requirements.txt","sha":"40f29298c05348c2f1227a53da3f88c89632feb3"},{"name":"requirements.txt","path":"modules/eks-k8s-role-mapping/aws_auth_configmap_generator/requirements.txt","sha":"97397a79f826def4e1023a6bc9b4cb346bdcafbe"}]},{"name":"main.tf","path":"modules/eks-k8s-role-mapping/main.tf","sha":"27557e43793f1ad7d021b8da3413c006075a0660"},{"name":"outputs.tf","path":"modules/eks-k8s-role-mapping/outputs.tf","sha":"95d4d4ec652bb541b91a2844e00f68064b423e60"},{"name":"variables.tf","path":"modules/eks-k8s-role-mapping/variables.tf","sha":"19ce18b4f61497d7366db872a40ce973f9db8549"}]},{"name":"eks-scripts","children":[{"name":"README.md","path":"modules/eks-scripts/README.md","sha":"96baaf535647b9f4c364d6a19057bcccb42df2be"},{"name":"bin","children":[{"name":"map-ec2-tags-to-node-labels","path":"modules/eks-scripts/bin/map-ec2-tags-to-node-labels","sha":"8087c82d4d47f25439f118c2a51e59d22689ada7"},{"name":"map_ec2_tags_to_node_labels.py","path":"modules/eks-scripts/bin/map_ec2_tags_to_node_labels.py","sha":"f75ad19587e95b2bd8924125ea2a1a697154909f"}]},{"name":"dev_requirements.txt","path":"modules/eks-scripts/dev_requirements.txt","sha":"f56f9d1629a85734fe16ed70f00f36b830cd97c9"},{"name":"install.sh","path":"modules/eks-scripts/install.sh","sha":"7f192fca97b098482a8a398019d4d53f45dba478"}]},{"name":"eks-vpc-tags","children":[{"name":"README.md","path":"modules/eks-vpc-tags/README.md","sha":"b53e923baaa79718b55a272158ff9b710871a6ce"},{"name":"outputs.tf","path":"modules/eks-vpc-tags/outputs.tf","sha":"0ef2787cfd02ea8668c687302b1929618079a0b2"},{"name":"variables.tf","path":"modules/eks-vpc-tags/variables.tf","sha":"a6e332e9da4e473e1e42b1ca6c7b0ba139a77cfb"},{"name":"versions.tf","path":"modules/eks-vpc-tags/versions.tf","sha":"e5d003c3e7a7296ca0f610fc77f94f2139fc59d2"}]}],"toggled":true},{"name":"rfc","children":[{"name":"locking-down-kiam.adoc","path":"rfc/locking-down-kiam.adoc","sha":"3e92efcc57dda26c406ed66c5f95fe76049b3d2c"},{"name":"shipping-logs-to-cloudwatch.md","path":"rfc/shipping-logs-to-cloudwatch.md","sha":"6199b55bfe1faea80833bbf0c411adc90b88b84b"}]},{"name":"setup.cfg","path":"setup.cfg","sha":"981bc2bfd0b35029438d56c6d862a7f1519b8fe6"},{"name":"test","children":[{"name":"Gopkg.lock","path":"test/Gopkg.lock","sha":"7dd58506d83164b594e3d650cae5c540987858e9"},{"name":"Gopkg.toml","path":"test/Gopkg.toml","sha":"a0159c5ca6bab4a7e77117edb9ab4b752517d4eb"},{"name":"README.md","path":"test/README.md","sha":"9bf8180d731bdc892279fcdbcbb03d245f31f83a"},{"name":"eks_cluster_integration_test.go","path":"test/eks_cluster_integration_test.go","sha":"e898491b14abb78d8c7c0bf6191547d3c7fa3fa1"},{"name":"eks_cluster_managed_workers_test.go","path":"test/eks_cluster_managed_workers_test.go","sha":"5c52034ff6ddf39d59169f1bc248d91867f0cdb7"},{"name":"eks_cluster_test_helpers.go","path":"test/eks_cluster_test_helpers.go","sha":"0ac527d18778dd162198297adb57e93927e5eb57"},{"name":"eks_cluster_upgrade_test.go","path":"test/eks_cluster_upgrade_test.go","sha":"73bb2f8bfe1a3cb2547e026840dc9bc6a88a7cc8"},{"name":"eks_cluster_with_iam_role_test.go","path":"test/eks_cluster_with_iam_role_test.go","sha":"ca0b2f65ebffee9c417c59c49884b4034c6ca895"},{"name":"eks_cluster_with_supporting_services_test.go","path":"test/eks_cluster_with_supporting_services_test.go","sha":"e90389ff9fd393a53e813000f3b22552913d0304"},{"name":"eks_fargate_cluster_disable_public_endpoint_test.go","path":"test/eks_fargate_cluster_disable_public_endpoint_test.go","sha":"25ba0984ef5979ca146d16b63654559939d822db"},{"name":"eks_fargate_cluster_irsa_test.go","path":"test/eks_fargate_cluster_irsa_test.go","sha":"ee867e5ad391a426146af448986959542b829490"},{"name":"eks_fargate_cluster_public_access_cidr_test.go","path":"test/eks_fargate_cluster_public_access_cidr_test.go","sha":"da8fa4c2a05ee1ba11ed1ab5310b4b209ad015f4"},{"name":"eks_fargate_cluster_test.go","path":"test/eks_fargate_cluster_test.go","sha":"49809cf53d4defb19e4672520d42c55d4d32d3f4"},{"name":"eks_fargate_cluster_with_supporting_services_test.go","path":"test/eks_fargate_cluster_with_supporting_services_test.go","sha":"196cb7393ea7159f75e189c3e2d235f0665043ad"},{"name":"errors.go","path":"test/errors.go","sha":"be062fe0205ff82db8183d0fde639aa1883013ad"},{"name":"kubefixtures","children":[{"name":"autoscaler-test-pods-deployment.yml","path":"test/kubefixtures/autoscaler-test-pods-deployment.yml","sha":"b2d94c4bfa729b639290ee21629c19ca6ea694ee"},{"name":"eks-irsa-test.yml","path":"test/kubefixtures/eks-irsa-test.yml","sha":"db5439cf6d38873dbae71daa4197d6947990a94a"},{"name":"eks-k8s-role-mapping-test-role.yml","path":"test/kubefixtures/eks-k8s-role-mapping-test-role.yml","sha":"ede7587308d2a4ecf55042b05800099c43f3af7d"},{"name":"kube-system-sa-admin-binding.yml","path":"test/kubefixtures/kube-system-sa-admin-binding.yml","sha":"282d406512102cbe54e952575f26e7e0fbb2aa9a"},{"name":"nginx-deployment.yml","path":"test/kubefixtures/nginx-deployment.yml","sha":"a58866e59c113635af24982cfb0b530f0c416af0"},{"name":"robust-nginx-deployment.yml","path":"test/kubefixtures/robust-nginx-deployment.yml","sha":"a71c2bb24c75b2ebcf54563df799281938a49ca5"}]},{"name":"script_tests","children":[{"name":"executor.sh","path":"test/script_tests/executor.sh","sha":"f2a571ab875195d450a942d684ce41f86f824e70"},{"name":"requirements.txt","path":"test/script_tests/requirements.txt","sha":"e78b3b8c7b4bdecf8d1f235c1f55dcf227ee19c6"},{"name":"test_aws_auth_configmap_generator.py","path":"test/script_tests/test_aws_auth_configmap_generator.py","sha":"8da981d07d31745a1db59e9693995e60cea14abc"},{"name":"test_map_ec2_tags_to_node_labels.py","path":"test/script_tests/test_map_ec2_tags_to_node_labels.py","sha":"1bb3a5eae3727c0e6caf29c2cf4b7d596bb9a161"},{"name":"tox.ini","path":"test/script_tests/tox.ini","sha":"088400028aa4cf08b188b449875cf243222f2250"}]},{"name":"terratest_options.go","path":"test/terratest_options.go","sha":"b396ba967a5d84e38dc5e94d89fba41f93f7e17a"},{"name":"test_debug_helpers.go","path":"test/test_debug_helpers.go","sha":"c71a7a9d5b68f0f59d2518496d9f5893206b5e22"},{"name":"test_helpers.go","path":"test/test_helpers.go","sha":"c0aa8112f2958c98fce5e1bf6193e04824b19aa7"}]}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"eks-cluster-control-plane-module\">EKS Cluster Control Plane Module</h1><div class=\"preview__body--border\"></div><p>This Terraform Module launches an <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/clusters.html\" class=\"preview__body--description--blue\" target=\"_blank\">Elastic Container Service for Kubernetes\nCluster</a>.</p>\n<p>This module is responsible for the EKS Control Plane in <a href=\"#what-is-an-eks-cluster\" class=\"preview__body--description--blue\">the EKS cluster topology</a>. You must\nlaunch worker nodes in order to be able to schedule pods on your cluster. See the <a href=\"/repos/v0.14.0/terraform-aws-eks/modules/eks-cluster-workers\" class=\"preview__body--description--blue\">eks-cluster-workers\nmodule</a> for managing EKS worker nodes.</p>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-you-use-this-module\">How do you use this module?</h2>\n<ul>\n<li>See the <a href=\"/repos/v0.14.0/terraform-aws-eks/README.adoc\" class=\"preview__body--description--blue\">root README</a> for instructions on using Terraform modules.</li>\n<li>See the <a href=\"/repos/v0.14.0/terraform-aws-eks/examples\" class=\"preview__body--description--blue\">examples</a> folder for example usage.</li>\n<li>See <a href=\"/repos/v0.14.0/terraform-aws-eks/modules/eks-cluster-control-plane/variables.tf\" class=\"preview__body--description--blue\">variables.tf</a> for all the variables you can set on this module.</li>\n<li>See <a href=\"/repos/v0.14.0/terraform-aws-eks/modules/eks-cluster-control-plane/outputs.tf\" class=\"preview__body--description--blue\">outputs.tf</a> for all the variables that are outputed by this module.</li>\n<li>This module depends on a packaged python binary, which requires a working python install.</li>\n<li>This module depends on <a href=\"https://kubernetes.io/docs/tasks/tools/install-kubectl/\" class=\"preview__body--description--blue\" target=\"_blank\"><code>kubectl</code></a>.</li>\n<li>See <a href=\"/repos/v0.14.0/terraform-aws-eks/core-concepts.md#how-to-authenticate-kubectl\" class=\"preview__body--description--blue\">How do I authenticate kubectl to the EKS cluster?</a> for information on how\nto authenticate kubectl.\n<ul>\n<li>You will need to install <a href=\"https://kubernetes.io/docs/tasks/tools/install-kubectl/\" class=\"preview__body--description--blue\" target=\"_blank\"><code>kubectl</code></a> to follow the\ninstructions.</li>\n<li>If you wish to use the automatic configuration, you will need\n<a href=\"/repos/kubergrunt\" class=\"preview__body--description--blue\"><code>kubergrunt</code></a>. Refer to the <code>kubergrunt</code> documentation for installation\ninstructions.</li>\n</ul>\n</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"what-is-the-eks-control-plane\">What is the EKS Control Plane?</h2>\n<p>The EKS Control Plane is a managed service entrirely managed by AWS. This contains the resources and endpoint to run and\naccess the <a href=\"https://kubernetes.io/docs/concepts/overview/components/#master-components\" class=\"preview__body--description--blue\" target=\"_blank\">Kubernetes master components</a>.\nThe resources are deployed into your VPC so that they inherit the network rules you configure for your VPC.</p>\n<p>Specifically, the control plane consists of:</p>\n<ul>\n<li><a href=\"https://coreos.com/etcd/\" class=\"preview__body--description--blue\" target=\"_blank\"><code>etcd</code></a>: A distributed key value store used by Kubernetes to hold the metadata and cluster\nstate.</li>\n<li><code>kube-apiserver</code>: Web service that exposes the Kubernetes API. This is the main entrypoint for interacting with the\nKubernetes cluster.</li>\n<li><code>kube-scheduler</code>: This component is responsible for watching for newly created Pods on the cluster, and scheduling\nthem on to the available worker nodes.</li>\n<li><code>kube-controller-manager</code>: This component is responsible for executing the controller logic. Controllers are\nresponsible for managing the Pods on the cluster. For example, you can use a\n<a href=\"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/\" class=\"preview__body--description--blue\" target=\"_blank\"><code>Deployment</code></a> controller to ensure that a\nspecified number of replicas of a Pod is running on the cluster.</li>\n<li><code>cloud-controller-manager</code>: This component is responsible for managing cloud components that Kubernetes will manage.\nThis includes resources like the\n<a href=\"https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/\" class=\"preview__body--description--blue\" target=\"_blank\"><code>LoadBalancers</code></a>.</li>\n</ul>\n<p>You can read more about the different components of EKS in <a href=\"/repos/v0.14.0/terraform-aws-eks/core-concepts.md#what-is-an-eks-cluster\" class=\"preview__body--description--blue\">the project README</a>.</p>\n<h2 class=\"preview__body--subtitle\" id=\"what-security-group-rules-are-created\">What security group rules are created?</h2>\n<p>This module will create a security group for the EKS cluster master nodes to allow them to function as a Kubernetes\ncluster. The rules are based on <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html\" class=\"preview__body--description--blue\" target=\"_blank\">the recommendations provided by\nAWS</a> for configuring an EKS cluster.</p>\n<h3 class=\"preview__body--subtitle\" id=\"a-name-how-to-extend-security-group-a-how-do-you-add-additional-security-group-rules\"><a name="how-to-extend-security-group"></a>How do you add additional security group rules?</h3>\n<p>To add additional security group rules to the EKS cluster master nodes, you can use the\n<a href=\"https://www.terraform.io/docs/providers/aws/r/security_group_rule.html\" class=\"preview__body--description--blue\" target=\"_blank\">aws_security_group_rule</a> resource, and set its\n<code>security_group_id</code> argument to the Terraform output of this module called <code>eks_master_security_group_id</code>. For example, here is how you can allow the master nodes\nin this cluster to allow incoming HTTPS requests on port 443 from an additional security group that is not the workers:</p>\n<pre>module <span class=\"hljs-string\">\"eks_cluster\"</span> {\n # (arguments omitted)\n}\n<span class=\"hljs-built_in\">\nresource </span><span class=\"hljs-string\">\"aws_security_group_rule\"</span> <span class=\"hljs-string\">\"allow_inbound_http_from_anywhere\"</span> {\n <span class=\"hljs-built_in\"> type </span> = <span class=\"hljs-string\">\"ingress\"</span>\n from_port = 443\n to_port = 443\n protocol = <span class=\"hljs-string\">\"tcp\"</span>\n\n security_group_id = module.eks_cluster.eks_master_security_group_id\n source_security_group_id = var.source_aws_security_group_id\n}\n</pre>\n<h2 class=\"preview__body--subtitle\" id=\"what-iam-policies-are-attached-to-the-eks-cluster\">What IAM policies are attached to the EKS Cluster?</h2>\n<p>This module will create IAM roles for the EKS cluster master nodes with the minimum set of policies necessary\nfor the cluster to function as a Kubernetes cluster. The policies attached to the roles are the same as those documented\nin <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html\" class=\"preview__body--description--blue\" target=\"_blank\">the AWS getting started guide for EKS</a>.</p>\n<h3 class=\"preview__body--subtitle\" id=\"how-do-you-add-additional-iam-policies\">How do you add additional IAM policies?</h3>\n<p>To add additional IAM policies to the EKS cluster master nodes, you can use the\n<a href=\"https://www.terraform.io/docs/providers/aws/r/iam_role_policy.html\" class=\"preview__body--description--blue\" target=\"_blank\">aws_iam_role_policy</a> or\n<a href=\"https://www.terraform.io/docs/providers/aws/r/iam_policy_attachment.html\" class=\"preview__body--description--blue\" target=\"_blank\">aws_iam_policy_attachment</a> resources, and set\nthe IAM role id to the Terraform output of this module called <code>eks_master_iam_role_name</code> for the master nodes. For\nexample, here is how you can allow the master nodes in this cluster to access an S3 bucket:</p>\n<pre>module <span class=\"hljs-string\">\"eks_cluster\"</span> {\n # (arguments omitted)\n}\n<span class=\"hljs-built_in\">\nresource </span><span class=\"hljs-string\">\"aws_iam_role_policy\"</span> <span class=\"hljs-string\">\"access_s3_bucket\"</span> {\n name = <span class=\"hljs-string\">\"access_s3_bucket\"</span>\n role = <span class=\"hljs-string\">\"<span class=\"hljs-variable\">${module.eks_cluster.eks_master_iam_role_name}</span>\"</span>\n <span class=\"hljs-built_in\"> policy </span>= <<EOF\n{\n <span class=\"hljs-string\">\"Version\"</span>: <span class=\"hljs-string\">\"2012-10-17\"</span>,\n <span class=\"hljs-string\">\"Statement\"</span>: [\n {\n <span class=\"hljs-string\">\"Sid\"</span>: <span class=\"hljs-string\">\"\"</span>,\n <span class=\"hljs-string\">\"Effect\"</span>:<span class=\"hljs-string\">\"Allow\"</span>,\n <span class=\"hljs-string\">\"Action\"</span>: <span class=\"hljs-string\">\"s3:GetObject\"</span>,\n <span class=\"hljs-string\">\"Resource\"</span>: <span class=\"hljs-string\">\"arn:aws:s3:::examplebucket/*\"</span>\n }\n ]\n}\nEOF\n}\n</pre>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-i-associate-iam-roles-to-the-pods\">How do I associate IAM roles to the Pods?</h2>\n<p><strong>NOTE: This configuration depends on <a href=\"/repos/kubergrunt\" class=\"preview__body--description--blue\">kubergrunt</a>, minimum version 0.5.3</strong></p>\n<p>If using a compatible Kubernetes version (1.13+) and AWS provider (2.28.0+), this module will set up the OpenID Connect\nProvider that can be used with the <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html\" class=\"preview__body--description--blue\" target=\"_blank\">IAM Roles for Service\nAccounts</a> feature. When this\nfeature is enabled, you can exchange the Kubernetes Service Account Tokens for IAM role credentials using the\n<code>sts:AssumeRoleWithWebIdentity</code> AWS API in the STS service.</p>\n<p>To allow Kubernetes Service Accounts to assume the roles, you need to grant the proper assume role IAM policies to the\nrole that is being assumed. Specifically, you need to:</p>\n<ul>\n<li>Allow the OpenID Connect Provider to assume the role.</li>\n<li>Specify any conditions on assuming the role. You can restrict by:\n<ul>\n<li>Service Accounts that can assume the role</li>\n<li>Which Namespaces have full access to assume the role (meaning, all Service Accounts in the Namespace can assume\nthat role).</li>\n</ul>\n</li>\n</ul>\n<p>You can use the\n<a href=\"/repos/v0.14.0/terraform-aws-eks/modules/eks-iam-role-assume-role-policy-for-service-account\" class=\"preview__body--description--blue\">eks-iam-role-assume-role-policy-for-service-account module</a> to\nconstruct the policy using a more convenient interface. Refer to the module documentation for more info.</p>\n<p>Once you have an IAM Role that can be assumed by the Kubernetes Service Account, you can configure your Pods to exchange\nthem for IAM role credentials. EKS will automatically configure the correct environment variables that the SDK expects\non the Pods when you annotate the associated Service Account with the role it should assume.</p>\n<p>The following shows an example Kubernetes manifest that configures the Service Account to assume the IAM role <code>arn:aws:iam::123456789012:role/myrole</code>:</p>\n<pre><span class=\"hljs-attribute\">apiVersion</span>: v1\n<span class=\"hljs-attribute\">kind</span>: ServiceAccount\n<span class=\"hljs-attribute\">metadata</span>:\n <span class=\"hljs-attribute\">annotations</span>:\n eks.amazonaws.com/<span class=\"hljs-attribute\">role-arn</span>: <span class=\"hljs-attribute\">arn</span>:<span class=\"hljs-attribute\">aws</span>:<span class=\"hljs-attribute\">iam</span>::<span class=\"hljs-number\">123456789012</span>:role/myrole\n</pre>\n<p>Note that the AWS SDK will automatically assume the role if you are using a compatible version. The following is a list\nof the minimum SDK version for various platforms that support the <code>AWS_WEB_IDENTITY_TOKEN_FILE</code> environment variable\nused by IRSA:</p>\n<pre><span class=\"hljs-selector-tag\">Java</span> 1<span class=\"hljs-selector-class\">.11</span><span class=\"hljs-selector-class\">.623</span>\n<span class=\"hljs-selector-tag\">Java2</span> 2<span class=\"hljs-selector-class\">.7</span><span class=\"hljs-selector-class\">.36</span>\n<span class=\"hljs-selector-tag\">Go</span> 1<span class=\"hljs-selector-class\">.23</span><span class=\"hljs-selector-class\">.13</span>\n<span class=\"hljs-selector-tag\">Python</span> 1<span class=\"hljs-selector-class\">.9</span><span class=\"hljs-selector-class\">.220</span>\n<span class=\"hljs-selector-tag\">Node</span> 2<span class=\"hljs-selector-class\">.521</span><span class=\"hljs-selector-class\">.0</span>\n<span class=\"hljs-selector-tag\">Ruby</span> 2<span class=\"hljs-selector-class\">.11</span><span class=\"hljs-selector-class\">.345</span>\n<span class=\"hljs-selector-tag\">PHP</span> 3<span class=\"hljs-selector-class\">.110</span><span class=\"hljs-selector-class\">.7</span>\n<span class=\"hljs-selector-class\">.NET</span> 3<span class=\"hljs-selector-class\">.3</span><span class=\"hljs-selector-class\">.580</span><span class=\"hljs-selector-class\">.0</span>\n</pre>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-i-ssh-into-the-nodes\">How do I SSH into the nodes?</h2>\n<p>By design, AWS does not allow you to SSH into the master nodes of an EKS cluster.</p>\n<h2 class=\"preview__body--subtitle\" id=\"api-access-and-networking\">API Access and Networking</h2>\n<p>By default the Kubernetes API is accessible from the internet. This is to make operations easier when making requests to\nthe EKS cluster control plane. However, this module supports restricting access to only be allowed from within the VPC.\nYou can restrict public access by setting the <code>endpoint_public_access</code> input variable to <code>false</code>.</p>\n<h2 class=\"preview__body--subtitle\" id=\"control-plane-logging\">Control Plane Logging</h2>\n<p>EKS supports exporting various logs to CloudWatch. By default, none of the logging options are enabled by this module.\nTo enable logs, you can pass in the relevant type strings to the <code>enabled_cluster_log_types</code> input variable. For\nexample, to enable API server and audit logs, you can pass in the list <code>["api", "audit"]</code>. See <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\" class=\"preview__body--description--blue\" target=\"_blank\">the official\ndocumentation</a> for a list of available log\ntypes.</p>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-i-deploy-pods-on-fargate\">How do I deploy Pods on Fargate?</h2>\n<p><a href=\"https://aws.amazon.com/fargate/\" class=\"preview__body--description--blue\" target=\"_blank\">AWS Fargate</a> is an AWS managed infrastructure for running ECS Tasks and EKS Pods\nwithout any worker nodes. With Fargate, your EKS Pods will automatically be assigned a node from a shared pool of VMs\nthat are fully managed by AWS. This means that you can focus entirely on the application you are deploying and not have\nto worry about servers, clusters, and the underlying infrastructure as a whole.</p>\n<p>To use Fargate with your EKS Pods, you need to create a Fargate Profile to select the Pods that you want to run. You can\nuse Namespaces and Labels to restrict which Pods of the EKS cluster will run on Fargate. This means that Pods that match\nthe specifications of the Fargate Profile will automatically be deployed to Fargate without any further configuration.</p>\n<p>Some additional notes on using Fargate:</p>\n<ul>\n<li>Fargate Profiles require a Pod Execution Role, which is an IAM role that will be assigned to the underlying\n<code>kubelet</code> of the Fargate instance. At a minimum, this role must be given enough permissions to pull the images\nused by the Pod. Note that <strong>this role is NOT made available to the Pods!</strong> Use <a href=\"#how-do-i-associate-iam-roles-to-pods\" class=\"preview__body--description--blue\">the IAM Role for Service Accounts\n(IRSA) feature of EKS</a> to assign IAM roles for use by the Pods themselves.</li>\n<li>If you set the input variable <code>fargate_only</code> on this module, the module will automatically allocate a Fargate\nProfile that selects all Pods in the <code>kube-system</code> and <code>default</code> Namespaces. To deploy to Fargate for other\nNamespaces, you must manually create additional Fargate Profiles that select those Pods (use <a href=\"https://www.terraform.io/docs/providers/aws/r/eks_fargate_profile.html\" class=\"preview__body--description--blue\" target=\"_blank\">the\n<code>aws_eks_fargate_profile</code> resource</a> to\nprovision Fargate Profiles with Terraform). The Pod Execution Role created by the module may be reused for other\nFargate Profiles.</li>\n<li>Fargate does not support DaemonSets. This means that you can't rely on the\n<a href=\"/repos/v0.14.0/terraform-aws-eks/modules/eks-cloudwatch-container-logs\" class=\"preview__body--description--blue\">eks-cloudwatch-container-logs</a> module to forward logs to CloudWatch. Instead, you\nneed to manually configure a sidecar <code>fluentd</code> container that forwards the log entries to CloudWatch Logs.</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-i-upgrade-the-kubernetes-version-of-the-cluster\">How do I upgrade the Kubernetes Version of the cluster?</h2>\n<p>To upgrade the minor version of Kubernetes deployed on the EKS cluster, you need to update the <code>kubernetes_version</code>\ninput variable. <strong>You must upgrade one minor version at a time</strong>, as EKS does not support upgrading by more than one\nminor version.</p>\n<p>When you bump minor versions, the module will automatically update the deployed Kubernetes components as described in\nthe <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html\" class=\"preview__body--description--blue\" target=\"_blank\">official upgrade guide</a>. This is handled\nwith the provided <code>upgrade_cluster</code> python binary, which will look up the deployed Kubernetes version and make the\nrequired <code>kubectl</code> calls to deploy the updated components.</p>\n<p>Note that you must update the nodes to use the corresponding <code>kubelet</code> version as well. This means that when you update\nminor versions, you will also need to update the AMIs used by the worker nodes to match the version and rotate the\nworkers. For more information on rotating worker nodes, refer to <a href=\"/repos/v0.14.0/terraform-aws-eks/modules/eks-cluster-workers/README.md#how-do-i-roll-out-an-update-to-the-instances\" class=\"preview__body--description--blue\">How do I roll out an update to the\ninstances?</a> in the <code>eks-cluster-workers</code>\nmodule README.</p>\n<h3 class=\"preview__body--subtitle\" id=\"python-helper-scripts\">Python Helper Scripts</h3>\n<p>This module contains various python helper scripts that are used to achieve enhanced functionality not available in\nTerraform. All these scripts are intended to be used as part of <a href=\"https://www.terraform.io/docs/provisioners/local-exec.html\" class=\"preview__body--description--blue\" target=\"_blank\">local-exec\nprovisioner</a>. In order to support disabling the scripts, we\nuse a <a href=\"https://www.terraform.io/docs/provisioners/null_resource.html\" class=\"preview__body--description--blue\" target=\"_blank\">null_resource</a> to wrap the provisioner. See this\nmodule's <a href=\"/repos/v0.14.0/terraform-aws-eks/modules/eks-cluster-control-plane/main.tf\" class=\"preview__body--description--blue\">main.tf file</a> for example usage.</p>\n<p>Since this is a python script, The operator machine must have a valid python interpreter available in the <code>PATH</code> under\nthe name <code>python</code>. The scripts support python versions 2.7, 3.5, 3.6, 3.7, and 3.8, on Mac OSX or Linux.</p>\n<p>Below is an overview of the scripts:</p>\n<ul>\n<li><code>upgrade_cluster</code>: Update the core Kubernetes applications deployed on to an EKS cluster to ensure that the versions\nmatch with the expected versions deployed for the configured Kubernetes version.</li>\n<li><code>cleanup_cluster_resources</code>: Clean up any residual resources managed by the EKS cluster that may be remaining after\nthe cluster is destroyed. This is used to workaround terraform and kubernetes limitations that may leave managed\nresources behind.</li>\n</ul>\n<h4 id=\"building-the-script-environment\">Building the script environment</h4>\n<p>Dealing with python requirements in a portable manner is tricky. On one hand, we can have everyone install the necessary\nrequirements using <code>pip</code>. On the other hand, adding this extra step for a tool like terraform is difficult and we\ncertainly don't want to pollute a user's existing python setup. To workaround this, we use a utility called\n<a href=\"https://pex.readthedocs.io/en/stable/whatispex.html\" class=\"preview__body--description--blue\" target=\"_blank\"><code>pex</code></a>. Pex will package the python script with all its\nrequirements into a single binary as a virtual environment that is unpacked at runtime. This Pex environment can also be\nmade to be compatible with multiple versions of python and multiple OS platforms, making it a portable python runtime\nenvironment for all our scripts. This module distributes the Pex binary so that it is available to terraform when the\nmodule is invoked.</p>\n<p>Since the Pex binary only contains the requirements, the binary only needs to be built when the requirements change. You\ndo not need to rebuild the binary for any changes to the source files in the <code>upgrade_cluster</code> or\n<code>cleanup_cluster_resources</code> library.</p>\n<p>To build the binary, you will need the following:</p>\n<ul>\n<li>A working python environment with <strong>all compatible versions of python</strong> setup (so that you can build binaries for all\nversions)</li>\n<li>tox and pex installed (use <code>pip install -r dev_requirements.txt</code>)</li>\n</ul>\n<p>You can then build the binary using the helper script <code>build.sh</code> which will build the binary and copy it to the <code>bin</code>\ndirectory for distribution. After that, you just need to check in the updated binaries.</p>\n<p>It is recommended to use <a href=\"https://github.com/pyenv/pyenv\" class=\"preview__body--description--blue\" target=\"_blank\"><code>pyenv</code></a> to help setup an environment with multiple python\ninterpreters. The latest binaries are built with the following python environment:</p>\n<pre>pyenv shell <span class=\"hljs-number\">2.7</span><span class=\"hljs-number\">.15</span> <span class=\"hljs-number\">3.5</span><span class=\"hljs-number\">.2</span> <span class=\"hljs-number\">3.6</span><span class=\"hljs-number\">.6</span> <span class=\"hljs-number\">3.7</span><span class=\"hljs-number\">.0</span> <span class=\"hljs-number\">3.8</span><span class=\"hljs-number\">.1</span>\n</pre>\n","repoName":"terraform-aws-eks","repoRef":"v0.14.0","serviceDescriptor":{"serviceName":"EC2 Kubernetes Service (EKS) Cluster","serviceRepoName":"terraform-aws-eks","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws"],"description":"Deploy a Kubernetes cluster on top of Amazon EC2 Kubernetes Service (EKS).","imageUrl":"eks.png","licenseType":"subscriber","technologies":["Terraform","Python","Bash"],"compliance":[],"tags":[""]},"serviceCategoryName":"Docker orchestration","fileName":"README.md","filePath":"/modules/eks-cluster-control-plane/README.md","title":"Repo Browser: EC2 Kubernetes Service (EKS) Cluster","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}