forked from jenkins-infra/aws
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheks-public-cluster.tf
278 lines (237 loc) · 9.7 KB
/
eks-public-cluster.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# Define a KMS main key to encrypt the EKS cluster
resource "aws_kms_key" "eks_public" {
description = "EKS Secret Encryption Key for the cluster ${local.public_cluster_name}"
enable_key_rotation = true
tags = {
associated_service = "eks/${local.public_cluster_name}"
}
}
# EKS Cluster definition
module "eks-public" {
source = "terraform-aws-modules/eks/aws"
version = "19.15.3"
cluster_name = local.public_cluster_name
# Kubernetes version in format '<MINOR>.<MINOR>', as per https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html
cluster_version = "1.25"
# Start is inclusive, end is exclusive (!): from index 3 to index 5 (https://www.terraform.io/language/functions/slice)
# We're using the 3 last private_subnets defined in vpc.tf for this cluster
subnet_ids = slice(module.vpc.private_subnets, 3, 6)
# Required to allow EKS service accounts to authenticate to AWS API through OIDC (and assume IAM roles)
# useful for autoscaler, EKS addons, NLB and any AWS API usage
# See list at https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-role-for-service-accounts-eks
enable_irsa = true
# Specifying the kubernetes provider to use for this cluster
# Note: this should be done AFTER initial cluster creation (bootstrap)
providers = {
kubernetes = kubernetes.eks-public
}
create_kms_key = false
cluster_encryption_config = {
provider_key_arn = aws_kms_key.eks_public.arn
resources = ["secrets"]
}
create_cluster_primary_security_group_tags = false
# Do not use interpolated values from `local` in either keys and values of provided tags (or `cluster_tags)
# To avoid having and implicit dependency to a resource not available when parsing the module (infamous errror `Error: Invalid for_each argument`)
# Ref. same error as having a `depends_on` in https://github.com/terraform-aws-modules/terraform-aws-eks/issues/2337
tags = {
Environment = "jenkins-infra-${terraform.workspace}"
GithubRepo = "aws"
GithubOrg = "jenkins-infra"
associated_service = "eks/eks-public"
}
# VPC is defined in vpc.tf
vpc_id = module.vpc.vpc_id
## Manage EKS addons with module - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon
# See new versions with `aws eks describe-addon-versions --kubernetes-version <k8s-version> --addon-name <addon>`
cluster_addons = {
# https://github.com/coredns/coredns/releases
coredns = {
addon_version = "v1.9.3-eksbuild.5"
}
# Kube-proxy on an Amazon EKS cluster has the same compatibility and skew policy as Kubernetes
# See https://kubernetes.io/releases/version-skew-policy/#kube-proxy
kube-proxy = {
addon_version = "v1.25.11-eksbuild.1"
}
# https://github.com/aws/amazon-vpc-cni-k8s/releases
vpc-cni = {
addon_version = "v1.13.2-eksbuild.1"
}
# https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/CHANGELOG.md
aws-ebs-csi-driver = {
addon_version = "v1.20.0-eksbuild.1"
service_account_role_arn = module.eks-public_irsa_ebs.iam_role_arn
}
}
eks_managed_node_group_defaults = {
instance_types = ["t3a.xlarge"]
capacity_type = "ON_DEMAND"
bootstrap_extra_args = "--kubelet-extra-args '--node-labels=node.kubernetes.io/lifecycle=normal'"
suspended_processes = ["AZRebalance"]
tags = {
"k8s.io/cluster-autoscaler/enabled" = true # Autoscaling enabled
"k8s.io/cluster-autoscaler/${local.public_cluster_name}" = "owned",
},
}
eks_managed_node_groups = {
# 1 subnet per node poole == 1 AZ per node pool
default_linux_az1 = {
# This worker pool is expected to host the "technical" services (such as the autoscaler, the load balancer controller, etc.) and the public services like artifact-caching-proxy
name = "eks-public-linux-az1"
min_size = 0
max_size = 4
desired_size = 2
subnet_ids = [element(module.vpc.private_subnets, 0)]
},
}
create_aws_auth_configmap = true
manage_aws_auth_configmap = true
cluster_endpoint_public_access = true
aws_auth_users = concat(local.configmap_iam_admin_accounts, [
# User used by infra.ci.jenkins.io to administrate the charts deployements with github.com/jenkins-infra/kubernetes-management
{
userarn = data.aws_iam_user.eks_public_charter.arn,
username = data.aws_iam_user.eks_public_charter.user_name,
groups = ["system:masters"],
},
])
aws_auth_accounts = [
local.aws_account_id,
]
}
## No restriction on the resources: either managed outside terraform, or already scoped by conditions
#tfsec:ignore:aws-iam-no-policy-wildcards
data "aws_iam_policy_document" "cluster_autoscaler_public" {
statement {
sid = "ec2"
effect = "Allow"
actions = [
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeInstanceTypes",
]
resources = ["*"]
}
statement {
sid = "ec2AutoScaling"
effect = "Allow"
actions = [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeTags",
]
resources = ["*"]
}
statement {
sid = "clusterAutoscalerOwn"
effect = "Allow"
actions = [
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"autoscaling:UpdateAutoScalingGroup",
]
resources = ["*"]
condition {
test = "StringEquals"
variable = "autoscaling:ResourceTag/kubernetes.io/cluster/${module.eks-public.cluster_name}"
values = ["owned"]
}
condition {
test = "StringEquals"
variable = "autoscaling:ResourceTag/k8s.io/cluster-autoscaler/enabled"
values = ["true"]
}
}
}
resource "aws_iam_policy" "cluster_autoscaler_public" {
name_prefix = "cluster-autoscaler-public"
description = "EKS cluster-autoscaler policy for cluster ${local.public_cluster_name}"
policy = data.aws_iam_policy_document.cluster_autoscaler_public.json
}
module "eks_iam_assumable_role_autoscaler_eks_public" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "5.28.0"
create_role = true
role_name = "${local.autoscaler_account_name}-eks-public"
provider_url = replace(module.eks-public.cluster_oidc_issuer_url, "https://", "")
role_policy_arns = [aws_iam_policy.cluster_autoscaler_public.arn]
oidc_fully_qualified_subjects = ["system:serviceaccount:${local.autoscaler_account_namespace}:${local.autoscaler_account_name}"]
tags = {
associated_service = "eks/${module.eks-public.cluster_name}"
}
}
module "eks-public_irsa_nlb" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "5.28.0"
create_role = true
role_name = "${local.nlb_account_name}-eks-public"
provider_url = replace(module.eks-public.cluster_oidc_issuer_url, "https://", "")
role_policy_arns = [aws_iam_policy.cluster_nlb.arn]
oidc_fully_qualified_subjects = ["system:serviceaccount:${local.nlb_account_namespace}:${local.nlb_account_name}"]
tags = {
associated_service = "eks/${module.eks-public.cluster_name}"
}
}
module "eks-public_irsa_ebs" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "5.28.0"
create_role = true
role_name = "${local.ebs_account_name}-eks-public"
provider_url = replace(module.eks-public.cluster_oidc_issuer_url, "https://", "")
role_policy_arns = [aws_iam_policy.ebs_csi.arn]
oidc_fully_qualified_audiences = ["sts.amazonaws.com"]
oidc_fully_qualified_subjects = ["system:serviceaccount:${local.ebs_account_namespace}:${local.ebs_account_name}"]
tags = {
associated_service = "eks/${module.eks-public.cluster_name}"
}
}
# Reference the existing user for administrating the charts from github.com/jenkins-infra/kubernetes-management
data "aws_iam_user" "eks_public_charter" {
user_name = "eks-public-charter"
}
# Reference to allow configuration of the Terraform's kubernetes provider (in providers.tf)
data "aws_eks_cluster_auth" "public-cluster" {
name = module.eks-public.cluster_name
}
# Elastic IPs used for the Public Load Balancer (so that the addresses never change)
resource "aws_eip" "lb_public" {
count = length(module.vpc.public_subnets)
vpc = true
tags = {
"Name" = "eks-public-loadbalancer-external-${count.index}"
}
}
# Custom Storage Classes to ensure that EBS PVC are bound to the correct availability zone
resource "kubernetes_storage_class" "ebs_sc" {
metadata {
name = "ebs-sc"
}
storage_provisioner = "ebs.csi.aws.com"
reclaim_policy = "Delete"
volume_binding_mode = "WaitForFirstConsumer"
allow_volume_expansion = true
allowed_topologies {
match_label_expressions {
key = "topology.ebs.csi.aws.com/zone"
values = ["us-east-2a"]
}
}
provider = kubernetes.eks-public
}
resource "kubernetes_storage_class" "ebs_sc_retain" {
metadata {
name = "ebs-sc-retain"
}
storage_provisioner = "ebs.csi.aws.com"
reclaim_policy = "Retain"
volume_binding_mode = "WaitForFirstConsumer"
allow_volume_expansion = true
allowed_topologies {
match_label_expressions {
key = "topology.ebs.csi.aws.com/zone"
values = ["us-east-2a"]
}
}
provider = kubernetes.eks-public
}