Tamedia Kubernetes as a Service (KaaS) Terraform Module¶
Opinionated Terraform module to deploy Kubernetes in AWS. Includes:
Managed Addons:
- EBS CSI
- VPC CNI
- CoreDNS
- KubeProxy
Components (installed by default):
Requirements¶
The module needs some resources to be deployed in order to operate correctly:
IAM service-linked roles
- AWSServiceRoleForEC2Spot
- AWSServiceRoleForEC2SpotFleet
Usage¶
module "k8s_platform" {
source = "tx-pts-dai/kubernetes-platform/aws"
# Pin this module to a specific version to avoid breaking changes
# version = "0.0.0"
name = "example-platform"
vpc = {
vpc_id = "vpc-12345678"
vpc_cidr = "10.0.0.0/16"
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
intra_subnets = ["10.0.3.0/24"]
}
tags = {
Environment = "sandbox"
GithubRepo = "terraform-aws-kubernetes-platform"
}
}
See the Examples below for more use cases
Upgrading Kubernetes Version¶
The Kubernetes version is configured via the kubernetes_version variable. The default version is updated with each module release.
To upgrade your cluster to a new Kubernetes version:
module "k8s_platform" {
source = "tx-pts-dai/kubernetes-platform/aws"
kubernetes_version = "1.34"
# ... other configuration
}
Important: Do not skip Kubernetes minor versions during upgrades. For example, upgrade from 1.32 → 1.33 → 1.34, not directly from 1.32 → 1.34.
Explanation and description of interesting use-cases¶
Why this module?
- To provide an AWS account with a K8s cluster with batteries included so that you can start deploying your workloads on a well-built foundation
- To encourage standardization and common practices
- To ease maintenance
Examples¶
- Complete - Includes creation of VPC, k8s cluster, addons and all the optional features.
- Datadog - EKS deployment with Datadog Operator integration
- Lacework - EKS deployment with Lacework integration
- Network - VPC deployment with custom subnets for kubernetes
Cleanup example deployments¶
Destroy Workflow - This manual workflow destroys deployed example deployments by selection the branch and the example to destroy.
Contributing¶
Pre-Commit¶
Installation: install pre-commit and execute pre-commit install. This will generate pre-commit hooks according to the config in .pre-commit-config.yaml
Before submitting a PR be sure to have used the pre-commit hooks or run: pre-commit run -a
The pre-commit command will run:
- Terraform fmt
- Terraform validate
- Terraform docs
- Terraform validate with tflint
- check for merge conflicts
- fix end of files
as described in the .pre-commit-config.yaml file
Requirements¶
| Name | Version |
|---|---|
| terraform | >= 1.10 |
| aws | >= 6.28 |
| helm | >= 3.0.2 |
| kubectl | >= 2.0.2 |
| kubernetes | >= 2.27 |
| time | >= 0.11 |
Providers¶
| Name | Version |
|---|---|
| aws | >= 6.28 |
| helm | >= 3.0.2 |
| kubernetes | >= 2.27 |
| time | >= 0.11 |
Modules¶
| Name | Source | Version |
|---|---|---|
| ack_capability | terraform-aws-modules/eks/aws//modules/capability | 21.15.1 |
| acm | terraform-aws-modules/acm/aws | 6.3.0 |
| argocd | ./modules/argocd | n/a |
| aws_ebs_csi_pod_identity | terraform-aws-modules/eks-pod-identity/aws | 2.7.0 |
| aws_gateway_controller_pod_identity | terraform-aws-modules/eks-pod-identity/aws | 2.7.0 |
| aws_lb_controller_pod_identity | terraform-aws-modules/eks-pod-identity/aws | 2.7.0 |
| aws_vpc_cni_pod_identity | terraform-aws-modules/eks-pod-identity/aws | 2.7.0 |
| ebs_csi_driver_irsa | terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts | 6.4.0 |
| eks | terraform-aws-modules/eks/aws | 21.15.1 |
| eks_addons | ./modules/eks-addons | n/a |
| external_dns_pod_identity | terraform-aws-modules/eks-pod-identity/aws | 2.7.0 |
| external_secrets_pod_identity | terraform-aws-modules/eks-pod-identity/aws | 2.7.0 |
| karpenter | terraform-aws-modules/eks/aws//modules/karpenter | 21.15.1 |
| karpenter_irsa | terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts | 6.4.0 |
| karpenter_security_group | ./modules/security-group | n/a |
| ssm | ./modules/ssm | n/a |
| vpc_cni_irsa | terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts | 6.4.0 |
Resources¶
Inputs¶
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| ack_iam_policy_arn | IAM policy ARN to attach to the ACK capability role. Defaults to AdministratorAccess if not specified. | string |
null |
no |
| acm_certificate | ACM certificate configuration for the domain(s). Controls domain name, alternative domain names, wildcard configuration, and validation behavior. Options include: - domain_name: Primary domain name for the certificate. If not provided, uses base_domain from other configuration. - subject_alternative_names: List of additional domain names to include in the certificate. - wildcard_certificates: When true, adds a wildcard prefix (*.) to all domains in the certificate. - prepend_stack_id: When true, prepends the stack identifier to each domain name. Only works after random_string is created. - wait_for_validation: When true, Terraform will wait for certificate validation to complete before proceeding. |
object({ |
{} |
no |
| argocd | Argo CD configurations | object({ |
{} |
no |
| base_domain | Base domain for the platform, used for ingress and ACM certificates | string |
null |
no |
| cluster_admins | Map of IAM roles to add as cluster admins role_arn: ARN of the IAM role to add as cluster admin role_name: Name of the IAM role to add as cluster admin kubernetes_groups: List of Kubernetes groups to add the role to (default: ["system:masters"]) role_arn and role_name are mutually exclusive, exactly one must be set. |
map(object({ |
{} |
no |
| create_addon_pod_identity_roles | Create addon pod identities roles. If set to true, all roles will be created | bool |
true |
no |
| eks | Map of EKS configurations including cluster settings and core addon customization. Cluster settings: - cluster_endpoint_public_access: Enable public access to cluster endpoint (default: true) - cluster_endpoint_private_access: Enable private access to cluster endpoint (default: true) - enable_cluster_creator_admin_permissions: Grant admin permissions to cluster creator (default: false) Core addon settings (vpc_cni, kube_proxy, eks_pod_identity_agent): - configuration_values: JSON string of addon configuration (merged with defaults for vpc-cni) Example: eks = { cluster_endpoint_public_access = false vpc_cni = { configuration_values = jsonencode({ env = { ENABLE_PREFIX_DELEGATION = "true" WARM_PREFIX_TARGET = "1" } }) } } |
any |
{} |
no |
| enable_ack | Enable ACK (AWS Controllers for Kubernetes) EKS capability. Note: AdministratorAccess is attached by default. Use ack_iam_policy_arn to override with a least-privilege policy. | bool |
true |
no |
| enable_acm_certificate | Enable ACM certificate | bool |
false |
no |
| enable_argocd | Enable Argo CD | bool |
false |
no |
| enable_fargate_fluentbit | Enable Fargate Fluentbit | bool |
true |
no |
| enable_sso_admin_auto_discovery | Enable automatic discovery of SSO admin roles. When disabled, only explicitly defined cluster_admins are used. | bool |
true |
no |
| enable_timestamp_id | Disable the timestamp-based ID generation. When true, uses a static ID instead of timestamp. | bool |
true |
no |
| extra_cluster_addons | Map of cluster addon configurations to enable for the cluster. Addon name can be the map keys or set with name. Addons are created after karpenter resources |
any |
{} |
no |
| extra_cluster_addons_timeouts | Create, update, and delete timeout configurations for the cluster addons | map(string) |
{} |
no |
| karpenter | Karpenter configurations | object({ |
{} |
no |
| karpenter_helm_set | List of Karpenter Helm set values | list(object({ |
[] |
no |
| karpenter_helm_values | List of Karpenter Helm values | list(string) |
[] |
no |
| karpenter_resources_helm_set | List of Karpenter Resources Helm set values | list(object({ |
[] |
no |
| karpenter_resources_helm_values | List of Karpenter Resources Helm values | list(string) |
[] |
no |
| kubernetes_access_roles | Map of reusable IAM roles that can be assumed by multiple principals. Creates standard roles that grant different levels of Kubernetes access. Supported predefined access_level values: - "view" -> AmazonEKSViewPolicy (read-only) - "edit" -> AmazonEKSEditPolicy (create/update resources) - "admin" -> AmazonEKSClusterAdminPolicy (full admin) - "custom" -> Use custom_policy_arns (list of policy ARNs) Example: { "readonly" = { controller_iam_role_arns = [ "arn:aws:iam::123456789012:role/backstage-prod", "arn:aws:iam::123456789012:role/ai-agent" ] access_level = "view" # Predefined: view, edit, admin, or custom scope = "cluster" # "cluster" or "namespace" namespaces = [] # required if scope = "namespace" } "developer" = { controller_iam_role_arns = ["arn:aws:iam::123456789012:role/dev-team"] access_level = "edit" scope = "namespace" namespaces = ["development", "staging"] } "ops-admin" = { controller_iam_role_arns = ["arn:aws:iam::123456789012:role/ops-team"] access_level = "admin" scope = "cluster" } "custom-access" = { controller_iam_role_arns = ["arn:aws:iam::123456789012:role/special-service"] access_level = "custom" custom_policy_arns = [ "arn:aws:eks::aws:cluster-access-policy/MyCustomPolicy" ] scope = "cluster" } } This creates: - {cluster}-k8s-readonly (view access) - {cluster}-k8s-developer (edit access on dev/staging namespaces) - {cluster}-k8s-ops-admin (full admin access) - {cluster}-k8s-custom-access (custom policies) |
map(object({ |
{} |
no |
| kubernetes_version | Kubernetes version for the EKS cluster (e.g., "1.34") | string |
"1.34" |
no |
| name | The name of the platform, a timestamp will be appended to this name to make the stack_name. If not provided, the name of the directory will be used. | string |
"" |
no |
| region | AWS region to use | string |
null |
no |
| tags | Default tags to apply to all resources | map(string) |
{} |
no |
| vpc | VPC configurations | object({ |
n/a | yes |
Outputs¶
| Name | Description |
|---|---|
| ack | Map of attributes for the ACK EKS capability |
| argocd | Map of attributes for the ArgoCD module |
| eks | Map of attributes for the EKS cluster |
| karpenter | Map of attributes for the Karpenter module |
| kubernetes_access_role_arns | Map of reusable Kubernetes access role names to their IAM role ARNs |
| kubernetes_access_roles | Detailed information about reusable Kubernetes access IAM roles |
Authors¶
Module is maintained by Alfredo Gottardo, David Beauvererd, Davide Cammarata, Francisco Ferreira, Roland Bapst and Samuel Wibrow
License¶
Apache 2 Licensed. See LICENSE for full details.