Skip to content

Commit d94a431

Browse files
committed
Initial commit
1 parent 2527aeb commit d94a431

File tree

9 files changed

+408
-2
lines changed

9 files changed

+408
-2
lines changed

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/.terraform/
2+
*.tfstate*
3+
*.auto.tfvars
4+
.terraform
5+
.terraform/*
6+
terraform.tfvars
7+
terraform.tfvars.example
8+
terraform.tfstate
9+
terraform.tfstate*
10+
kubeconfig-*
11+
ignore.tf

.pre-commit-config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
repos:
2+
- repo: git://github.com/antonbabenko/pre-commit-terraform
3+
rev: v1.43.0
4+
hooks:
5+
- id: terraform_fmt
6+
- id: terraform_docs
7+
- id: terraform_validate
8+
- id: terraform_tflint

README.md

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,52 @@
1-
# terraform-kubernetes-external-dns-aws-istio
2-
Terraform module to deploy and configure k8s external DNS with EKS and Istio
1+
# Kubernetes External DNS for AWS EKS
2+
3+
Terraform module [External DNS with Istio Gateway](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/istio.md) for aws.
4+
5+
## Usage
6+
7+
```
8+
module "external-dns-aws" {
9+
source = "gitizenme/external-dns-aws/kubernetes"
10+
version = "1.0.1"
11+
12+
domain = "my-domain.com"
13+
k8s_cluster_name = "cluster-name
14+
k8s_replicas = 2
15+
hosted_zone_id = "ROUTE53 ZONE ID"
16+
}
17+
```
18+
19+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
20+
## Requirements
21+
22+
| Name | Version |
23+
|------|---------|
24+
| terraform | >= 0.12 |
25+
26+
## Providers
27+
28+
| Name | Version |
29+
|------|---------|
30+
| aws | n/a |
31+
| kubernetes | n/a |
32+
33+
## Inputs
34+
35+
| Name | Description | Type | Default | Required |
36+
|------|-------------|------|---------|:--------:|
37+
| domain | Domain to add external DNS to | `string` | n/a | yes |
38+
| k8s\_cluster\_name | Current Cluster Name | `string` | n/a | yes |
39+
| hosted\_zone\_id | Route53 Hosted Zone ID | `string` | n/a | yes |
40+
| external\_dns\_version | The AWS External DNS version to use. See https://github.com/kubernetes-sigs/external-dns/releases for available versions | `string` | `"0.7.6"` | no |
41+
| k8s\_cluster\_type | K8s cluster Type | `string` | `"eks"` | no |
42+
| k8s\_namespace | Kubernetes namespace to deploy the AWS External DNS into. | `string` | `"kube-system"` | no |
43+
| k8s\_pod\_labels | Additional labels to be added to the Pods. | `map(string)` | `{}` | no |
44+
| k8s\_replicas | Amount of replicas to be created. | `number` | `1` | no |
45+
46+
## Outputs
47+
48+
| Name | Description |
49+
|------|-------------|
50+
| kubernetes\_deployment | n/a |
51+
52+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

iam.tf

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
data "aws_caller_identity" "current" {}
2+
3+
data "aws_iam_policy_document" "eks_assume_role" {
4+
statement {
5+
actions = ["sts:AssumeRole"]
6+
effect = "Allow"
7+
principals {
8+
identifiers = ["eks.amazonaws.com"]
9+
type = "Service"
10+
}
11+
}
12+
}
13+
14+
resource "aws_iam_role" "external_dns" {
15+
name = "eks-external-dns"
16+
description = "Permissions required by the Kubernetes AWS EKS External Name controller to do it's job."
17+
path = "/"
18+
19+
assume_role_policy = data.aws_iam_policy_document.eks_assume_role.json
20+
}
21+
22+
data "aws_iam_policy_document" "external_dns" {
23+
statement {
24+
actions = [
25+
"route53:ChangeResourceRecordSets",
26+
]
27+
28+
resources = ["arn:aws:route53:::hostedzone/*"]
29+
}
30+
statement {
31+
actions = [
32+
"route53:ListHostedZones",
33+
"route53:ListResourceRecordSets",
34+
]
35+
36+
resources = ["*"]
37+
}
38+
}
39+
40+
resource "aws_iam_policy" "external_dns" {
41+
name = "external_dns"
42+
description = "Allows access to resources needed to run external dns."
43+
policy = data.aws_iam_policy_document.external_dns.json
44+
}
45+
46+
resource "aws_iam_role_policy_attachment" "external_dns" {
47+
role = aws_iam_role.external_dns.name
48+
policy_arn = aws_iam_policy.external_dns.arn
49+
}

kube2iam.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
data "aws_iam_policy_document" "kube2iam" {
2+
version = "2012-10-17"
3+
4+
statement {
5+
effect = "Allow"
6+
7+
actions = [
8+
"sts:AssumeRole",
9+
]
10+
11+
resources = ["*"]
12+
}
13+
}

main.tf

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
locals {
2+
external_dns_docker_image = "k8s.gcr.io/external-dns/external-dns:v${var.external_dns_version}"
3+
external_dns_version = var.external_dns_version
4+
}
5+
6+
7+
resource "kubernetes_service_account" "this" {
8+
automount_service_account_token = true
9+
metadata {
10+
name = "external-dns"
11+
namespace = var.k8s_namespace
12+
labels = {
13+
"app.kubernetes.io/name" = "external-dns"
14+
"app.kubernetes.io/managed-by" = "terraform"
15+
}
16+
}
17+
}
18+
19+
resource "kubernetes_cluster_role" "this" {
20+
metadata {
21+
name = "external-dns"
22+
23+
labels = {
24+
"app.kubernetes.io/name" = "external-dns"
25+
"app.kubernetes.io/managed-by" = "terraform"
26+
}
27+
}
28+
29+
rule {
30+
api_groups = [
31+
"",
32+
]
33+
34+
resources = [
35+
"endpoints",
36+
]
37+
38+
verbs = [
39+
"get",
40+
"list",
41+
"watch",
42+
]
43+
}
44+
45+
rule {
46+
api_groups = [
47+
"",
48+
]
49+
50+
resources = [
51+
"services",
52+
]
53+
54+
verbs = [
55+
"get",
56+
"list",
57+
"watch",
58+
]
59+
}
60+
61+
rule {
62+
api_groups = [
63+
"",
64+
]
65+
66+
resources = [
67+
"pods",
68+
]
69+
70+
verbs = [
71+
"get",
72+
"list",
73+
"watch",
74+
]
75+
}
76+
rule {
77+
api_groups = [
78+
"extensions",
79+
]
80+
81+
resources = [
82+
"ingresses",
83+
]
84+
85+
verbs = [
86+
"get",
87+
"watch",
88+
"list",
89+
]
90+
}
91+
rule {
92+
api_groups = [
93+
"",
94+
]
95+
96+
resources = [
97+
"nodes",
98+
]
99+
100+
verbs = [
101+
"list",
102+
"watch",
103+
]
104+
}
105+
}
106+
107+
resource "kubernetes_cluster_role_binding" "this" {
108+
metadata {
109+
name = "external-dns-viewer"
110+
111+
labels = {
112+
"app.kubernetes.io/name" = "external-dns"
113+
"app.kubernetes.io/managed-by" = "terraform"
114+
}
115+
}
116+
117+
role_ref {
118+
api_group = "rbac.authorization.k8s.io"
119+
kind = "ClusterRole"
120+
name = kubernetes_cluster_role.this.metadata[0].name
121+
}
122+
123+
subject {
124+
kind = "ServiceAccount"
125+
name = kubernetes_service_account.this.metadata[0].name
126+
namespace = kubernetes_service_account.this.metadata[0].namespace
127+
}
128+
}
129+
130+
resource "kubernetes_deployment" "this" {
131+
depends_on = [kubernetes_cluster_role_binding.this]
132+
133+
metadata {
134+
name = "external-dns"
135+
namespace = var.k8s_namespace
136+
137+
labels = {
138+
"app.kubernetes.io/name" = "external-dns"
139+
"app.kubernetes.io/version" = "v${local.external_dns_version}"
140+
"app.kubernetes.io/managed-by" = "terraform"
141+
}
142+
143+
annotations = {
144+
"field.cattle.io/description" = "AWS External DNS"
145+
}
146+
}
147+
148+
spec {
149+
150+
replicas = var.k8s_replicas
151+
152+
selector {
153+
match_labels = {
154+
"app.kubernetes.io/name" = "external-dns"
155+
}
156+
}
157+
158+
strategy {
159+
type = "Recreate"
160+
}
161+
162+
template {
163+
metadata {
164+
labels = merge(
165+
{
166+
"app.kubernetes.io/name" = "external-dns"
167+
"app.kubernetes.io/version" = local.external_dns_version
168+
},
169+
var.k8s_pod_labels
170+
)
171+
}
172+
173+
spec {
174+
affinity {
175+
pod_anti_affinity {
176+
preferred_during_scheduling_ignored_during_execution {
177+
weight = 100
178+
pod_affinity_term {
179+
label_selector {
180+
match_expressions {
181+
key = "app.kubernetes.io/name"
182+
operator = "In"
183+
values = ["external-dns"]
184+
}
185+
}
186+
topology_key = "kubernetes.io/hostname"
187+
}
188+
}
189+
}
190+
}
191+
192+
automount_service_account_token = true
193+
194+
dns_policy = "ClusterFirst"
195+
196+
restart_policy = "Always"
197+
198+
container {
199+
name = "server"
200+
image = local.external_dns_docker_image
201+
image_pull_policy = "Always"
202+
termination_message_path = "/dev/termination-log"
203+
204+
args = [
205+
"--source=service",
206+
"--source=ingress",
207+
"--domain-filter=${var.domain}",
208+
"--provider=aws",
209+
"--policy=upsert-only",
210+
"--aws-zone-type=public",
211+
"--registry=txt",
212+
"--txt-owner-id=${var.hosted_zone_id}",
213+
]
214+
}
215+
security_context {
216+
fs_group = 65534
217+
}
218+
219+
service_account_name = kubernetes_service_account.this.metadata[0].name
220+
termination_grace_period_seconds = 60
221+
}
222+
}
223+
}
224+
}

outputs.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
output "kubernetes_deployment" {
2+
value = "${kubernetes_deployment.this.metadata.0.namespace}/${kubernetes_deployment.this.metadata.0.name}"
3+
}

0 commit comments

Comments
 (0)