forked from aws-ia/terraform-aws-eks-blueprints
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add transparent encryption with cilium and wiregaurd (aws-ia#1130)
Co-authored-by: Bryant Biggs <[email protected]>
- Loading branch information
Showing
11 changed files
with
429 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Transparent Encryption with Cilium and Wirguard | ||
|
||
This example shows how to provision an EKS cluster with: | ||
- Managed node group based on Bottlerocket AMI | ||
- Cilium configured in CNI chaining mode with VPC CNI and with Wiregaurd transparent encryption enabled | ||
|
||
## Reference Documentation: | ||
|
||
- [Cilium CNI Chaning Documentation](https://docs.cilium.io/en/v1.12/gettingstarted/cni-chaining-aws-cni/) | ||
- [Cilium Wiregaurd Encryption Documentation](https://docs.cilium.io/en/v1.12/gettingstarted/encryption-wireguard/) | ||
|
||
## Prerequisites: | ||
|
||
Ensure that you have the following tools installed locally: | ||
|
||
1. [aws cli](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) | ||
2. [kubectl](https://Kubernetes.io/docs/tasks/tools/) | ||
3. [terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) | ||
|
||
## Deploy | ||
|
||
To provision this example with a sample app for testing: | ||
|
||
```sh | ||
terraform init | ||
terraform apply | ||
``` | ||
|
||
To provision this example without sample app for testing: | ||
|
||
```sh | ||
terraform init | ||
terraform apply -var enable_example=false | ||
``` | ||
|
||
Enter `yes` at command prompt to apply | ||
|
||
## Validate | ||
|
||
The following command will update the `kubeconfig` on your local machine and allow you to interact with your EKS Cluster using `kubectl` to validate the deployment. | ||
|
||
1. Run `update-kubeconfig` command: | ||
|
||
```sh | ||
aws eks --region <REGION> update-kubeconfig --name <CLUSTER_NAME> | ||
``` | ||
|
||
2. List the daemonsets | ||
|
||
```sh | ||
kubectl get ds -n kube-system | ||
|
||
# Output should look something similar | ||
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE | ||
aws-node 2 2 2 2 2 <none> 156m | ||
cilium 2 2 2 2 2 kubernetes.io/os=linux 152m | ||
kube-proxy 2 2 2 2 2 <none> 156m | ||
``` | ||
|
||
3. Open a shell inside the cilium container | ||
|
||
```sh | ||
kubectl -n kube-system exec -ti ds/cilium -- bash | ||
``` | ||
|
||
4. Verify Encryption is enabled | ||
|
||
```sh | ||
cilium status | grep Encryption | ||
|
||
# Output should look something similar | ||
Encryption: Wireguard [cilium_wg0 (Pubkey: b2krgbHgaCsVWALMnFLiS/RekhhcE36PXEjQ7T8+mW0=, Port: 51871, Peers: 1)] | ||
``` | ||
|
||
5. Install tcpdump | ||
|
||
```sh | ||
apt-get update | ||
apt-get install -y tcpdump | ||
``` | ||
|
||
6. Start a packet capture and verify you don't see payload in clear text | ||
|
||
```sh | ||
tcpdump -A -c 3 -i cilium_wg0 | ||
|
||
# Output should look similar below (truncated for brevity) | ||
|
||
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode | ||
listening on cilium_wg0, link-type RAW (Raw IP), capture size 262144 bytes | ||
05:28:30.234209 IP ip-10-0-11-73.ec2.internal.58086 > ip-10-0-10-160.ec2.internal.http: Flags [S], seq 2831772984, win 62727, options [mss 8961,sackOK,TS val 3834644316 ecr 0,nop,wscale 7], length 0 | ||
E..<].@.?... | ||
..I | ||
. | ||
....P..m8........&.....#.... | ||
...\........ | ||
05:28:30.234306 IP ip-10-0-10-160.ec2.internal.http > ip-10-0-11-73.ec2.internal.58086: Flags [S.], seq 131501951, ack 2831772985, win 62643, options [mss 8961,sackOK,TS val 1959385110 ecr 3834644316,nop,wscale 7], length 0 | ||
E..<..@.?... | ||
. | ||
. | ||
..I.P........m9....*.....#.... | ||
t......\.... | ||
05:28:30.234930 IP ip-10-0-11-73.ec2.internal.58086 > ip-10-0-10-160.ec2.internal.http: Flags [.], ack 1, win 491, options [nop,nop,TS val 3834644317 ecr 1959385110], length 0 | ||
E..4].@.?... | ||
..I | ||
. | ||
....P..m9............... | ||
...]t... | ||
3 packets captured | ||
9 packets received by filter | ||
1 packet dropped by kernel | ||
``` | ||
7. Exit the container shell | ||
|
||
```sh | ||
exit | ||
``` | ||
|
||
## Destroy | ||
|
||
To teardown and remove the resources created in this example: | ||
|
||
```sh | ||
terraform destroy -target=module.eks_blueprints_kubernetes_addons -auto-approve | ||
terraform destroy -target=module.eks_blueprints -auto-approve | ||
terraform destroy -auto-approve | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
provider "aws" { | ||
region = local.region | ||
} | ||
|
||
provider "kubernetes" { | ||
host = module.eks_blueprints.eks_cluster_endpoint | ||
cluster_ca_certificate = base64decode(module.eks_blueprints.eks_cluster_certificate_authority_data) | ||
token = data.aws_eks_cluster_auth.this.token | ||
} | ||
|
||
provider "helm" { | ||
kubernetes { | ||
host = module.eks_blueprints.eks_cluster_endpoint | ||
cluster_ca_certificate = base64decode(module.eks_blueprints.eks_cluster_certificate_authority_data) | ||
token = data.aws_eks_cluster_auth.this.token | ||
} | ||
} | ||
|
||
provider "kubectl" { | ||
apply_retry_count = 10 | ||
host = module.eks_blueprints.eks_cluster_endpoint | ||
cluster_ca_certificate = base64decode(module.eks_blueprints.eks_cluster_certificate_authority_data) | ||
load_config_file = false | ||
token = data.aws_eks_cluster_auth.this.token | ||
} | ||
|
||
data "aws_eks_cluster_auth" "this" { | ||
name = module.eks_blueprints.eks_cluster_id | ||
} | ||
|
||
data "aws_availability_zones" "available" {} | ||
|
||
locals { | ||
name = basename(path.cwd) | ||
# var.cluster_name is for Terratest | ||
cluster_name = local.name | ||
cluster_version = "1.23" | ||
region = "us-west-2" | ||
|
||
vpc_cidr = "10.0.0.0/16" | ||
azs = slice(data.aws_availability_zones.available.names, 0, 3) | ||
|
||
tags = { | ||
Blueprint = local.name | ||
GithubRepo = "github.com/aws-ia/terraform-aws-eks-blueprints" | ||
} | ||
} | ||
|
||
#--------------------------------------------------------------- | ||
# EKS Blueprints | ||
#--------------------------------------------------------------- | ||
|
||
module "eks_blueprints" { | ||
source = "../.." | ||
|
||
cluster_name = local.cluster_name | ||
cluster_version = local.cluster_version | ||
|
||
vpc_id = module.vpc.vpc_id | ||
private_subnet_ids = module.vpc.private_subnets | ||
|
||
managed_node_groups = { | ||
# BottleRocket ships with kernel 5.10 so there is no need | ||
# to do anything special | ||
bottlerocket = { | ||
node_group_name = "mg5" | ||
instance_types = ["m5.large"] | ||
min_size = 2 | ||
desired_size = 2 | ||
max_size = 2 | ||
ami_type = "BOTTLEROCKET_x86_64" | ||
subnet_ids = module.vpc.private_subnets | ||
} | ||
} | ||
|
||
tags = local.tags | ||
} | ||
|
||
module "eks_blueprints_kubernetes_addons" { | ||
source = "../../modules/kubernetes-addons" | ||
|
||
eks_cluster_id = module.eks_blueprints.eks_cluster_id | ||
eks_cluster_endpoint = module.eks_blueprints.eks_cluster_endpoint | ||
eks_oidc_provider = module.eks_blueprints.oidc_provider | ||
eks_cluster_version = module.eks_blueprints.eks_cluster_version | ||
|
||
# Wait on the `kube-system` profile before provisioning addons | ||
data_plane_wait_arn = module.eks_blueprints.managed_node_group_arn[0] | ||
|
||
# Add-ons | ||
enable_cilium = true | ||
cilium_enable_wireguard = true | ||
|
||
tags = local.tags | ||
} | ||
|
||
#--------------------------------------------------------------- | ||
# Supporting Resources | ||
#--------------------------------------------------------------- | ||
|
||
module "vpc" { | ||
source = "terraform-aws-modules/vpc/aws" | ||
version = "~> 3.0" | ||
|
||
name = local.name | ||
cidr = local.vpc_cidr | ||
|
||
azs = local.azs | ||
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] | ||
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 10)] | ||
|
||
enable_nat_gateway = true | ||
single_nat_gateway = true | ||
enable_dns_hostnames = true | ||
|
||
# Manage so we can name | ||
manage_default_network_acl = true | ||
default_network_acl_tags = { Name = "${local.name}-default" } | ||
manage_default_route_table = true | ||
default_route_table_tags = { Name = "${local.name}-default" } | ||
manage_default_security_group = true | ||
default_security_group_tags = { Name = "${local.name}-default" } | ||
|
||
public_subnet_tags = { | ||
"kubernetes.io/role/elb" = 1 | ||
} | ||
|
||
private_subnet_tags = { | ||
"kubernetes.io/role/internal-elb" = 1 | ||
} | ||
|
||
tags = local.tags | ||
} | ||
|
||
#--------------------------------------------------------------- | ||
# Sample App for Testing | ||
#--------------------------------------------------------------- | ||
|
||
resource "kubectl_manifest" "server" { | ||
count = var.enable_example ? 1 : 0 | ||
|
||
yaml_body = yamlencode({ | ||
apiVersion = "v1" | ||
kind = "Pod" | ||
metadata = { | ||
name = "server" | ||
labels = { | ||
blog = "wireguard" | ||
name = "server" | ||
} | ||
} | ||
spec = { | ||
containers = [ | ||
{ | ||
name = "server" | ||
image = "nginx" | ||
} | ||
] | ||
topologySpreadConstraints = [ | ||
{ | ||
maxSkew = 1 | ||
topologyKey = "kubernetes.io/hostname" | ||
whenUnsatisfiable = "DoNotSchedule" | ||
labelSelector = { | ||
matchLabels = { | ||
blog = "wireguard" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
}) | ||
|
||
depends_on = [ | ||
module.eks_blueprints_kubernetes_addons | ||
] | ||
} | ||
|
||
resource "kubectl_manifest" "service" { | ||
count = var.enable_example ? 1 : 0 | ||
|
||
yaml_body = yamlencode({ | ||
apiVersion = "v1" | ||
kind = "Service" | ||
metadata = { | ||
name = "server" | ||
} | ||
spec = { | ||
selector = { | ||
name = "server" | ||
} | ||
ports = [ | ||
{ | ||
port = 80 | ||
} | ||
] | ||
} | ||
}) | ||
} | ||
|
||
resource "kubectl_manifest" "client" { | ||
count = var.enable_example ? 1 : 0 | ||
|
||
yaml_body = yamlencode({ | ||
apiVersion = "v1" | ||
kind = "Pod" | ||
metadata = { | ||
name = "client" | ||
labels = { | ||
blog = "wireguard" | ||
name = "client" | ||
} | ||
} | ||
spec = { | ||
containers = [ | ||
{ | ||
name = "client" | ||
image = "busybox" | ||
command = ["watch", "wget", "server"] | ||
} | ||
] | ||
topologySpreadConstraints = [ | ||
{ | ||
maxSkew = 1 | ||
topologyKey = "kubernetes.io/hostname" | ||
whenUnsatisfiable = "DoNotSchedule" | ||
labelSelector = { | ||
matchLabels = { | ||
blog = "wireguard" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
}) | ||
|
||
depends_on = [ | ||
kubectl_manifest.server[0] | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
output "configure_kubectl" { | ||
description = "Configure kubectl: make sure you're logged in with the correct AWS profile and run the following command to update your kubeconfig" | ||
value = module.eks_blueprints.configure_kubectl | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# tflint-ignore: terraform_unused_declarations | ||
variable "enable_example" { | ||
description = "Enable example to test this blueprint" | ||
type = bool | ||
default = true | ||
} |
Oops, something went wrong.