feat(aws): add Terraform module for Amazon EKS and DocumentDB setup

This commit is contained in:
Cédric Verstraeten
2026-08-06 12:21:27 +00:00
parent 442137cab2
commit 8c620ccf1f
11 changed files with 928 additions and 0 deletions

View File

@@ -1 +1,57 @@
# Amazon DocumentDB
[Amazon DocumentDB](https://aws.amazon.com/documentdb/) is a managed, MongoDB
compatible database. It can be used as the metadata store for Kerberos Hub
instead of a self-hosted MongoDB.
## Things to know
- **Not reachable from outside its VPC.** DocumentDB has no public endpoint, so
the Kerberos Hub services must run inside (or be peered with) the same VPC.
- **TLS is enabled by default.** Clients must trust the Amazon RDS certificate
authority bundle:
`https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem`.
- **Not every MongoDB feature is available.** Retryable writes, the MongoDB
Stable API, geospatial queries/indexes and complex `$lookup` pipelines are
unsupported. Set `mongodb.flavor: "documentdb"` and
`mongodb.retryWrites: "false"` in the hub chart so those code paths are
disabled.
## Provisioning
The [`amazon-eks-documentdb`](../amazon-eks-documentdb/README.md) Terraform
stack creates a VPC, an EKS cluster and a DocumentDB cluster with TLS enforced,
and outputs a ready to paste `mongodb` values block for the hub helm chart.
## Connecting Kerberos Hub
Configure the database through `mongodb.uri` (not `mongodb.host`) and point the
chart at the CA bundle:
```bash
curl -O https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
kubectl create secret generic mongodb-ca --from-file=global-bundle.pem -n kerberos-hub
```
```yaml
mongodb:
flavor: "documentdb"
retryWrites: "false"
uri: "mongodb://<user>:<password>@<cluster>.docdb.amazonaws.com:27017/?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false"
adminDatabase: "admin"
authenticationMechanism: "SCRAM-SHA-1"
tls:
enabled: true
existingSecret: "mongodb-ca"
caFileName: "global-bundle.pem"
mountPath: "/certs"
```
The chart mounts the bundle read-only into every workload that talks to
MongoDB and appends `tls=true&tlsCAFile=/certs/global-bundle.pem` to the
connection string.
## Related
- [`../amazon-eks-documentdb`](../amazon-eks-documentdb/README.md) — Terraform for EKS + DocumentDB
- [`../../overlays/documentdb`](../../overlays/documentdb) — Kustomize overlay using DocumentDB

View File

@@ -0,0 +1,12 @@
.terraform/
.terraform.lock.hcl
*.tfstate
*.tfstate.*
*.tfplan
crash.log
override.tf
override.tf.json
*_override.tf
*_override.tf.json
terraform.tfvars
*.auto.tfvars

View File

@@ -0,0 +1,236 @@
# Amazon EKS + DocumentDB (Terraform)
Terraform stack that creates a **basic Kubernetes cluster (EKS) and a managed
MongoDB-compatible database (Amazon DocumentDB) on AWS**, wired together so
Kerberos Hub can be installed on it straight away.
It is primarily meant as a **reproducible test environment** for the DocumentDB
support in the [`hub` helm chart](https://github.com/kerberos-io/helm-charts),
in particular the `mongodb.tls.*` values that mount the Amazon RDS certificate
authority bundle. It is deliberately small and cheap, not a hardened production
landing zone.
## What it creates
```mermaid
flowchart LR
subgraph VPC["VPC (10.20.0.0/16)"]
subgraph Public["Public subnets"]
NAT[NAT gateway]
LB[Load balancers]
end
subgraph Private["Private subnets"]
NODES[EKS managed node group]
DOCDB[(DocumentDB cluster<br/>TLS enforced)]
end
end
EKSCP[EKS control plane] --- NODES
NODES -- "27017 / TLS" --> DOCDB
NODES --> NAT
```
| Component | Details |
| --------- | ------- |
| VPC | Public + private subnets across 3 availability zones, internet gateway, NAT gateway |
| EKS | Managed control plane, one managed node group, `coredns`, `kube-proxy`, `vpc-cni`, `eks-pod-identity-agent` and `aws-ebs-csi-driver` add-ons (IRSA role included) |
| DocumentDB | Cluster + instances in the private subnets, encryption **at rest** (KMS) and **in transit** (`tls=enabled`), subnet group, cluster parameter group |
| Security | A dedicated security group that only allows port `27017` from the EKS worker node security group (plus any extra CIDRs you pass in) |
> [!IMPORTANT]
> DocumentDB has **no public endpoint**. It can only be reached from inside the
> VPC, which is why the workloads that talk to it must run on this cluster (or
> you must tunnel through a bastion host / VPN).
> [!WARNING]
> This stack costs money while it exists (EKS control plane, NAT gateway, EC2
> nodes, DocumentDB instances and storage). Run `terraform destroy` when you are
> done.
## Prerequisites
- [Terraform](https://developer.hashicorp.com/terraform/downloads) >= 1.5
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) v2, authenticated with permissions to create VPC, EKS, IAM and DocumentDB resources
- `kubectl` and `helm`
## Usage
```bash
cd deployment/modules/amazon-eks-documentdb
cp terraform.tfvars.example terraform.tfvars
$EDITOR terraform.tfvars
terraform init
terraform plan
terraform apply
```
Creating the cluster and the database takes a while (EKS and DocumentDB are
both slow to provision).
State is kept locally by default. For anything shared, add a backend, for
example:
```hcl
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "kerberos-hub/eks-documentdb.tfstate"
region = "eu-west-1"
}
}
```
### Connect kubectl
```bash
$(terraform output -raw update_kubeconfig_command)
kubectl get nodes
```
## Installing Kerberos Hub against DocumentDB
### 1. Create the certificate authority secret
DocumentDB presents a certificate signed by the Amazon RDS certificate
authority, so every client needs the bundle:
```bash
kubectl create namespace kerberos-hub
curl -O https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
kubectl create secret generic mongodb-ca \
--from-file=global-bundle.pem \
-n kerberos-hub
```
### 2. Generate the values
```bash
terraform output -raw hub_values_snippet > hub-documentdb-values.yaml
```
Which produces something like:
```yaml
mongodb:
flavor: "documentdb"
retryWrites: "false"
uri: "mongodb://kerberos:...@kerberos-hub-docdb.cluster-xxxx.eu-west-1.docdb.amazonaws.com:27017/?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false"
adminDatabase: "admin"
authenticationMechanism: "SCRAM-SHA-1"
tls:
enabled: true
existingSecret: "mongodb-ca"
caFileName: "global-bundle.pem"
mountPath: "/certs"
```
The chart mounts the bundle into every workload that talks to MongoDB, appends
`tls=true&tlsCAFile=/certs/global-bundle.pem` to the URI, and exposes
`MONGODB_TLS`, `MONGODB_TLS_CA_FILE` and `MONGODB_TLS_INSECURE_SKIP_VERIFY`
through the `mongodb-config` ConfigMap.
> [!NOTE]
> With DocumentDB you must configure the database through `mongodb.uri`, not
> through `mongodb.host` / `mongodb.username` / `mongodb.password`, so that the
> TLS parameters end up in the connection string that every service uses.
### 3. Install the chart
```bash
helm repo add kerberos https://charts.kerberos.io
helm install hub kerberos/hub \
-n kerberos-hub \
-f your-hub-values.yaml \
-f hub-documentdb-values.yaml
```
The `hub_values_snippet` output contains credentials, so treat the generated
file as a secret and do not commit it.
### 4. Verify
```bash
kubectl logs -n kerberos-hub deploy/hub-api | head -50
kubectl exec -n kerberos-hub deploy/hub-api -- ls -l /certs
```
A one-off connectivity check from inside the cluster:
```bash
kubectl run mongosh --rm -it --restart=Never -n kerberos-hub \
--image=mongodb/mongodb-community-server:7.0-ubi8 \
--overrides='{"spec":{"volumes":[{"name":"ca","secret":{"secretName":"mongodb-ca"}}],"containers":[{"name":"mongosh","image":"mongodb/mongodb-community-server:7.0-ubi8","stdin":true,"tty":true,"command":["mongosh"],"args":["'"$(terraform output -raw mongodb_uri)"'&tls=true&tlsCAFile=/certs/global-bundle.pem"],"volumeMounts":[{"name":"ca","mountPath":"/certs"}]}]}}'
```
## Persistent volumes
The EBS CSI driver is installed, but EKS ships `gp2` as the default storage
class. To use `gp3` instead:
```bash
kubectl patch storageclass gp2 -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
kubectl apply -f - <<'EOF'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
parameters:
type: gp3
EOF
```
## Tear down
```bash
# Remove the release first so its load balancers and volumes are cleaned up.
helm uninstall hub -n kerberos-hub
terraform destroy
```
## Inputs
The defaults are tuned for a small test stack. See [variables.tf](variables.tf)
for the full list; the ones you are most likely to change:
| Variable | Default | Description |
| -------- | ------- | ----------- |
| `name` | `kerberos-hub` | Name prefix for every resource |
| `region` | `eu-west-1` | AWS region |
| `vpc_cidr` | `10.20.0.0/16` | VPC CIDR block |
| `single_nat_gateway` | `true` | One shared NAT gateway (cheaper, not highly available) |
| `kubernetes_version` | `1.31` | EKS control plane version |
| `cluster_endpoint_public_access_cidrs` | `["0.0.0.0/0"]` | Who may reach the Kubernetes API, **narrow this down** |
| `node_instance_types` | `["t3.large"]` | Worker node instance types |
| `node_desired_size` | `2` | Number of worker nodes |
| `docdb_instance_class` | `db.t3.medium` | DocumentDB instance class |
| `docdb_instance_count` | `1` | Number of DocumentDB instances |
| `docdb_username` | `kerberos` | Master username |
| `docdb_password` | generated | Master password, generated when unset |
| `docdb_tls` | `true` | Enforce TLS on the cluster |
| `docdb_allowed_cidrs` | `[]` | Extra CIDRs allowed on port 27017 |
## Outputs
| Output | Description |
| ------ | ----------- |
| `cluster_name`, `cluster_endpoint` | EKS cluster identity |
| `update_kubeconfig_command` | Ready to run `aws eks update-kubeconfig ...` |
| `vpc_id`, `private_subnet_ids` | Networking identifiers |
| `docdb_endpoint`, `docdb_reader_endpoint`, `docdb_port` | DocumentDB connection details |
| `docdb_username`, `docdb_password` | Master credentials (password is sensitive) |
| `mongodb_uri` | Connection string for `mongodb.uri` (sensitive) |
| `hub_values_snippet` | Ready to paste helm values including the TLS block (sensitive) |
## Related
- [`../amazon-documentdb`](../amazon-documentdb/README.md) — using DocumentDB as the Kerberos Hub metadata store
- [`../../overlays/documentdb`](../../overlays/documentdb) — Kustomize overlay that deploys Kerberos Hub against DocumentDB
- [`../../README.k8s-managed.md`](../../README.k8s-managed.md) — installing on managed Kubernetes

View File

@@ -0,0 +1,122 @@
###############################################################################
# DocumentDB
#
# The cluster is created with TLS (encryption in transit) and encryption at
# rest enabled. Clients must trust the Amazon RDS certificate authority bundle:
#
# curl -O https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
#
# For Kerberos Hub that bundle is mounted through the helm chart's
# `mongodb.tls` values, see the README next to this file.
###############################################################################
resource "random_password" "docdb" {
count = var.docdb_password == null ? 1 : 0
length = 32
special = true
# DocumentDB rejects '/', '"' and '@' in the master password. '@' and '/'
# would also break the MongoDB connection string.
override_special = "!#$%&*()-_=+[]{}<>:?"
}
locals {
docdb_password = var.docdb_password != null ? var.docdb_password : random_password.docdb[0].result
}
resource "aws_security_group" "docdb" {
name = "${local.name}-docdb"
description = "MongoDB wire protocol access to the Kerberos Hub DocumentDB cluster"
vpc_id = module.vpc.vpc_id
tags = merge(local.tags, { Name = "${local.name}-docdb" })
}
resource "aws_vpc_security_group_ingress_rule" "docdb_from_eks_nodes" {
security_group_id = aws_security_group.docdb.id
description = "DocumentDB from the EKS worker nodes"
referenced_security_group_id = module.eks.node_security_group_id
ip_protocol = "tcp"
from_port = 27017
to_port = 27017
}
resource "aws_vpc_security_group_ingress_rule" "docdb_from_cidrs" {
for_each = toset(var.docdb_allowed_cidrs)
security_group_id = aws_security_group.docdb.id
description = "DocumentDB from ${each.value}"
cidr_ipv4 = each.value
ip_protocol = "tcp"
from_port = 27017
to_port = 27017
}
resource "aws_docdb_subnet_group" "this" {
name = "${local.name}-docdb"
description = "Private subnets of the Kerberos Hub VPC"
subnet_ids = module.vpc.private_subnets
tags = local.tags
}
resource "aws_docdb_cluster_parameter_group" "this" {
name = "${local.name}-docdb"
family = var.docdb_parameter_group_family
description = "Kerberos Hub DocumentDB parameters"
parameter {
name = "tls"
value = var.docdb_tls ? "enabled" : "disabled"
}
tags = local.tags
lifecycle {
create_before_destroy = true
}
}
resource "aws_docdb_cluster" "this" {
cluster_identifier = "${local.name}-docdb"
engine = "docdb"
engine_version = var.docdb_engine_version
port = 27017
master_username = var.docdb_username
master_password = local.docdb_password
db_subnet_group_name = aws_docdb_subnet_group.this.name
db_cluster_parameter_group_name = aws_docdb_cluster_parameter_group.this.name
vpc_security_group_ids = [aws_security_group.docdb.id]
storage_encrypted = true
kms_key_id = var.docdb_kms_key_id
backup_retention_period = var.docdb_backup_retention_period
preferred_backup_window = "02:00-04:00"
preferred_maintenance_window = "sun:04:30-sun:05:30"
enabled_cloudwatch_logs_exports = var.docdb_enabled_cloudwatch_logs_exports
deletion_protection = var.docdb_deletion_protection
skip_final_snapshot = var.docdb_skip_final_snapshot
final_snapshot_identifier = var.docdb_skip_final_snapshot ? null : "${local.name}-docdb-final"
tags = local.tags
}
resource "aws_docdb_cluster_instance" "this" {
count = var.docdb_instance_count
identifier = "${local.name}-docdb-${count.index}"
cluster_identifier = aws_docdb_cluster.this.id
instance_class = var.docdb_instance_class
auto_minor_version_upgrade = true
tags = local.tags
}

View File

@@ -0,0 +1,70 @@
###############################################################################
# EKS
###############################################################################
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.31"
cluster_name = local.name
cluster_version = var.kubernetes_version
cluster_endpoint_public_access = var.cluster_endpoint_public_access
cluster_endpoint_public_access_cidrs = var.cluster_endpoint_public_access_cidrs
# Give the identity running `terraform apply` cluster-admin, so that
# `aws eks update-kubeconfig` immediately works.
enable_cluster_creator_admin_permissions = true
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
cluster_addons = {
coredns = {}
kube-proxy = {}
vpc-cni = {}
eks-pod-identity-agent = {}
aws-ebs-csi-driver = {
service_account_role_arn = module.ebs_csi_irsa.iam_role_arn
}
}
eks_managed_node_groups = {
default = {
instance_types = var.node_instance_types
capacity_type = "ON_DEMAND"
min_size = var.node_min_size
max_size = var.node_max_size
desired_size = var.node_desired_size
disk_size = var.node_disk_size
}
}
tags = local.tags
}
###############################################################################
# EBS CSI driver
#
# Kerberos Hub's supporting components (RabbitMQ, VerneMQ, MinIO, ...) claim
# persistent volumes, so the cluster needs a working CSI driver.
###############################################################################
module "ebs_csi_irsa" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "~> 5.44"
role_name = "${local.name}-ebs-csi"
attach_ebs_csi_policy = true
oidc_providers = {
main = {
provider_arn = module.eks.oidc_provider_arn
namespace_service_accounts = ["kube-system:ebs-csi-controller-sa"]
}
}
tags = local.tags
}

