diff --git a/docs/patterns/istio-multi-cluster.md b/docs/patterns/istio-multi-cluster.md deleted file mode 100644 index edf5f16af7..0000000000 --- a/docs/patterns/istio-multi-cluster.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Istio - Multi-Cluster ---- - -{% - include-markdown "../../patterns/istio-multi-cluster/README.md" -%} diff --git a/patterns/istio-multi-cluster/0.certs-tool/.gitignore b/patterns/istio-multi-cluster/0.certs-tool/.gitignore deleted file mode 100644 index b2290143a4..0000000000 --- a/patterns/istio-multi-cluster/0.certs-tool/.gitignore +++ /dev/null @@ -1 +0,0 @@ -certs diff --git a/patterns/istio-multi-cluster/0.certs-tool/Makefile.k8s.mk b/patterns/istio-multi-cluster/0.certs-tool/Makefile.k8s.mk deleted file mode 100644 index 0a4777e43d..0000000000 --- a/patterns/istio-multi-cluster/0.certs-tool/Makefile.k8s.mk +++ /dev/null @@ -1,102 +0,0 @@ -.SUFFIXES: .csr .pem .conf -.PRECIOUS: %/ca-key.pem %/ca-cert.pem %/cert-chain.pem -.PRECIOUS: %/workload-cert.pem %/key.pem %/workload-cert-chain.pem -.SECONDARY: root-cert.csr root-ca.conf %/cluster-ca.csr %/intermediate.conf - -.DEFAULT_GOAL := help - -SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) - -include $(SELF_DIR)common.mk - -#------------------------------------------------------------------------ -##help: print this help message -.PHONY: help - -help: - @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/##//' - -#------------------------------------------------------------------------ -##fetch-root-ca: fetch root CA and key from a k8s cluster. -.PHONY: fetch-root-ca -rawcluster := $(shell kubectl config current-context) -cluster := $(subst /,-,$(rawcluster)) -pwd := $(shell pwd) -export KUBECONFIG - -fetch-root-ca: - @echo "fetching root ca from k8s cluster: "$(cluster)"" - @mkdir -p $(pwd)/$(cluster) - @res=$(shell kubectl get secret istio-ca-secret -n $(ISTIO-NAMESPACE) >/dev/null 2>&1; echo $$?) -ifeq ($(res), 1) - @kubectl get secret cacerts -n $(ISTIO_NAMESPACE) -o "jsonpath={.data['ca-cert\.pem']}" | base64 -d > $(cluster)/k8s-root-cert.pem - @kubectl get secret cacerts -n $(ISTIO_NAMESPACE) -o "jsonpath={.data['ca-key\.pem']}" | base64 -d > $(cluster)/k8s-root-key.pem -else - @kubectl get secret istio-ca-secret -n $(ISTIO_NAMESPACE) -o "jsonpath={.data['ca-cert\.pem']}" | base64 -d > $(cluster)/k8s-root-cert.pem - @kubectl get secret istio-ca-secret -n $(ISTIO_NAMESPACE) -o "jsonpath={.data['ca-key\.pem']}" | base64 -d > $(cluster)/k8s-root-key.pem -endif - -k8s-root-cert.pem: - @cat $(cluster)/k8s-root-cert.pem > $@ - -k8s-root-key.pem: - @cat $(cluster)/k8s-root-key.pem > $@ -#------------------------------------------------------------------------ -##-cacerts: generate intermediate certificates for a cluster or VM with signed with istio root cert from the specified k8s cluster and store them under directory -.PHONY: %-cacerts - -%-cacerts: %/cert-chain.pem - @echo "done" - -%/cert-chain.pem: %/ca-cert.pem k8s-root-cert.pem - @echo "generating $@" - @cat $^ > $@ - @echo "Intermediate certs stored in $(dir $<)" - @cp k8s-root-cert.pem $(dir $<)/root-cert.pem - -%/ca-cert.pem: %/cluster-ca.csr k8s-root-key.pem k8s-root-cert.pem - @echo "generating $@" - @openssl x509 -req -days $(INTERMEDIATE_DAYS) \ - -CA k8s-root-cert.pem -CAkey k8s-root-key.pem -CAcreateserial\ - -extensions req_ext -extfile $(dir $<)/intermediate.conf \ - -in $< -out $@ - -%/cluster-ca.csr: L=$(dir $@) -%/cluster-ca.csr: %/ca-key.pem %/intermediate.conf - @echo "generating $@" - @openssl req -new -config $(L)/intermediate.conf -key $< -out $@ - -%/ca-key.pem: fetch-root-ca - @echo "generating $@" - @mkdir -p $(dir $@) - @openssl genrsa -out $@ 4096 - -#------------------------------------------------------------------------ -##-certs: generate intermediate certificates and sign certificates for a virtual machine connected to the namespace ` using serviceAccount `$SERVICE_ACCOUNT` using root cert from k8s cluster. -.PHONY: %-certs - -%-certs: fetch-root-ca %/workload-cert-chain.pem k8s-root-cert.pem - @echo "done" - -%/workload-cert-chain.pem: k8s-root-cert.pem %/ca-cert.pem %/workload-cert.pem - @echo "generating $@" - @cat $^ > $@ - @echo "Intermediate and workload certs stored in $(dir $<)" - @cp k8s-root-cert.pem $(dir $@)/root-cert.pem - -%/workload-cert.pem: %/workload.csr - @echo "generating $@" - @openssl x509 -req -days $(WORKLOAD_DAYS) \ - -CA $(dir $<)/ca-cert.pem -CAkey $(dir $<)/ca-key.pem -CAcreateserial\ - -extensions req_ext -extfile $(dir $<)/workload.conf \ - -in $< -out $@ - -%/workload.csr: L=$(dir $@) -%/workload.csr: %/key.pem %/workload.conf - @echo "generating $@" - @openssl req -new -config $(L)/workload.conf -key $< -out $@ - -%/key.pem: - @echo "generating $@" - @mkdir -p $(dir $@) - @openssl genrsa -out $@ 4096 diff --git a/patterns/istio-multi-cluster/0.certs-tool/Makefile.selfsigned.mk b/patterns/istio-multi-cluster/0.certs-tool/Makefile.selfsigned.mk deleted file mode 100644 index 2a87d071f6..0000000000 --- a/patterns/istio-multi-cluster/0.certs-tool/Makefile.selfsigned.mk +++ /dev/null @@ -1,98 +0,0 @@ -.SUFFIXES: .csr .pem .conf -.PRECIOUS: %/ca-key.pem %/ca-cert.pem %/cert-chain.pem -.PRECIOUS: %/workload-cert.pem %/key.pem %/workload-cert-chain.pem -.SECONDARY: root-cert.csr root-ca.conf %/cluster-ca.csr %/intermediate.conf - -.DEFAULT_GOAL := help - -SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) - -include $(SELF_DIR)common.mk - -#------------------------------------------------------------------------ -##help: print this help message -.PHONY: help - -help: - @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/##//' - -#------------------------------------------------------------------------ -##root-ca: generate root CA files (key and certificate) in current directory. -.PHONY: root-ca - -root-ca: root-key.pem root-cert.pem - -root-cert.pem: root-cert.csr root-key.pem - @echo "generating $@" - @openssl x509 -req -sha256 -days $(ROOTCA_DAYS) -signkey root-key.pem \ - -extensions req_ext -extfile root-ca.conf \ - -in $< -out $@ - -root-cert.csr: root-key.pem root-ca.conf - @echo "generating $@" - @openssl req -sha256 -new -key $< -config root-ca.conf -out $@ - -root-key.pem: - @echo "generating $@" - @openssl genrsa -out $@ 4096 -#------------------------------------------------------------------------ -##-cacerts: generate self signed intermediate certificates for and store them under directory. -.PHONY: %-cacerts - -%-cacerts: %/cert-chain.pem - @echo "done" - -%/cert-chain.pem: %/ca-cert.pem root-cert.pem - @echo "generating $@" - @cat $^ > $@ - @echo "Intermediate inputs stored in $(dir $<)" - @cp root-cert.pem $(dir $<) - - -%/ca-cert.pem: %/cluster-ca.csr root-key.pem root-cert.pem - @echo "generating $@" - @openssl x509 -req -sha256 -days $(INTERMEDIATE_DAYS) \ - -CA root-cert.pem -CAkey root-key.pem -CAcreateserial\ - -extensions req_ext -extfile $(dir $<)/intermediate.conf \ - -in $< -out $@ - -%/cluster-ca.csr: L=$(dir $@) -%/cluster-ca.csr: %/ca-key.pem %/intermediate.conf - @echo "generating $@" - @openssl req -sha256 -new -config $(L)/intermediate.conf -key $< -out $@ - -%/ca-key.pem: - @echo "generating $@" - @mkdir -p $(dir $@) - @openssl genrsa -out $@ 4096 - -#------------------------------------------------------------------------ -##-certs: generate intermediate certificates and sign certificates for a virtual machine connected to the namespace ` using serviceAccount `$SERVICE_ACCOUNT` using self signed root certs. -.PHONY: %-certs - -%-certs: %/ca-cert.pem %/workload-cert-chain.pem root-cert.pem - @echo "done" - -%/workload-cert-chain.pem: %/workload-cert.pem %/ca-cert.pem root-cert.pem - @echo "generating $@" - @cat $^ > $@ - @echo "Intermediate and workload certs stored in $(dir $<)" - @cp root-cert.pem $(dir $@)/root-cert.pem - - -%/workload-cert.pem: %/workload.csr - @echo "generating $@" - @openssl x509 -sha256 -req -days $(WORKLOAD_DAYS) \ - -CA $(dir $<)/ca-cert.pem -CAkey $(dir $<)/ca-key.pem -CAcreateserial\ - -extensions req_ext -extfile $(dir $<)/workload.conf \ - -in $< -out $@ - -%/workload.csr: L=$(dir $@) -%/workload.csr: %/key.pem %/workload.conf - @echo "generating $@" - @openssl req -sha256 -new -config $(L)/workload.conf -key $< -out $@ - -%/key.pem: - @echo "generating $@" - @mkdir -p $(dir $@) - @openssl genrsa -out $@ 4096 diff --git a/patterns/istio-multi-cluster/0.certs-tool/README.md b/patterns/istio-multi-cluster/0.certs-tool/README.md deleted file mode 100644 index ad6dd42c21..0000000000 --- a/patterns/istio-multi-cluster/0.certs-tool/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Generating Certificates for Bootstrapping Multi-cluster / Mesh Expansion Chain of Trust - -The directory contains two Makefiles for generating new root, intermediate certificates and workload certificates: -- `Makefile.k8s.mk`: Creates certificates based on a root-ca from a k8s cluster. The current context in the default `kubeconfig` is used for accessing the cluster. -- `Makefile.selfsigned.mk`: Creates certificates based on a generated self-signed root. - -The table below describes the targets supported by both Makefiles. - -Make Target | Makefile | Description ------- | -------- | ----------- -`root-ca` | `Makefile.selfsigned.mk` | Generates a self-signed root CA key and certificate. -`fetch-root-ca` | `Makefile.k8s.mk` | Fetches the Istio CA from the Kubernetes cluster, using the current context in the default `kubeconfig`. -`$NAME-cacerts` | Both | Generates intermediate certificates signed by the root CA for a cluster or VM with `$NAME` (e.g., `us-east`, `cluster01`, etc.). They are stored under `$NAME` directory. To differentiate between clusters, we include a `Location` (`L`) designation in the certificates `Subject` field, with the cluster's name. -`$NAMESPACE-certs` | Both | Generates intermediate certificates and sign certificates for a virtual machine connected to the namespace `$NAMESPACE` using serviceAccount `$SERVICE_ACCOUNT` using the root cert and store them under `$NAMESPACE` directory. -`clean` | Both | Removes any generated root certificates, keys, and intermediate files. - -For example: - -```bash -make -f Makefile.selfsigned.mk root-ca -``` - -Note that the Makefile generates long-lived intermediate certificates. While this might be -acceptable for demonstration purposes, a more realistic and secure deployment would use -short-lived and automatically renewed certificates for the intermediate CAs. diff --git a/patterns/istio-multi-cluster/0.certs-tool/common.mk b/patterns/istio-multi-cluster/0.certs-tool/common.mk deleted file mode 100644 index ba3f90c9d5..0000000000 --- a/patterns/istio-multi-cluster/0.certs-tool/common.mk +++ /dev/null @@ -1,101 +0,0 @@ -#------------------------------------------------------------------------ -# variables: root CA -ROOTCA_DAYS ?= 3650 -ROOTCA_KEYSZ ?= 4096 -ROOTCA_ORG ?= Istio -ROOTCA_CN ?= Root CA -KUBECONFIG ?= $(HOME)/.kube/config -ISTIO_NAMESPACE ?= istio-system -# Additional variables are defined in root-ca.conf target below. - -#------------------------------------------------------------------------ -# variables: intermediate CA -INTERMEDIATE_DAYS ?= 3650 -INTERMEDIATE_KEYSZ ?= 4096 -INTERMEDIATE_ORG ?= Istio -INTERMEDIATE_CN ?= Intermediate CA -INTERMEDIATE_SAN_DNS ?= istiod.istio-system.svc -# Additional variables are defined in %/intermediate.conf target below. - -#------------------------------------------------------------------------ -# variables: workload certs: eg VM -WORKLOAD_DAYS ?= 1 -SERVICE_ACCOUNT ?= default -WORKLOAD_CN ?= Workload - -#------------------------------------------------------------------------ -# variables: files to clean -FILES_TO_CLEAN+=k8s-root-cert.pem \ - k8s-root-cert.srl \ - k8s-root-key.pem root-ca.conf root-cert.csr root-cert.pem root-cert.srl root-key.pem -#------------------------------------------------------------------------ -# clean -.PHONY: clean - -clean: ## Cleans all the intermediate files and folders previously generated. - @rm -f $(FILES_TO_CLEAN) - -root-ca.conf: - @echo "[ req ]" > $@ - @echo "encrypt_key = no" >> $@ - @echo "prompt = no" >> $@ - @echo "utf8 = yes" >> $@ - @echo "default_md = sha256" >> $@ - @echo "default_bits = $(ROOTCA_KEYSZ)" >> $@ - @echo "req_extensions = req_ext" >> $@ - @echo "x509_extensions = req_ext" >> $@ - @echo "distinguished_name = req_dn" >> $@ - @echo "[ req_ext ]" >> $@ - @echo "subjectKeyIdentifier = hash" >> $@ - @echo "basicConstraints = critical, CA:true" >> $@ - @echo "keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign" >> $@ - @echo "[ req_dn ]" >> $@ - @echo "O = $(ROOTCA_ORG)" >> $@ - @echo "CN = $(ROOTCA_CN)" >> $@ - -%/intermediate.conf: L=$(dir $@) -%/intermediate.conf: - @echo "[ req ]" > $@ - @echo "encrypt_key = no" >> $@ - @echo "prompt = no" >> $@ - @echo "utf8 = yes" >> $@ - @echo "default_md = sha256" >> $@ - @echo "default_bits = $(INTERMEDIATE_KEYSZ)" >> $@ - @echo "req_extensions = req_ext" >> $@ - @echo "x509_extensions = req_ext" >> $@ - @echo "distinguished_name = req_dn" >> $@ - @echo "[ req_ext ]" >> $@ - @echo "subjectKeyIdentifier = hash" >> $@ - @echo "basicConstraints = critical, CA:true, pathlen:0" >> $@ - @echo "keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign" >> $@ - @echo "subjectAltName=@san" >> $@ - @echo "[ san ]" >> $@ - @echo "DNS.1 = $(INTERMEDIATE_SAN_DNS)" >> $@ - @echo "[ req_dn ]" >> $@ - @echo "O = $(INTERMEDIATE_ORG)" >> $@ - @echo "CN = $(INTERMEDIATE_CN)" >> $@ - @echo "L = $(L:/=)" >> $@ - -%/workload.conf: L=$(dir $@) -%/workload.conf: - @echo "[ req ]" > $@ - @echo "encrypt_key = no" >> $@ - @echo "prompt = no" >> $@ - @echo "utf8 = yes" >> $@ - @echo "default_md = sha256" >> $@ - @echo "default_bits = $(INTERMEDIATE_KEYSZ)" >> $@ - @echo "req_extensions = req_ext" >> $@ - @echo "x509_extensions = req_ext" >> $@ - @echo "distinguished_name = req_dn" >> $@ - @echo "[ req_ext ]" >> $@ - @echo "subjectKeyIdentifier = hash" >> $@ - @echo "basicConstraints = critical, CA:false" >> $@ - @echo "keyUsage = digitalSignature, keyEncipherment" >> $@ - @echo "extendedKeyUsage = serverAuth, clientAuth" >> $@ - @echo "subjectAltName=@san" >> $@ - @echo "[ san ]" >> $@ - @echo "URI.1 = spiffe://cluster.local/ns/$(L)sa/$(SERVICE_ACCOUNT)" >> $@ - @echo "[ req_dn ]" >> $@ - @echo "O = $(INTERMEDIATE_ORG)" >> $@ - @echo "CN = $(WORKLOAD_CN)" >> $@ - @echo "L = $(L:/=)" >> $@ diff --git a/patterns/istio-multi-cluster/0.certs-tool/create-certs.sh b/patterns/istio-multi-cluster/0.certs-tool/create-certs.sh deleted file mode 100755 index 10a976abf6..0000000000 --- a/patterns/istio-multi-cluster/0.certs-tool/create-certs.sh +++ /dev/null @@ -1,6 +0,0 @@ -# https://istio.io/latest/docs/tasks/security/cert-management/plugin-ca-cert/#plug-in-certificates-and-key-into-the-cluster -mkdir certs -cd certs -make -f ../Makefile.selfsigned.mk root-ca -make -f ../Makefile.selfsigned.mk cluster-1-cacerts -make -f ../Makefile.selfsigned.mk cluster-2-cacerts diff --git a/patterns/istio-multi-cluster/0.vpc/main.tf b/patterns/istio-multi-cluster/0.vpc/main.tf deleted file mode 100644 index 79e24b7e61..0000000000 --- a/patterns/istio-multi-cluster/0.vpc/main.tf +++ /dev/null @@ -1,122 +0,0 @@ -provider "aws" { - region = local.region -} - -data "aws_availability_zones" "available" {} - -locals { - cluster_name = format("%s-%s", basename(path.cwd), "shared") - region = "eu-west-1" - - vpc_cidr = "10.0.0.0/16" - azs = slice(data.aws_availability_zones.available.names, 0, 3) - - tags = { - Blueprint = local.cluster_name - GithubRepo = "github.com/aws-ia/terraform-aws-eks-blueprints" - } -} - -################################################################################ -# VPC -################################################################################ - -module "vpc" { - source = "terraform-aws-modules/vpc/aws" - version = "~> 5.0" - - name = local.cluster_name - cidr = local.vpc_cidr - - azs = local.azs - private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)] - public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)] - - enable_nat_gateway = true - single_nat_gateway = true - - public_subnet_tags = { - "kubernetes.io/role/elb" = 1 - } - - private_subnet_tags = { - "kubernetes.io/role/internal-elb" = 1 - } - - tags = local.tags -} - -################################################################################ -# Cluster 1 additional security group for cross cluster communication -################################################################################ - -resource "aws_security_group" "cluster1_additional_sg" { - name = "cluster1_additional_sg" - description = "Allow communication from cluster2 SG to cluster1 SG" - vpc_id = module.vpc.vpc_id - tags = { - Name = "cluster1_additional_sg" - } -} - -resource "aws_vpc_security_group_egress_rule" "cluster1_additional_sg_allow_all_4" { - security_group_id = aws_security_group.cluster1_additional_sg.id - - ip_protocol = "-1" - cidr_ipv4 = "0.0.0.0/0" -} - -resource "aws_vpc_security_group_egress_rule" "cluster1_additional_sg_allow_all_6" { - security_group_id = aws_security_group.cluster1_additional_sg.id - - ip_protocol = "-1" - cidr_ipv6 = "::/0" -} - -################################################################################ -# Cluster 2 additional security group for cross cluster communication -################################################################################ - -resource "aws_security_group" "cluster2_additional_sg" { - name = "cluster2_additional_sg" - description = "Allow communication from cluster1 SG to cluster2 SG" - vpc_id = module.vpc.vpc_id - tags = { - Name = "cluster2_additional_sg" - } -} - -resource "aws_vpc_security_group_egress_rule" "cluster2_additional_sg_allow_all_4" { - security_group_id = aws_security_group.cluster2_additional_sg.id - - ip_protocol = "-1" - cidr_ipv4 = "0.0.0.0/0" -} -resource "aws_vpc_security_group_egress_rule" "cluster2_additional_sg_allow_all_6" { - security_group_id = aws_security_group.cluster2_additional_sg.id - - ip_protocol = "-1" - cidr_ipv6 = "::/0" -} - -################################################################################ -# cross SG ingress rules Cluster 2 allow to cluster 1 -################################################################################ - -resource "aws_vpc_security_group_ingress_rule" "cluster2_to_cluster_1" { - security_group_id = aws_security_group.cluster1_additional_sg.id - - referenced_security_group_id = aws_security_group.cluster2_additional_sg.id - ip_protocol = "-1" -} - -################################################################################ -# cross SG ingress rules Cluster 1 allow to cluster 2 -################################################################################ - -resource "aws_vpc_security_group_ingress_rule" "cluster1_to_cluster_2" { - security_group_id = aws_security_group.cluster2_additional_sg.id - - referenced_security_group_id = aws_security_group.cluster1_additional_sg.id - ip_protocol = "-1" -} diff --git a/patterns/istio-multi-cluster/0.vpc/outputs.tf b/patterns/istio-multi-cluster/0.vpc/outputs.tf deleted file mode 100644 index c6cbe85746..0000000000 --- a/patterns/istio-multi-cluster/0.vpc/outputs.tf +++ /dev/null @@ -1,24 +0,0 @@ -output "vpc_id" { - description = "Amazon EKS VPC ID" - value = module.vpc.vpc_id -} - -output "subnet_ids" { - description = "Amazon EKS Subnet IDs" - value = module.vpc.private_subnets -} - -output "vpc_cidr" { - description = "Amazon EKS VPC CIDR Block." - value = local.vpc_cidr -} - -output "cluster1_additional_sg_id" { - description = "Cluster1 additional SG" - value = aws_security_group.cluster1_additional_sg.id -} - -output "cluster2_additional_sg_id" { - description = "Cluster2 additional SG" - value = aws_security_group.cluster2_additional_sg.id -} diff --git a/patterns/istio-multi-cluster/0.vpc/variables.tf b/patterns/istio-multi-cluster/0.vpc/variables.tf deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/patterns/istio-multi-cluster/0.vpc/versions.tf b/patterns/istio-multi-cluster/0.vpc/versions.tf deleted file mode 100644 index 6cbf2a99e8..0000000000 --- a/patterns/istio-multi-cluster/0.vpc/versions.tf +++ /dev/null @@ -1,17 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.47" - } - } - - # ## Used for end-to-end testing on project; update to suit your needs - # backend "s3" { - # bucket = "" - # region = "" - # key = "e2e/istio-multi-cluster-vpc/terraform.tfstate" - # } -} diff --git a/patterns/istio-multi-cluster/1.cluster1/README.md b/patterns/istio-multi-cluster/1.cluster1/README.md deleted file mode 100644 index 695f28a43f..0000000000 --- a/patterns/istio-multi-cluster/1.cluster1/README.md +++ /dev/null @@ -1,249 +0,0 @@ -# Amazon EKS Cluster w/ Istio - -This example shows how to provision an EKS cluster with Istio. - -* Deploy EKS Cluster with one managed node group in an VPC -* Add node_security_group rules for port access required for Istio communication -* Install Istio using Helm resources in Terraform -* Install Istio Ingress Gateway using Helm resources in Terraform -* Deploy/Validate Istio communication using sample application - -Refer to the [documentation](https://istio.io/latest/docs/concepts/) for `Istio` concepts. - -## 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: - -```sh -terraform init -terraform apply -``` - -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 update-kubeconfig --name -``` - -2. List the nodes running currently - -```sh -kubectl get nodes -``` - -``` -# Output should look like below -NAME STATUS ROLES AGE VERSION -ip-10-0-22-173.ec2.internal Ready 48m v1.27.3-eks-a5565ad -``` - -3. List out the pods running currently: - -```sh -kubectl get pods,svc -n istio-system -``` - -``` -# Output should look like below -NAME READY STATUS RESTARTS AGE -pod/istio-ingress-6f7c5dffd8-4kww 1/1 Running 0 48m -pod/istiod-ff577f8b8-t9ww2 1/1 Running 0 48m - -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -service/istio-ingress LoadBalancer 172.20.100.3 a59363808e78d46d59bf3378cafffcec-a12f9c78cb607b6b.elb.us-east-1.amazonaws.com 15021:32118/TCP,80:32740/TCP,443:30624/TCP 48m -service/istiod ClusterIP 172.20.249.63 15010/TCP,15012/TCP,443/TCP,15014/TCP 48m -``` - -4. Verify all the helm releases installed for Istio: - -```sh -helm list -n istio-system -``` - -``` -# Output should look like below -NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION -istio-base istio-system 1 2023-07-19 11:05:41.599921 -0700 PDT deployed base-1.18.1 1.18.1 -istio-ingress istio-system 1 2023-07-19 11:06:03.41609 -0700 PDT deployed gateway-1.18.1 1.18.1 -istiod istio-system 1 2023-07-19 11:05:48.087616 -0700 PDT deployed istiod-1.18.1 1.18.1 -``` - -## Test - -1. Create the sample namespace and enable the sidecar injection for this namespace - -```sh -kubectl create namespace sample -kubectl label namespace sample istio-injection=enabled -``` - -``` -namespace/sample created -namespace/sample labeled -``` - -2. Deploy helloworld app - -```sh -cat < helloworld.yaml -apiVersion: v1 -kind: Service -metadata: - name: helloworld - labels: - app: helloworld - service: helloworld -spec: - ports: - - port: 5000 - name: http - selector: - app: helloworld ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: helloworld-v1 - labels: - app: helloworld - version: v1 -spec: - replicas: 1 - selector: - matchLabels: - app: helloworld - version: v1 - template: - metadata: - labels: - app: helloworld - version: v1 - spec: - containers: - - name: helloworld - image: docker.io/istio/examples-helloworld-v1 - resources: - requests: - cpu: "100m" - imagePullPolicy: IfNotPresent #Always - ports: - - containerPort: 5000 -EOF - -kubectl apply -f helloworld.yaml -n sample -``` - -``` -service/helloworld created -deployment.apps/helloworld-v1 created -``` - -3. Deploy sleep app that we will use to connect to helloworld app - -```sh -cat < sleep.yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: sleep ---- -apiVersion: v1 -kind: Service -metadata: - name: sleep - labels: - app: sleep - service: sleep -spec: - ports: - - port: 80 - name: http - selector: - app: sleep ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: sleep -spec: - replicas: 1 - selector: - matchLabels: - app: sleepdocs/blueprints/argocd.md - template: - metadata: - labels: - app: sleep - spec: - terminationGracePeriodSeconds: 0 - serviceAccountName: sleep - containers: - - name: sleep - image: curlimages/curl - command: ["/bin/sleep", "infinity"] - imagePullPolicy: IfNotPresent - volumeMounts: - - mountPath: /etc/sleep/tls - name: secret-volume - volumes: - - name: secret-volume - secret: - secretName: sleep-secret - optional: true -EOF - -kubectl apply -f sleep.yaml -n sample -``` - -``` -serviceaccount/sleep created -service/sleep created -deployment.apps/sleep created -``` - -4. Check all the pods in the `sample` namespace - -```sh -kubectl get pods -n sample -``` -``` -NAME READY STATUS RESTARTS AGE -helloworld-v1-b6c45f55-bx2xk 2/2 Running 0 50s -sleep-9454cc476-p2zxr 2/2 Running 0 15s -``` -5. Connect to helloworld app from sleep app and see the connectivity is using envoy proxy - -```sh -kubectl exec -n sample -c sleep \ - "$(kubectl get pod -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -v helloworld.sample:5000/hello -``` -``` -* processing: helloworld.sample:5000/hello - ... -* Connection #0 to host helloworld.sample left intact -``` - -## Destroy - -To teardown and remove the resources created in this example: - -```sh -terraform destroy -target="module.eks_blueprints_addons" -auto-approve -terraform destroy -auto-approve -``` diff --git a/patterns/istio-multi-cluster/1.cluster1/main.tf b/patterns/istio-multi-cluster/1.cluster1/main.tf deleted file mode 100644 index 0fcb4b57f1..0000000000 --- a/patterns/istio-multi-cluster/1.cluster1/main.tf +++ /dev/null @@ -1,269 +0,0 @@ -provider "aws" { - region = local.region -} - -data "terraform_remote_state" "vpc" { - backend = "local" - - config = { - path = "${path.module}/../0.vpc/terraform.tfstate" - } -} - -provider "kubernetes" { - host = module.eks.cluster_endpoint - cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) - - exec { - api_version = "client.authentication.k8s.io/v1beta1" - command = "aws" - # This requires the awscli to be installed locally where Terraform is executed - args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name] - } -} - -provider "helm" { - kubernetes { - host = module.eks.cluster_endpoint - cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) - - exec { - api_version = "client.authentication.k8s.io/v1beta1" - command = "aws" - # This requires the awscli to be installed locally where Terraform is executed - args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name] - } - } -} - -locals { - cluster_name = var.name - region = var.region - - cluster1_additional_sg_id = data.terraform_remote_state.vpc.outputs.cluster1_additional_sg_id - cluster2_additional_sg_id = data.terraform_remote_state.vpc.outputs.cluster2_additional_sg_id - - istio_chart_url = "https://istio-release.storage.googleapis.com/charts" - istio_chart_version = "1.18.2" - - tags = { - Blueprint = local.cluster_name - GithubRepo = "github.com/aws-ia/terraform-aws-eks-blueprints" - } -} - -################################################################################ -# Cluster -################################################################################ - -module "eks" { - source = "terraform-aws-modules/eks/aws" - version = "~> 19.16" - - cluster_name = local.cluster_name - cluster_version = "1.27" - cluster_endpoint_public_access = true - - # EKS Addons - cluster_addons = { - coredns = {} - kube-proxy = {} - vpc-cni = {} - } - - vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id - subnet_ids = data.terraform_remote_state.vpc.outputs.subnet_ids - - eks_managed_node_groups = { - cluster1 = { - instance_types = ["m5.large"] - - min_size = 1 - max_size = 5 - desired_size = 2 - vpc_security_group_ids = [local.cluster1_additional_sg_id] - } - } - - # SG Rule for nodes in cluster 2 to be able to reach to the cluster1 control plane - cluster_security_group_additional_rules = { - ingress_allow_from_other_cluster = { - description = "Access EKS from EC2 instances in other cluster." - protocol = "tcp" - from_port = 443 - to_port = 443 - type = "ingress" - source_security_group_id = local.cluster2_additional_sg_id - } - } - - # EKS K8s API cluster needs to be able to talk with the EKS worker nodes with port 15017/TCP and 15012/TCP which is used by Istio - # Istio in order to create sidecar needs to be able to communicate with webhook and for that network passage to EKS is needed. - node_security_group_additional_rules = { - ingress_15017 = { - description = "Cluster API - Istio Webhook namespace.sidecar-injector.istio.io" - protocol = "TCP" - from_port = 15017 - to_port = 15017 - type = "ingress" - source_cluster_security_group = true - } - ingress_15012 = { - description = "Cluster API to nodes ports/protocols" - protocol = "TCP" - from_port = 15012 - to_port = 15012 - type = "ingress" - source_cluster_security_group = true - } - } - - tags = local.tags -} - -################################################################################ -# EKS Blueprints Addons -################################################################################ - -module "addons" { - source = "aws-ia/eks-blueprints-addons/aws" - version = "~> 1.0" - - cluster_name = module.eks.cluster_name - cluster_endpoint = module.eks.cluster_endpoint - cluster_version = module.eks.cluster_version - oidc_provider_arn = module.eks.oidc_provider_arn - - # This is required to expose Istio Ingress Gateway - enable_aws_load_balancer_controller = true - enable_cert_manager = true - - tags = local.tags -} - -################################################################################ -# Istio -################################################################################ - -resource "kubernetes_namespace" "istio_system" { - metadata { - name = "istio-system" - labels = { - istio-injection = "enabled" - } - } -} - -resource "helm_release" "istio_base" { - - repository = local.istio_chart_url - chart = "base" - name = "istio-base" - namespace = kubernetes_namespace.istio_system.metadata[0].name - version = local.istio_chart_version - wait = false - - depends_on = [ - module.addons - ] -} - -resource "helm_release" "istiod" { - repository = local.istio_chart_url - chart = "istiod" - name = "istiod" - namespace = helm_release.istio_base.metadata[0].namespace - version = local.istio_chart_version - wait = false - - set { - name = "meshConfig.accessLogFile" - value = "/dev/stdout" - } - - set { - name = "global.multiCluster.clusterName" - value = local.cluster_name - } - - set { - name = "global.meshID" - value = local.cluster_name - } - - set { - name = "global.network" - value = local.cluster_name - } -} - -resource "helm_release" "istio_ingress" { - repository = local.istio_chart_url - chart = "gateway" - name = "istio-ingress" - namespace = helm_release.istiod.metadata[0].namespace - version = local.istio_chart_version - wait = false - - values = [ - yamlencode( - { - labels = { - istio = "ingressgateway" - } - service = { - annotations = { - "service.beta.kubernetes.io/aws-load-balancer-type" = "nlb" - "service.beta.kubernetes.io/aws-load-balancer-scheme" = "internet-facing" - } - } - } - ) - ] -} - -################################################################################ -# Isito certs for cross-cluster traffice -# https://istio.io/latest/docs/ops/deployment/deployment-models/#trust-within-a-mesh -# https://istio.io/latest/docs/ops/diagnostic-tools/multicluster/#trust-configuration -################################################################################ - -resource "kubernetes_secret" "cacerts" { - metadata { - name = "cacerts" - namespace = "istio-system" - } - - data = { - "ca-cert.pem" = file("${path.module}/../certs-tool/certs/${local.cluster_name}/ca-cert.pem") - "ca-key.pem" = file("${path.module}/../certs-tool/certs/${local.cluster_name}/ca-key.pem") - "root-cert.pem" = file("${path.module}/../certs-tool/certs/${local.cluster_name}/root-cert.pem") - "cert-chain.pem" = file("${path.module}/../certs-tool/certs/${local.cluster_name}/cert-chain.pem") - } -} - -################################################################################ -# Data source for Istio reader token -################################################################################ - -resource "kubernetes_secret" "istio_reader" { - depends_on = [module.addons, helm_release.istiod] - - metadata { - annotations = { - "kubernetes.io/service-account.name" = "istio-reader-service-account" - } - name = "istio-reader-service-account-istio-remote-secret-token" - namespace = "istio-system" - } - - type = "kubernetes.io/service-account-token" -} - -data "kubernetes_secret" "istio_reader" { - depends_on = [kubernetes_secret.istio_reader] - metadata { - name = "istio-reader-service-account-istio-remote-secret-token" - namespace = "istio-system" - } -} diff --git a/patterns/istio-multi-cluster/1.cluster1/outputs.tf b/patterns/istio-multi-cluster/1.cluster1/outputs.tf deleted file mode 100644 index 547f279483..0000000000 --- a/patterns/istio-multi-cluster/1.cluster1/outputs.tf +++ /dev/null @@ -1,36 +0,0 @@ -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 = "aws eks --region ${local.region} update-kubeconfig --name ${module.eks.cluster_name}" -} - -output "istio_reader_token" { - description = "Istio token for cross cluster auth" - value = data.kubernetes_secret.istio_reader.data["token"] - sensitive = true -} - -output "istio_reader_cacert" { - description = "Istio token for cross cluster auth" - value = data.kubernetes_secret.istio_reader.data["ca.crt"] - sensitive = true -} - -output "cluster_endpoint" { - description = "Cluster endpoint" - value = module.eks.cluster_endpoint -} - -output "cluster_certificate_authority_data" { - description = "Cluster ca certificate" - value = module.eks.cluster_certificate_authority_data -} - -output "cluster_name" { - description = "Cluster name" - value = module.eks.cluster_name -} - -output "cluster_region" { - description = "Cluster region" - value = local.region -} diff --git a/patterns/istio-multi-cluster/1.cluster1/variables.tf b/patterns/istio-multi-cluster/1.cluster1/variables.tf deleted file mode 100644 index cda81ee812..0000000000 --- a/patterns/istio-multi-cluster/1.cluster1/variables.tf +++ /dev/null @@ -1,12 +0,0 @@ - -variable "name" { - description = "cluster name" - type = string - default = "cluster-1" -} - -variable "region" { - description = "cluster name" - type = string - default = "eu-west-1" -} diff --git a/patterns/istio-multi-cluster/1.cluster1/versions.tf b/patterns/istio-multi-cluster/1.cluster1/versions.tf deleted file mode 100644 index 07b68ccbe0..0000000000 --- a/patterns/istio-multi-cluster/1.cluster1/versions.tf +++ /dev/null @@ -1,25 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.47" - } - helm = { - source = "hashicorp/helm" - version = ">= 2.9" - } - kubernetes = { - source = "hashicorp/kubernetes" - version = ">= 2.20" - } - } - - # ## Used for end-to-end testing on project; update to suit your needs - # backend "s3" { - # bucket = "" - # region = "" - # key = "e2e/istio-multi-cluster-vpc/terraform.tfstate" - # } -} diff --git a/patterns/istio-multi-cluster/2.cluster2/README.md b/patterns/istio-multi-cluster/2.cluster2/README.md deleted file mode 100644 index 45f0bb03bd..0000000000 --- a/patterns/istio-multi-cluster/2.cluster2/README.md +++ /dev/null @@ -1,267 +0,0 @@ -# Amazon EKS Cluster w/ Istio - -This example shows how to provision an EKS cluster with Istio. - -* Deploy EKS Cluster with one managed node group in an VPC -* Add node_security_group rules for port access required for Istio communication -* Install Istio using Helm resources in Terraform -* Install Istio Ingress Gateway using Helm resources in Terraform -* Deploy/Validate Istio communication using sample application - -Refer to the [documentation](https://istio.io/latest/docs/concepts/) for `Istio` concepts. - -## 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: - -```sh -terraform init -terraform apply -``` - -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 update-kubeconfig --name -``` - -2. List the nodes running currently - -```sh -kubectl get nodes -``` - -``` -# Output should look like below -NAME STATUS ROLES AGE VERSION -ip-10-0-22-173.ec2.internal Ready 48m v1.27.3-eks-a5565ad -``` - -3. List out the pods running currently: - -```sh -kubectl get pods,svc -n istio-system -``` - -``` -# Output should look like below -NAME READY STATUS RESTARTS AGE -pod/istio-ingress-6f7c5dffd8-chkww 1/1 Running 0 48m -pod/istiod-ff577f8b8-t9ww2 1/1 Running 0 48m - -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -service/istio-ingress LoadBalancer 172.20.100.3 a59363808e78d46d59bf3378cafffcec-a12f9c78cb607b6b.elb.us-east-1.amazonaws.com 15021:32118/TCP,80:32740/TCP,443:30624/TCP 48m -service/istiod ClusterIP 172.20.249.63 15010/TCP,15012/TCP,443/TCP,15014/TCP 48m -``` - -4. Verify all the helm releases installed for Istio: - -```sh -helm list -n istio-system -``` - -``` -# Output should look like below -NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION -istio-base istio-system 1 2023-07-19 11:05:41.599921 -0700 PDT deployed base-1.18.1 1.18.1 -istio-ingress istio-system 1 2023-07-19 11:06:03.41609 -0700 PDT deployed gateway-1.18.1 1.18.1 -istiod istio-system 1 2023-07-19 11:05:48.087616 -0700 PDT deployed istiod-1.18.1 1.18.1 -``` - -## Test - -1. Create the sample namespace and enable the sidecar injection for this namespace - -```sh -kubectl create namespace sample -kubectl label namespace sample istio-injection=enabled -``` - -``` -namespace/sample created -namespace/sample labeled -``` - -2. Deploy helloworld app - -```sh -cat < helloworld.yaml -apiVersion: v1 -kind: Service -metadata: - name: helloworld - labels: - app: helloworld - service: helloworld -spec: - ports: - - port: 5000 - name: http - selector: - app: helloworld ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: helloworld-v1 - labels: - app: helloworld - version: v1 -spec: - replicas: 1 - selector: - matchLabels: - app: helloworld - version: v1 - template: - metadata: - labels: - app: helloworld - version: v1 - spec: - containers: - - name: helloworld - image: docker.io/istio/examples-helloworld-v1 - resources: - requests: - cpu: "100m" - imagePullPolicy: IfNotPresent #Always - ports: - - containerPort: 5000 -EOF - -kubectl apply -f helloworld.yaml -n sample -``` - -``` -service/helloworld created -deployment.apps/helloworld-v1 created -``` - -3. Deploy sleep app that we will use to connect to helloworld app - -```sh -cat < sleep.yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: sleep ---- -apiVersion: v1 -kind: Service -metadata: - name: sleep - labels: - app: sleep - service: sleep -spec: - ports: - - port: 80 - name: http - selector: - app: sleep ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: sleep -spec: - replicas: 1 - selector: - matchLabels: - app: sleepdocs/blueprints/argocd.md - template: - metadata: - labels: - app: sleep - spec: - terminationGracePeriodSeconds: 0 - serviceAccountName: sleep - containers: - - name: sleep - image: curlimages/curl - command: ["/bin/sleep", "infinity"] - imagePullPolicy: IfNotPresent - volumeMounts: - - mountPath: /etc/sleep/tls - name: secret-volume - volumes: - - name: secret-volume - secret: - secretName: sleep-secret - optional: true -EOF - -kubectl apply -f sleep.yaml -n sample -``` - -``` -serviceaccount/sleep created -service/sleep created -deployment.apps/sleep created -``` - -4. Check all the pods in the `sample` namespace - -```sh -kubectl get pods -n sample -``` -``` -NAME READY STATUS RESTARTS AGE -helloworld-v1-b6c45f55-bx2xk 2/2 Running 0 50s -sleep-9454cc476-p2zxr 2/2 Running 0 15s -``` -5. Connect to helloworld app from sleep app and see the connectivity is using envoy proxy - -```sh -kubectl exec -n sample -c sleep \ - "$(kubectl get pod -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -v helloworld.sample:5000/hello -``` -``` -* processing: helloworld.sample:5000/hello - % Total % Received % Xferd Average Speed Time Time Time Current - Dload Upload Total Spent Left Speed - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 172.20.26.38:5000... -* Connected to helloworld.sample (172.20.26.38) port 5000 -> GET /hello HTTP/1.1 -> Host: helloworld.sample:5000 -> User-Agent: curl/8.2.0 -> Accept: */* -> -< HTTP/1.1 200 OK -< server: envoy -< date: Fri, 21 Jul 2023 18:56:09 GMT -< content-type: text/html; charset=utf-8 -< content-length: 58 -< x-envoy-upstream-service-time: 142 -< -{ [58 bytes data] -100 58 100 58 Hello version: v1, instance: helloworld-v1-b6c45f55-h592c - 0 0 392 0 --:--:-- --:--:-- --:--:-- 394 -* Connection #0 to host helloworld.sample left intact -``` - -## Destroy - -To teardown and remove the resources created in this example: - -```sh -terraform destroy -target="module.eks_blueprints_addons" -auto-approve -terraform destroy -auto-approve -``` diff --git a/patterns/istio-multi-cluster/2.cluster2/main.tf b/patterns/istio-multi-cluster/2.cluster2/main.tf deleted file mode 100644 index 27956e249e..0000000000 --- a/patterns/istio-multi-cluster/2.cluster2/main.tf +++ /dev/null @@ -1,269 +0,0 @@ -provider "aws" { - region = local.region -} - -data "terraform_remote_state" "vpc" { - backend = "local" - - config = { - path = "${path.module}/../0.vpc/terraform.tfstate" - } -} - -provider "kubernetes" { - host = module.eks.cluster_endpoint - cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) - - exec { - api_version = "client.authentication.k8s.io/v1beta1" - command = "aws" - # This requires the awscli to be installed locally where Terraform is executed - args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name] - } -} - -provider "helm" { - kubernetes { - host = module.eks.cluster_endpoint - cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) - - exec { - api_version = "client.authentication.k8s.io/v1beta1" - command = "aws" - # This requires the awscli to be installed locally where Terraform is executed - args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name] - } - } -} - -locals { - cluster_name = var.name - region = var.region - - cluster1_additional_sg_id = data.terraform_remote_state.vpc.outputs.cluster1_additional_sg_id - cluster2_additional_sg_id = data.terraform_remote_state.vpc.outputs.cluster2_additional_sg_id - - - istio_chart_url = "https://istio-release.storage.googleapis.com/charts" - istio_chart_version = "1.18.2" - - tags = { - Blueprint = local.cluster_name - GithubRepo = "github.com/aws-ia/terraform-aws-eks-blueprints" - } -} - -################################################################################ -# Cluster -################################################################################ - -module "eks" { - source = "terraform-aws-modules/eks/aws" - version = "~> 19.16" - - cluster_name = local.cluster_name - cluster_version = "1.27" - cluster_endpoint_public_access = true - - # EKS Addons - cluster_addons = { - coredns = {} - kube-proxy = {} - vpc-cni = {} - } - - vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id - subnet_ids = data.terraform_remote_state.vpc.outputs.subnet_ids - - eks_managed_node_groups = { - cluster2 = { - instance_types = ["m5.large"] - - min_size = 1 - max_size = 5 - desired_size = 2 - vpc_security_group_ids = [local.cluster2_additional_sg_id] - - } - } - # SG Rule for nodes in cluster 2 to be able to reach to the cluster1 control plane - cluster_security_group_additional_rules = { - ingress_allow_from_other_cluster = { - description = "Access EKS from EC2 instances in other cluster." - protocol = "tcp" - from_port = 443 - to_port = 443 - type = "ingress" - source_security_group_id = local.cluster1_additional_sg_id - } - } - - # EKS K8s API cluster needs to be able to talk with the EKS worker nodes with port 15017/TCP and 15012/TCP which is used by Istio - # Istio in order to create sidecar needs to be able to communicate with webhook and for that network passage to EKS is needed. - node_security_group_additional_rules = { - ingress_15017 = { - description = "Cluster API - Istio Webhook namespace.sidecar-injector.istio.io" - protocol = "TCP" - from_port = 15017 - to_port = 15017 - type = "ingress" - source_cluster_security_group = true - } - ingress_15012 = { - description = "Cluster API to nodes ports/protocols" - protocol = "TCP" - from_port = 15012 - to_port = 15012 - type = "ingress" - source_cluster_security_group = true - } - } - - tags = local.tags -} - -################################################################################ -# EKS Blueprints Addons -################################################################################ - -module "addons" { - source = "aws-ia/eks-blueprints-addons/aws" - version = "~> 1.0" - - cluster_name = module.eks.cluster_name - cluster_endpoint = module.eks.cluster_endpoint - cluster_version = module.eks.cluster_version - oidc_provider_arn = module.eks.oidc_provider_arn - - # This is required to expose Istio Ingress Gateway - enable_aws_load_balancer_controller = true - enable_cert_manager = true - - tags = local.tags -} - -################################################################################ -# Istio -################################################################################ - -resource "kubernetes_namespace" "istio_system" { - metadata { - name = "istio-system" - labels = { - istio-injection = "enabled" - } - } -} - -resource "helm_release" "istio_base" { - - repository = local.istio_chart_url - chart = "base" - name = "istio-base" - namespace = kubernetes_namespace.istio_system.metadata[0].name - version = local.istio_chart_version - wait = false - - depends_on = [ - module.addons - ] -} - -resource "helm_release" "istiod" { - repository = local.istio_chart_url - chart = "istiod" - name = "istiod" - namespace = helm_release.istio_base.metadata[0].namespace - version = local.istio_chart_version - wait = false - - set { - name = "meshConfig.accessLogFile" - value = "/dev/stdout" - } - - set { - name = "global.multiCluster.clusterName" - value = local.cluster_name - } - - set { - name = "global.meshID" - value = local.cluster_name - } - - set { - name = "global.network" - value = local.cluster_name - } -} - -resource "helm_release" "istio_ingress" { - repository = local.istio_chart_url - chart = "gateway" - name = "istio-ingress" - namespace = helm_release.istiod.metadata[0].namespace - version = local.istio_chart_version - wait = false - - values = [ - yamlencode( - { - labels = { - istio = "ingressgateway" - } - service = { - annotations = { - "service.beta.kubernetes.io/aws-load-balancer-type" = "nlb" - "service.beta.kubernetes.io/aws-load-balancer-scheme" = "internet-facing" - } - } - } - ) - ] -} - -################################################################################ -# Istio certs for cross-cluster traffic -# https://istio.io/latest/docs/ops/deployment/deployment-models/#trust-within-a-mesh -# https://istio.io/latest/docs/ops/diagnostic-tools/multicluster/#trust-configuration -################################################################################ - -resource "kubernetes_secret" "cacerts" { - metadata { - name = "cacerts" - namespace = "istio-system" - } - - data = { - "ca-cert.pem" = file("${path.module}/../certs-tool/certs/${local.cluster_name}/ca-cert.pem") - "ca-key.pem" = file("${path.module}/../certs-tool/certs/${local.cluster_name}/ca-key.pem") - "root-cert.pem" = file("${path.module}/../certs-tool/certs/${local.cluster_name}/root-cert.pem") - "cert-chain.pem" = file("${path.module}/../certs-tool/certs/${local.cluster_name}/cert-chain.pem") - } -} - -################################################################################ -# Data source for Istio reader token -################################################################################ - -resource "kubernetes_secret" "istio_reader" { - depends_on = [module.addons, helm_release.istiod] - metadata { - annotations = { - "kubernetes.io/service-account.name" = "istio-reader-service-account" - } - name = "istio-reader-service-account-istio-remote-secret-token" - namespace = "istio-system" - } - - type = "kubernetes.io/service-account-token" -} - -data "kubernetes_secret" "istio_reader_data" { - depends_on = [kubernetes_secret.istio_reader] - metadata { - name = "istio-reader-service-account-istio-remote-secret-token" - namespace = "istio-system" - } -} diff --git a/patterns/istio-multi-cluster/2.cluster2/outputs.tf b/patterns/istio-multi-cluster/2.cluster2/outputs.tf deleted file mode 100644 index 9193c9f887..0000000000 --- a/patterns/istio-multi-cluster/2.cluster2/outputs.tf +++ /dev/null @@ -1,36 +0,0 @@ -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 = "aws eks --region ${local.region} update-kubeconfig --name ${module.eks.cluster_name}" -} - -output "istio_reader_token" { - description = "Istio token for cross cluster auth" - value = data.kubernetes_secret.istio_reader_data.data["token"] - sensitive = true -} - -output "istio_reader_cacert" { - description = "Istio token for cross cluster auth" - value = data.kubernetes_secret.istio_reader_data.data["ca.crt"] - sensitive = true -} - -output "cluster_endpoint" { - description = "Cluster endpoint" - value = module.eks.cluster_endpoint -} - -output "cluster_certificate_authority_data" { - description = "Cluster ca certificate" - value = module.eks.cluster_certificate_authority_data -} - -output "cluster_name" { - description = "Cluster name" - value = module.eks.cluster_name -} - -output "cluster_region" { - description = "Cluster region" - value = local.region -} diff --git a/patterns/istio-multi-cluster/2.cluster2/variables.tf b/patterns/istio-multi-cluster/2.cluster2/variables.tf deleted file mode 100644 index 5c73a40427..0000000000 --- a/patterns/istio-multi-cluster/2.cluster2/variables.tf +++ /dev/null @@ -1,12 +0,0 @@ - -variable "name" { - description = "cluster name" - type = string - default = "cluster-2" -} - -variable "region" { - description = "cluster name" - type = string - default = "eu-west-1" -} diff --git a/patterns/istio-multi-cluster/2.cluster2/versions.tf b/patterns/istio-multi-cluster/2.cluster2/versions.tf deleted file mode 100644 index 07b68ccbe0..0000000000 --- a/patterns/istio-multi-cluster/2.cluster2/versions.tf +++ /dev/null @@ -1,25 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.47" - } - helm = { - source = "hashicorp/helm" - version = ">= 2.9" - } - kubernetes = { - source = "hashicorp/kubernetes" - version = ">= 2.20" - } - } - - # ## Used for end-to-end testing on project; update to suit your needs - # backend "s3" { - # bucket = "" - # region = "" - # key = "e2e/istio-multi-cluster-vpc/terraform.tfstate" - # } -} diff --git a/patterns/istio-multi-cluster/3.istio-multi-primary/istio-remote-secret.tftpl b/patterns/istio-multi-cluster/3.istio-multi-primary/istio-remote-secret.tftpl deleted file mode 100644 index e868022df0..0000000000 --- a/patterns/istio-multi-cluster/3.istio-multi-primary/istio-remote-secret.tftpl +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -clusters: -- cluster: - certificate-authority-data: ${cluster_certificate_authority_data} - server: ${cluster_host} - name: ${cluster_name} -contexts: -- context: - cluster: ${cluster_name} - user: ${cluster_name} - name: ${cluster_name} -current-context: ${cluster_name} -kind: Config -preferences: {} -users: -- name: ${cluster_name} - user: - token: ${cluster_istio_reader_token} diff --git a/patterns/istio-multi-cluster/3.istio-multi-primary/main.tf b/patterns/istio-multi-cluster/3.istio-multi-primary/main.tf deleted file mode 100644 index 0a43657927..0000000000 --- a/patterns/istio-multi-cluster/3.istio-multi-primary/main.tf +++ /dev/null @@ -1,98 +0,0 @@ -data "terraform_remote_state" "cluster1" { - backend = "local" - - config = { - path = "${path.module}/../1.cluster1/terraform.tfstate" - } -} - -provider "kubernetes" { - host = data.terraform_remote_state.cluster1.outputs.cluster_endpoint - cluster_ca_certificate = base64decode(data.terraform_remote_state.cluster1.outputs.cluster_certificate_authority_data) - - exec { - api_version = "client.authentication.k8s.io/v1beta1" - command = "aws" - args = ["eks", "get-token", "--cluster-name", data.terraform_remote_state.cluster1.outputs.cluster_name, "--region", data.terraform_remote_state.cluster1.outputs.cluster_region] - } - alias = "cluster1" -} - -data "terraform_remote_state" "cluster2" { - backend = "local" - - config = { - path = "${path.module}/../2.cluster2/terraform.tfstate" - } -} - -provider "kubernetes" { - host = data.terraform_remote_state.cluster2.outputs.cluster_endpoint - cluster_ca_certificate = base64decode(data.terraform_remote_state.cluster2.outputs.cluster_certificate_authority_data) - - exec { - api_version = "client.authentication.k8s.io/v1beta1" - command = "aws" - # This requires the awscli to be installed locally where Terraform is executed - args = ["eks", "get-token", "--cluster-name", data.terraform_remote_state.cluster2.outputs.cluster_name, "--region", data.terraform_remote_state.cluster2.outputs.cluster_region] - } - alias = "cluster2" -} - -################################################################################ -# Istio remote secret for cluster 1 (istioctl x create-remote-secret) -################################################################################ - -resource "kubernetes_secret" "istio_remote_secret_cluster2" { - provider = kubernetes.cluster1 - - metadata { - annotations = { - "kubernetes.io/service-account.name" = "istio-reader-service-account" - } - labels = { - "istio/multiCluster" = "true" - } - name = "istio-remote-secret-${data.terraform_remote_state.cluster2.outputs.cluster_name}" - namespace = "istio-system" - } - data = { - cluster1_name = templatefile("${path.module}/istio-remote-secret.tftpl", - { - cluster_certificate_authority_data = data.terraform_remote_state.cluster2.outputs.cluster_certificate_authority_data - cluster_host = data.terraform_remote_state.cluster2.outputs.cluster_endpoint - cluster_name = data.terraform_remote_state.cluster2.outputs.cluster_name - cluster_istio_reader_token = data.terraform_remote_state.cluster2.outputs.istio-reader-token - } - ) - } -} - -################################################################################ -# Istio remote secret for cluster 2 (istioctl x create-remote-secret) -################################################################################ - -resource "kubernetes_secret" "istio_remote_secret_cluster1" { - provider = kubernetes.cluster2 - - metadata { - annotations = { - "kubernetes.io/service-account.name" = "istio-reader-service-account" - } - labels = { - "istio/multiCluster" = "true" - } - name = "istio-remote-secret-${data.terraform_remote_state.cluster1.outputs.cluster_name}" - namespace = "istio-system" - } - data = { - cluster1_name = templatefile("${path.module}/istio-remote-secret.tftpl", - { - cluster_certificate_authority_data = data.terraform_remote_state.cluster1.outputs.cluster_certificate_authority_data - cluster_host = data.terraform_remote_state.cluster1.outputs.cluster_endpoint - cluster_name = data.terraform_remote_state.cluster1.outputs.cluster_name - cluster_istio_reader_token = data.terraform_remote_state.cluster1.outputs.istio-reader-token - } - ) - } -} diff --git a/patterns/istio-multi-cluster/3.istio-multi-primary/outputs.tf b/patterns/istio-multi-cluster/3.istio-multi-primary/outputs.tf deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/patterns/istio-multi-cluster/3.istio-multi-primary/variables.tf b/patterns/istio-multi-cluster/3.istio-multi-primary/variables.tf deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/patterns/istio-multi-cluster/3.istio-multi-primary/versions.tf b/patterns/istio-multi-cluster/3.istio-multi-primary/versions.tf deleted file mode 100644 index 629fc65f2d..0000000000 --- a/patterns/istio-multi-cluster/3.istio-multi-primary/versions.tf +++ /dev/null @@ -1,17 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - kubernetes = { - source = "hashicorp/kubernetes" - version = ">= 2.20" - } - } - - # ## Used for end-to-end testing on project; update to suit your needs - # backend "s3" { - # bucket = "terraform-ssp-github-actions-state" - # region = "us-west-2" - # key = "e2e/istio-multi-cluster-multi-primary-setup/terraform.tfstate" - # } -} diff --git a/patterns/istio-multi-cluster/4.test-connectivity/istio-helloworld.yaml b/patterns/istio-multi-cluster/4.test-connectivity/istio-helloworld.yaml deleted file mode 100644 index e870420e6d..0000000000 --- a/patterns/istio-multi-cluster/4.test-connectivity/istio-helloworld.yaml +++ /dev/null @@ -1,72 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: helloworld - labels: - app: helloworld - service: helloworld -spec: - ports: - - port: 5000 - name: http - selector: - app: helloworld ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: helloworld-v1 - labels: - app: helloworld - version: v1 -spec: - replicas: 1 - selector: - matchLabels: - app: helloworld - version: v1 - template: - metadata: - labels: - app: helloworld - version: v1 - spec: - containers: - - name: helloworld - image: docker.io/istio/examples-helloworld-v1 - resources: - requests: - cpu: "100m" - imagePullPolicy: IfNotPresent #Always - ports: - - containerPort: 5000 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: helloworld-v2 - labels: - app: helloworld - version: v2 -spec: - replicas: 1 - selector: - matchLabels: - app: helloworld - version: v2 - template: - metadata: - labels: - app: helloworld - version: v2 - spec: - containers: - - name: helloworld - image: docker.io/istio/examples-helloworld-v2 - resources: - requests: - cpu: "100m" - imagePullPolicy: IfNotPresent #Always - ports: - - containerPort: 5000 diff --git a/patterns/istio-multi-cluster/4.test-connectivity/istio-sleep.yaml b/patterns/istio-multi-cluster/4.test-connectivity/istio-sleep.yaml deleted file mode 100644 index 7ee33332a7..0000000000 --- a/patterns/istio-multi-cluster/4.test-connectivity/istio-sleep.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -# Copyright Istio Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -################################################################################################## -# Sleep service -################################################################################################## -apiVersion: v1 -kind: ServiceAccount -metadata: - name: sleep ---- -apiVersion: v1 -kind: Service -metadata: - name: sleep - labels: - app: sleep - service: sleep -spec: - ports: - - port: 80 - name: http - selector: - app: sleep ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: sleep -spec: - replicas: 1 - selector: - matchLabels: - app: sleep - template: - metadata: - labels: - app: sleep - spec: - terminationGracePeriodSeconds: 0 - serviceAccountName: sleep - containers: - - name: sleep - image: curlimages/curl - command: ["/bin/sleep", "infinity"] - imagePullPolicy: IfNotPresent - volumeMounts: - - mountPath: /etc/sleep/tls - name: secret-volume - volumes: - - name: secret-volume - secret: - secretName: sleep-secret - optional: true ---- diff --git a/patterns/istio-multi-cluster/4.test-connectivity/test_connectivity.sh b/patterns/istio-multi-cluster/4.test-connectivity/test_connectivity.sh deleted file mode 100755 index 9437af7c08..0000000000 --- a/patterns/istio-multi-cluster/4.test-connectivity/test_connectivity.sh +++ /dev/null @@ -1,46 +0,0 @@ -export CLUSTER_1=cluster-1 -export CLUSTER_2=cluster-2 -export AWS_DEFAULT_REGION=$(aws configure get region) -export AWS_ACCOUNT_NUMBER=$(aws sts get-caller-identity --query "Account" --output text) - -aws eks update-kubeconfig --name $CLUSTER_1 --region $AWS_DEFAULT_REGION -aws eks update-kubeconfig --name $CLUSTER_2 --region $AWS_DEFAULT_REGION - -export CTX_CLUSTER_1=arn:aws:eks:$AWS_DEFAULT_REGION:${AWS_ACCOUNT_NUMBER}:cluster/$CLUSTER_1 -export CTX_CLUSTER_2=arn:aws:eks:$AWS_DEFAULT_REGION:${AWS_ACCOUNT_NUMBER}:cluster/$CLUSTER_2 - - -kubectl exec --context="${CTX_CLUSTER_1}" -n sample -c sleep \ - "$(kubectl get pod --context="${CTX_CLUSTER_1}" -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -sS helloworld.sample:5000/hello -kubectl exec --context="${CTX_CLUSTER_1}" -n sample -c sleep \ - "$(kubectl get pod --context="${CTX_CLUSTER_1}" -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -sS helloworld.sample:5000/hello -kubectl exec --context="${CTX_CLUSTER_1}" -n sample -c sleep \ - "$(kubectl get pod --context="${CTX_CLUSTER_1}" -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -sS helloworld.sample:5000/hello -kubectl exec --context="${CTX_CLUSTER_1}" -n sample -c sleep \ - "$(kubectl get pod --context="${CTX_CLUSTER_1}" -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -sS helloworld.sample:5000/hello - - -kubectl exec --context="${CTX_CLUSTER_2}" -n sample -c sleep \ - "$(kubectl get pod --context="${CTX_CLUSTER_2}" -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -sS helloworld.sample:5000/hello -kubectl exec --context="${CTX_CLUSTER_2}" -n sample -c sleep \ - "$(kubectl get pod --context="${CTX_CLUSTER_2}" -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -sS helloworld.sample:5000/hello -kubectl exec --context="${CTX_CLUSTER_2}" -n sample -c sleep \ - "$(kubectl get pod --context="${CTX_CLUSTER_2}" -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -sS helloworld.sample:5000/hello -kubectl exec --context="${CTX_CLUSTER_2}" -n sample -c sleep \ - "$(kubectl get pod --context="${CTX_CLUSTER_2}" -n sample -l \ - app=sleep -o jsonpath='{.items[0].metadata.name}')" \ - -- curl -sS helloworld.sample:5000/hello diff --git a/patterns/istio-multi-cluster/README.md b/patterns/istio-multi-cluster/README.md deleted file mode 100644 index ba9211ac04..0000000000 --- a/patterns/istio-multi-cluster/README.md +++ /dev/null @@ -1,124 +0,0 @@ -# Amazon EKS Multi-Cluster w/ Istio - -This pattern demonstrates 2 Amazon EKS clusters configured with Istio. -Istio will be set-up to operate in a [Multi-Primary](https://istio.io/latest/docs/setup/install/multicluster/multi-primary/) configuration, where services are shared across clusters. - -Refer to the [documentation](https://istio.io/latest/docs/concepts/) for `Istio` concepts. - -## Notable configuration - -* This sample relies on reading data from Terraform Remote State in the different folders. In a production setup, Terraform Remote State is stored in a persistent backend such as Terraform Cloud or S3. For more information, please refer to the Terraform [Backends](https://developer.hashicorp.com/terraform/language/settings/backends/configuration) documentation -* The process for connecting clusters is separated from the cluster creation as it requires all cluster to be created first, and exchange configuration between one to the other - -## Folder structure - -### [`0.certs-tool`](0.certs-tool/) - -This folder is the [Makefiles](https://github.com/istio/istio/tree/master/tools/certs) from the Istio projects to generate 1 root CA with 2 intermediate CAs for each cluster. Please refer to the ["Certificate Management"](https://istio.io/latest/docs/tasks/security/cert-management/) section in the Istio documentation. For production setup it's [highly recommended](https://istio.io/latest/docs/tasks/security/cert-management/plugin-ca-cert/#plug-in-certificates-and-key-into-the-cluster) by the Istio project to have a production-ready CA solution. - -> **_NOTE:_** The [0.certs-tool/create-certs.sh](0.certs-tool/create-certs.sh) script needs to run before the cluster creation so the code will pick up the relevant certificates - -### [`0.vpc`](0.vpc/) - -This folder creates the VPC for both clusters. The VPC creation is not part of the cluster provisioning and therefore lives in a separate folder. -To support the multi-cluster/Multi-Primary setup, this folder also creates additional security group to be used by each cluster worker nodes to allow cross-cluster communication (resources `cluster1_additional_sg` and `cluster2_additional_sg`). These security groups allow communication from one to the other and each will be added to the worker nodes of the relevant cluster - -### [`1.cluster1`](1.cluster1/) - -This folder creates an Amazon EKS Cluster, named by default `cluster-1` (see [`variables.tf`](1.cluster1/variables.tf)), with AWS Load Balancer Controller, and Istio installation. -Configurations in this folder to be aware of: - -* The cluster is configured to use the security groups created in the `0.vpc` folder (`cluster1_additional_sg` in this case). -* Kubernetes Secret named `cacerts` is created with the certificates created by the [0.certs-tool/create-certs.sh](0.certs-tool/create-certs.sh) script -* Kubernetes Secret named `cacerts` named `istio-reader-service-account-istio-remote-secret-token` of type `Service-Account` is being created. This is to replicate the [istioctl experimental create-remote-secret](https://istio.io/latest/docs/reference/commands/istioctl/#istioctl-experimental-create-remote-secret) command. This secret will be used in folder [`3.istio-multi-primary`](3.istio-multi-primary/) to apply kubeconfig secret with tokens from the other cluster to be able to communicate to the other cluster API Server - -### [`2.cluster2`](2.cluster2/) - -Same configuration as in `1.cluster1` except the name of the cluster which is `cluster-2`. - -### [`3.istio-multi-primary`](3.istio-multi-primary/) - -This folder deploys a reader secret on each cluster. It replicates the [`istioctl experimental create-remote-secret`](https://istio.io/latest/docs/reference/commands/istioctl/#istioctl-experimental-create-remote-secret) by applying a kubeconfig secret prefixed `istio-remote-secret-` with the cluster name at the end. - -### [`4.test-connectivity`](4.test-connectivity/) - -This folder test the installation connectivity. It follows the Istio guide [Verify the installation](https://istio.io/latest/docs/setup/install/multicluster/verify/) by deploying services on each cluster, and `curl`-ing from one to the other - -## 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 - -### Prereq - Provision Certificates - -```shell -cd 0.certs-tool -./create-certs.sh -cd.. -``` - -### Step 0 - Create the VPC - -```shell -cd 0.certs-tool -./create-certs.sh -cd.. -``` - -### Step 1 - Deploy cluster-1 - -```shell -cd 1.cluster1 -terraform init -terraform apply -auto-approve -cd.. -``` - -### Step 2 - Deploy cluster-2 - -```shell -cd 2.cluster2 -terraform init -terraform apply -auto-approve -cd.. -``` - -### Step 3 - Configure Istio Multi-Primary - -```shell -cd 3.istio-multi-primary -terraform init -terraform apply -auto-approve -cd.. -``` - -### Step 4 - test installation and connectivity - -```shell -cd 4.test-connectivity -./test_connectivity.sh -cd.. -``` - -This script deploy the sample application to both clusters and run curl from a pod in one cluster to a service that is deployed in both cluster. You should expect to see responses from both `V1` and `V2` of the sample application. -The script run 4 `curl` command from cluster-1 to cluster-2 and vice versa - -## Destroy - -To teardown and remove the resources created in this example: - -```shell -cd 3.istio-multi-primary -terraform apply -destroy -autoapprove -cd ../2.cluster2 -terraform apply -destroy -autoapprove -cd ../1.cluster1 -terraform apply -destroy -autoapprove -cd ../0.vpc -terraform apply -destroy -autoapprove -```