View File

@@ -0,0 +1,124 @@
###############################################################################
# Cluster
###############################################################################
output "region" {
description = "AWS region the stack is deployed in."
value = var.region
}
output "cluster_name" {
description = "Name of the EKS cluster."
value = module.eks.cluster_name
}
output "cluster_endpoint" {
description = "Endpoint of the Kubernetes API server."
value = module.eks.cluster_endpoint
}
output "update_kubeconfig_command" {
description = "Command to point kubectl at the new cluster."
value = "aws eks update-kubeconfig --region ${var.region} --name ${module.eks.cluster_name}"
}
output "vpc_id" {
description = "ID of the VPC. DocumentDB is only reachable from inside this VPC."
value = module.vpc.vpc_id
}
output "private_subnet_ids" {
description = "IDs of the private subnets hosting the worker nodes and DocumentDB."
value = module.vpc.private_subnets
}
###############################################################################
# DocumentDB
###############################################################################
output "docdb_endpoint" {
description = "Cluster (writer) endpoint of the DocumentDB cluster."
value = aws_docdb_cluster.this.endpoint
}
output "docdb_reader_endpoint" {
description = "Reader endpoint of the DocumentDB cluster."
value = aws_docdb_cluster.this.reader_endpoint
}
output "docdb_port" {
description = "Port the DocumentDB cluster listens on."
value = aws_docdb_cluster.this.port
}
output "docdb_username" {
description = "DocumentDB master username."
value = aws_docdb_cluster.this.master_username
}
output "docdb_password" {
description = "DocumentDB master password. Read it with: terraform output -raw docdb_password"
value = local.docdb_password
sensitive = true
}
output "docdb_security_group_id" {
description = "Security group guarding the DocumentDB cluster."
value = aws_security_group.docdb.id
}
output "docdb_tls_enabled" {
description = "Whether TLS is enforced on the DocumentDB cluster."
value = var.docdb_tls
}
###############################################################################
# Kerberos Hub wiring
###############################################################################
output "mongodb_uri" {
description = <<-EOT
Connection string for the Kerberos Hub helm chart (`mongodb.uri`).
The chart appends `tls=true` and `tlsCAFile=...` itself when
`mongodb.tls.enabled=true`, so no TLS parameters are included here.
Read it with: terraform output -raw mongodb_uri
EOT
value = format(
"mongodb://%s:%s@%s:%d/?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false",
var.docdb_username,
urlencode(local.docdb_password),
aws_docdb_cluster.this.endpoint,
aws_docdb_cluster.this.port,
)
sensitive = true
}
output "hub_values_snippet" {
description = <<-EOT
Ready to paste values for the Kerberos Hub helm chart. Write it to a file with:
terraform output -raw hub_values_snippet > hub-documentdb-values.yaml
It expects the Amazon RDS CA bundle to be available as the `mongodb-ca` secret:
curl -O https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
kubectl create secret generic mongodb-ca --from-file=global-bundle.pem -n kerberos-hub
EOT
value = <<-EOT
mongodb:
# DocumentDB does not support geospatial queries, complex $lookup
# pipelines or retryable writes, hence the flavor and retryWrites below.
flavor: "documentdb"
retryWrites: "false"
uri: "mongodb://${var.docdb_username}:${urlencode(local.docdb_password)}@${aws_docdb_cluster.this.endpoint}:${aws_docdb_cluster.this.port}/?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false"
adminDatabase: "admin"
authenticationMechanism: "SCRAM-SHA-1"
tls:
enabled: ${var.docdb_tls}
existingSecret: "mongodb-ca"
caFileName: "global-bundle.pem"
mountPath: "/certs"
EOT
sensitive = true
}

View File

@@ -0,0 +1,33 @@
# Copy to terraform.tfvars and adjust.
name = "kerberos-hub"
region = "eu-west-1"
environment = "test"
# Networking
vpc_cidr = "10.20.0.0/16"
availability_zone_count = 3
single_nat_gateway = true
# EKS
kubernetes_version = "1.31"
# Restrict this to your office or VPN range.
cluster_endpoint_public_access_cidrs = ["0.0.0.0/0"]
node_instance_types = ["t3.large"]
node_desired_size = 2
node_min_size = 2
node_max_size = 4
# DocumentDB
docdb_engine_version = "5.0.0"
docdb_parameter_group_family = "docdb5.0"
docdb_instance_class = "db.t3.medium"
docdb_instance_count = 1
docdb_username = "kerberos"
# Leave docdb_password unset to have one generated:
# terraform output -raw docdb_password
docdb_tls = true
# Throwaway test stack settings, flip these for anything long lived.
docdb_deletion_protection = false
docdb_skip_final_snapshot = true

View File

@@ -0,0 +1,194 @@
###############################################################################
# General
###############################################################################
variable "name" {
description = "Name prefix used for every resource created by this stack."
type = string
default = "kerberos-hub"
validation {
condition = can(regex("^[a-z][a-z0-9-]{2,30}$", var.name))
error_message = "The name must be lowercase, start with a letter and contain only letters, digits and dashes (3-31 characters)."
}
}
variable "region" {
description = "AWS region to deploy into."
type = string
default = "eu-west-1"
}
variable "environment" {
description = "Environment label applied as a tag (for example test, staging, production)."
type = string
default = "test"
}
variable "tags" {
description = "Extra tags merged into every resource."
type = map(string)
default = {}
}
###############################################################################
# Networking
###############################################################################
variable "vpc_cidr" {
description = "CIDR block of the VPC. DocumentDB is only reachable from within this VPC."
type = string
default = "10.20.0.0/16"
}
variable "availability_zone_count" {
description = "Number of availability zones to spread the subnets over. DocumentDB requires at least two."
type = number
default = 3
validation {
condition = var.availability_zone_count >= 2 && var.availability_zone_count <= 4
error_message = "availability_zone_count must be between 2 and 4."
}
}
variable "single_nat_gateway" {
description = "Use one shared NAT gateway instead of one per availability zone. Cheaper, but not highly available."
type = bool
default = true
}
###############################################################################
# EKS
###############################################################################
variable "kubernetes_version" {
description = "Kubernetes version of the EKS control plane."
type = string
default = "1.31"
}
variable "cluster_endpoint_public_access" {
description = "Expose the Kubernetes API server publicly. Keep it on for a test cluster, restrict it with cluster_endpoint_public_access_cidrs."
type = bool
default = true
}
variable "cluster_endpoint_public_access_cidrs" {
description = "CIDR blocks allowed to reach the public Kubernetes API endpoint. Narrow this to your office/VPN range."
type = list(string)
default = ["0.0.0.0/0"]
}
variable "node_instance_types" {
description = "Instance types of the managed node group."
type = list(string)
default = ["t3.large"]
}
variable "node_desired_size" {
description = "Desired number of worker nodes."
type = number
default = 2
}
variable "node_min_size" {
description = "Minimum number of worker nodes."
type = number
default = 2
}
variable "node_max_size" {
description = "Maximum number of worker nodes."
type = number
default = 4
}
variable "node_disk_size" {
description = "EBS volume size (GiB) of each worker node."
type = number
default = 50
}
###############################################################################
# DocumentDB
###############################################################################
variable "docdb_engine_version" {
description = "DocumentDB engine version."
type = string
default = "5.0.0"
}
variable "docdb_parameter_group_family" {
description = "Parameter group family matching the engine version (docdb5.0, docdb4.0, ...)."
type = string
default = "docdb5.0"
}
variable "docdb_instance_class" {
description = "Instance class of the DocumentDB instances."
type = string
default = "db.t3.medium"
}
variable "docdb_instance_count" {
description = "Number of DocumentDB instances. One is enough for a test stack, use two or more for failover."
type = number
default = 1
}
variable "docdb_username" {
description = "DocumentDB master username. 'admin' and other reserved words are rejected by AWS."
type = string
default = "kerberos"
}
variable "docdb_password" {
description = "DocumentDB master password. Leave null to generate one; read it afterwards with 'terraform output -raw docdb_password'."
type = string
default = null
sensitive = true
}
variable "docdb_tls" {
description = "Enforce TLS (encryption in transit) on the cluster. Keep this enabled; it is the configuration the hub chart's mongodb.tls values are meant for."
type = bool
default = true
}
variable "docdb_kms_key_id" {
description = "KMS key ARN for encryption at rest. Leave null to use the AWS managed key."
type = string
default = null
}
variable "docdb_backup_retention_period" {
description = "Number of days automated backups are retained."
type = number
default = 1
}
variable "docdb_deletion_protection" {
description = "Prevent the cluster from being deleted. Keep false for a throwaway test stack."
type = bool
default = false
}
variable "docdb_skip_final_snapshot" {
description = "Skip the final snapshot on destroy. Keep true for a throwaway test stack."
type = bool
default = true
}
variable "docdb_enabled_cloudwatch_logs_exports" {
description = "Log types exported to CloudWatch (audit, profiler)."
type = list(string)
default = []
}
variable "docdb_allowed_cidrs" {
description = "Extra CIDR blocks allowed to reach DocumentDB on port 27017, on top of the EKS worker nodes (for example a bastion subnet)."
type = list(string)
default = []
}

View File

@@ -0,0 +1,18 @@
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.60"
}
random = {
source = "hashicorp/random"
version = ">= 3.6"
}
}
}
provider "aws" {
region = var.region
}

View File

@@ -0,0 +1,59 @@
locals {
name = var.name
tags = merge(
{
Project = "kerberos-hub"
Environment = var.environment
ManagedBy = "terraform"
Module = "deployment/modules/amazon-eks-documentdb"
},
var.tags,
)
azs = slice(data.aws_availability_zones.available.names, 0, var.availability_zone_count)
}
data "aws_availability_zones" "available" {
state = "available"
filter {
name = "opt-in-status"
values = ["opt-in-not-required"]
}
}
###############################################################################
# VPC
#
# DocumentDB has no public endpoint: it only listens inside the VPC. Both the
# EKS worker nodes and the DocumentDB instances therefore live in the private
# subnets, and the workers reach the internet (image pulls) through NAT.
###############################################################################
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.13"
name = "${local.name}-vpc"
cidr = var.vpc_cidr
azs = local.azs
private_subnets = [for index in range(var.availability_zone_count) : cidrsubnet(var.vpc_cidr, 4, index)]
public_subnets = [for index in range(var.availability_zone_count) : cidrsubnet(var.vpc_cidr, 4, index + 8)]
enable_nat_gateway = true
single_nat_gateway = var.single_nat_gateway
enable_dns_hostnames = true
enable_dns_support = true
public_subnet_tags = {
"kubernetes.io/role/elb" = "1"
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = "1"
}
tags = local.tags
}