From 2e5d819ceda27b60eeaaa44afee51397636581c2 Mon Sep 17 00:00:00 2001 From: Rajalakshmi Ramasubramanian Date: Fri, 10 Jul 2020 07:40:33 +0000 Subject: [PATCH 1/4] Update Ingress gateway walkthrough to use appmesh prod cli --- walkthroughs/howto-ingress-gateway/README.md | 9 +-------- .../infrastructure/ecs-service.yaml | 12 +----------- walkthroughs/howto-ingress-gateway/mesh/mesh.sh | 4 ++-- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/walkthroughs/howto-ingress-gateway/README.md b/walkthroughs/howto-ingress-gateway/README.md index 52bbab65..5d5b4a73 100644 --- a/walkthroughs/howto-ingress-gateway/README.md +++ b/walkthroughs/howto-ingress-gateway/README.md @@ -89,14 +89,7 @@ Internet --> (terminate TLS) NLB (originate TLS) --> (terminate TLS) Gateway (or ## Step 1: Prerequisites -You will need the latest version of the App Mesh Preview CLI for this walkthrough. You can download and use the latest version using the command below. - -```bash -aws configure add-model \ - --service-name appmesh-preview \ - --service-model https://raw.githubusercontent.com/aws/aws-app-mesh-roadmap/master/appmesh-preview/service-model.json -``` -You'll also need a keypair stored in AWS to access a bastion host. You can create a keypair using the command below if you don't have one. See [Amazon EC2 Key Pairs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html). +You'll need a keypair stored in AWS to access a bastion host. You can create a keypair using the command below if you don't have one. See [Amazon EC2 Key Pairs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html). ```bash aws ec2 create-key-pair --key-name color-app | jq -r .KeyMaterial > ~/.ssh/color-app.pem diff --git a/walkthroughs/howto-ingress-gateway/infrastructure/ecs-service.yaml b/walkthroughs/howto-ingress-gateway/infrastructure/ecs-service.yaml index ae8e13ec..40e1fb6a 100644 --- a/walkthroughs/howto-ingress-gateway/infrastructure/ecs-service.yaml +++ b/walkthroughs/howto-ingress-gateway/infrastructure/ecs-service.yaml @@ -128,8 +128,6 @@ Resources: Environment: - Name: 'APPMESH_VIRTUAL_NODE_NAME' Value: !Sub 'mesh/${AppMeshMeshName}/virtualNode/colorteller-white-vn' - - Name: 'APPMESH_PREVIEW' - Value: '1' ColorTellerWhiteService: Type: 'AWS::ECS::Service' @@ -249,8 +247,6 @@ Resources: Environment: - Name: 'APPMESH_VIRTUAL_NODE_NAME' Value: !Sub 'mesh/${AppMeshMeshName}/virtualNode/colorteller-black-vn' - - Name: 'APPMESH_PREVIEW' - Value: '1' ColorTellerBlackService: Type: 'AWS::ECS::Service' @@ -370,8 +366,6 @@ Resources: Environment: - Name: 'APPMESH_VIRTUAL_NODE_NAME' Value: !Sub 'mesh/${AppMeshMeshName}/virtualNode/colorteller-blue-vn' - - Name: 'APPMESH_PREVIEW' - Value: '1' ColorTellerBlueService: Type: 'AWS::ECS::Service' @@ -491,8 +485,6 @@ Resources: Environment: - Name: 'APPMESH_VIRTUAL_NODE_NAME' Value: !Sub 'mesh/${AppMeshMeshName}/virtualNode/colorteller-red-vn' - - Name: 'APPMESH_PREVIEW' - Value: '1' ColorTellerRedService: Type: 'AWS::ECS::Service' @@ -561,7 +553,7 @@ Resources: Command: - 'CMD-SHELL' - 'curl -s http://localhost:9901/server_info | grep state | grep -q LIVE' - Interval: 5 + Interval: 30 Timeout: 2 Retries: 3 LogConfiguration: @@ -574,8 +566,6 @@ Resources: Environment: - Name: 'APPMESH_VIRTUAL_NODE_NAME' Value: !Sub 'mesh/${AppMeshMeshName}/virtualGateway/colorgateway-vg' - - Name: 'APPMESH_PREVIEW' - Value: '1' - Name: 'ENABLE_ENVOY_STATS_TAGS' Value: '1' - Name: 'ENABLE_ENVOY_DOG_STATSD' diff --git a/walkthroughs/howto-ingress-gateway/mesh/mesh.sh b/walkthroughs/howto-ingress-gateway/mesh/mesh.sh index ff1db529..43a5491f 100755 --- a/walkthroughs/howto-ingress-gateway/mesh/mesh.sh +++ b/walkthroughs/howto-ingress-gateway/mesh/mesh.sh @@ -22,7 +22,7 @@ sanity_check() { fi } -appmesh_cmd="aws appmesh-preview" +appmesh_cmd="aws appmesh" create_mesh() { spec_file=$1 @@ -302,4 +302,4 @@ main() { esac } -main $@ \ No newline at end of file +main $@ From 08e2500b360d57083563eb7669eaa3f1db8b4541 Mon Sep 17 00:00:00 2001 From: Rajalakshmi Ramasubramanian Date: Mon, 13 Jul 2020 22:56:50 +0000 Subject: [PATCH 2/4] Setting Healthcheck StartPeriod as 60s --- .../howto-ingress-gateway/infrastructure/ecs-service.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/walkthroughs/howto-ingress-gateway/infrastructure/ecs-service.yaml b/walkthroughs/howto-ingress-gateway/infrastructure/ecs-service.yaml index 40e1fb6a..d7e8f998 100644 --- a/walkthroughs/howto-ingress-gateway/infrastructure/ecs-service.yaml +++ b/walkthroughs/howto-ingress-gateway/infrastructure/ecs-service.yaml @@ -553,9 +553,10 @@ Resources: Command: - 'CMD-SHELL' - 'curl -s http://localhost:9901/server_info | grep state | grep -q LIVE' - Interval: 30 + Interval: 5 Timeout: 2 Retries: 3 + StartPeriod: 60 LogConfiguration: LogDriver: 'awslogs' Options: From 5b3a5bebc0d968fd1dcefb3805dfda79fa70be17 Mon Sep 17 00:00:00 2001 From: Rajalakshmi Ramasubramanian Date: Tue, 22 Dec 2020 20:04:41 +0000 Subject: [PATCH 3/4] * Chaging mesh service discovery to Cloudmap * Handling AWS Cli V2 --- walkthroughs/howto-cross-account/README.md | 6 +++--- .../howto-cross-account/primary-account/deploy.sh | 9 ++++++++- .../howto-cross-account/primary-account/mesh.yaml | 10 ++++++---- .../howto-cross-account/secondary-account/mesh.yaml | 5 +++-- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/walkthroughs/howto-cross-account/README.md b/walkthroughs/howto-cross-account/README.md index b2a99053..bc69edd9 100644 --- a/walkthroughs/howto-cross-account/README.md +++ b/walkthroughs/howto-cross-account/README.md @@ -25,9 +25,9 @@ These backends will be configured in distinct accounts and made accessible throu ``` 2. Edit the `vars.env` file to add your account and profile settings: - 1. **Project Name** used to isolate resources created in this demo from other's in your account. e.g. howto-cross-account + 1. **Project Name** used to isolate resources created in this demo from other's in your account. e.g. cross-account ``` - export PROJECT_NAME=howto-cross-account + export PROJECT_NAME=cross-account ``` 2. **Account IDs**: This demo needs two accounts to which are in the same AWS Organization. @@ -82,7 +82,7 @@ These backends will be configured in distinct accounts and made accessible throu ``` export KEY_PAIR=... ``` -3. Source the `env.vars` file using `source env.vars` +3. Source the `vars.env` file using `source vars.env` 4. Setup base cloudformation stack by running ``` ./deploy.sh diff --git a/walkthroughs/howto-cross-account/primary-account/deploy.sh b/walkthroughs/howto-cross-account/primary-account/deploy.sh index ada9cd50..190b6a68 100755 --- a/walkthroughs/howto-cross-account/primary-account/deploy.sh +++ b/walkthroughs/howto-cross-account/primary-account/deploy.sh @@ -11,13 +11,20 @@ if [ -z $AWS_PROFILE ]; then fi DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" +ECR_URL="${AWS_PRIMARY_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com" ECR_IMAGE_PREFIX=${AWS_PRIMARY_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${PROJECT_NAME} +AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1) deploy_image() { echo "Deploying Gateway image to ECR..." aws ecr describe-repositories --repository-name ${PROJECT_NAME}/gateway >/dev/null 2>&1 || aws ecr create-repository --repository-name ${PROJECT_NAME}/gateway docker build -t ${ECR_IMAGE_PREFIX}/gateway ${DIR}/gateway --build-arg BACKEND_SERVICE=backend.${PROJECT_NAME}.local - $(aws --profile ${AWS_PROFILE} ecr get-login --no-include-email) + if [[ ${AWS_CLI_VERSION} == 1 ]] + then + $(aws --profile ${AWS_PROFILE} ecr get-login --no-include-email) + else + aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin $ECR_URL + fi docker push ${ECR_IMAGE_PREFIX}/gateway } diff --git a/walkthroughs/howto-cross-account/primary-account/mesh.yaml b/walkthroughs/howto-cross-account/primary-account/mesh.yaml index 3ff00e51..4caba375 100644 --- a/walkthroughs/howto-cross-account/primary-account/mesh.yaml +++ b/walkthroughs/howto-cross-account/primary-account/mesh.yaml @@ -23,8 +23,9 @@ Resources: Port: 80 Protocol: http ServiceDiscovery: - DNS: - Hostname: !Sub "gateway.${ProjectName}.local" + AWSCloudMap: + NamespaceName: !Sub "${ProjectName}.local" + ServiceName: "gateway" BackendNode: Type: AWS::AppMesh::VirtualNode @@ -37,8 +38,9 @@ Resources: Port: 80 Protocol: http ServiceDiscovery: - DNS: - Hostname: !Sub "backend.${ProjectName}.local" + AWSCloudMap: + NamespaceName: !Sub "${ProjectName}.local" + ServiceName: "backend" VirtualRouter: Type: AWS::AppMesh::VirtualRouter diff --git a/walkthroughs/howto-cross-account/secondary-account/mesh.yaml b/walkthroughs/howto-cross-account/secondary-account/mesh.yaml index c2427215..54b87a0d 100644 --- a/walkthroughs/howto-cross-account/secondary-account/mesh.yaml +++ b/walkthroughs/howto-cross-account/secondary-account/mesh.yaml @@ -22,5 +22,6 @@ Resources: Port: 80 Protocol: http ServiceDiscovery: - DNS: - Hostname: !Sub "backend.secondary.${ProjectName}.local" + AWSCloudMap: + Namespace: !Sub "secondar.${ProjectName}.local" + ServiceName: "backend" From 716fa9b6063722f6dc3858a3ddff8aa1c1e486d4 Mon Sep 17 00:00:00 2001 From: Mridula Grandhi <42749134+gmridula@users.noreply.github.com> Date: Mon, 12 Apr 2021 12:42:06 -0400 Subject: [PATCH 4/4] [Blogpost] Traffic Encryption in AWS App Mesh across accounts using ACM (#403) * walkthrough of service connectivity scripts * adding README * moving blog scripts from walkthroughs to blogs folder and additional changes * adding ecr login support with v1 and v2 aws cli versions * added ECS_URL * Adding required scripts for ACM AppMesh blogpost * Update readme.md Fixing the infrastructure typo * Update infrastructure_backend.yaml Removing the commented-out resources. * Modifying the virtual node updates to use CRD's * Update and rename yelb_ui_update to yelb_ui_update.yaml * Update and rename yelb_db_update to yelb_db_update.yaml * Update and rename appserver_update to appserver_update.yaml * Update and rename redis_update to redis_update.yaml --- .../AWS/ECS/mesh/yelb-appmesh-db.sh | 1 + .../eks-app-mesh-cross-account-acm/cleanup.sh | 100 +++++ .../eks/setup.sh | 112 ++++++ .../backend_vpc_peering_routes.yaml | 29 ++ .../frontend_vpc_peering_routes.yaml | 30 ++ .../infrastructure_backend.yaml | 358 ++++++++++++++++++ .../infrastructure_frontend.yaml | 293 ++++++++++++++ .../infrastructure/setup.sh | 38 ++ .../mesh/Config | 26 ++ .../mesh/apply_tls_on_yelb_nodes.sh | 71 ++++ .../mesh/appserver_update.yaml | 81 ++++ .../mesh/ca_config.txt | 12 + .../mesh/create_mesh.sh | 17 + .../mesh/redis_update.yaml | 43 +++ .../mesh/revoke_config.txt | 8 + .../mesh/yelb-appserver.yaml | 67 ++++ .../mesh/yelb-db.yaml | 28 ++ .../mesh/yelb-redis.yaml | 28 ++ .../mesh/yelb-ui.yaml | 32 ++ .../mesh/yelb_db_update.yaml | 43 +++ .../mesh/yelb_ui_update.yaml | 46 +++ .../eks-app-mesh-cross-account-acm/readme.md | 155 ++++++++ .../shared_resources/shared_mesh.yaml | 19 + .../yelb/resources_backend.yaml | 100 +++++ .../yelb/resources_frontend.yaml | 50 +++ 25 files changed, 1787 insertions(+) create mode 100755 walkthroughs/eks-app-mesh-cross-account-acm/cleanup.sh create mode 100755 walkthroughs/eks-app-mesh-cross-account-acm/eks/setup.sh create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/backend_vpc_peering_routes.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/frontend_vpc_peering_routes.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/infrastructure_backend.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/infrastructure_frontend.yaml create mode 100755 walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/setup.sh create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/Config create mode 100755 walkthroughs/eks-app-mesh-cross-account-acm/mesh/apply_tls_on_yelb_nodes.sh create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/appserver_update.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/ca_config.txt create mode 100755 walkthroughs/eks-app-mesh-cross-account-acm/mesh/create_mesh.sh create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/redis_update.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/revoke_config.txt create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-appserver.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-db.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-redis.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-ui.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb_db_update.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb_ui_update.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/readme.md create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/shared_resources/shared_mesh.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/yelb/resources_backend.yaml create mode 100644 walkthroughs/eks-app-mesh-cross-account-acm/yelb/resources_frontend.yaml diff --git a/blogs/ecs-service-connectivity/yelb/deployments/platformdeployment/AWS/ECS/mesh/yelb-appmesh-db.sh b/blogs/ecs-service-connectivity/yelb/deployments/platformdeployment/AWS/ECS/mesh/yelb-appmesh-db.sh index 0695d047..1b766537 100644 --- a/blogs/ecs-service-connectivity/yelb/deployments/platformdeployment/AWS/ECS/mesh/yelb-appmesh-db.sh +++ b/blogs/ecs-service-connectivity/yelb/deployments/platformdeployment/AWS/ECS/mesh/yelb-appmesh-db.sh @@ -1,3 +1,4 @@ + #Gets the yelb db endpoint from yelb-fargate cloudformation stack export YELB_DB_ENDPOINT=$(aws cloudformation describe-stacks --stack-name yelb-fargate --query "Stacks[0].Outputs[?OutputKey=='YelbDBEndpointUrl'].OutputValue" --output text) diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/cleanup.sh b/walkthroughs/eks-app-mesh-cross-account-acm/cleanup.sh new file mode 100755 index 00000000..36519f02 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/cleanup.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +set -e +export AWS_PAGER="" + +echo "Deleting the EKS clusters" +eksctl delete -p frontend cluster -f /tmp/eks-frontend-configuration.yml +eksctl delete -p backend cluster -f /tmp/eks-backend-configuration.yml + +echo "Deleting the App Mesh virtual services" +aws --profile frontend appmesh delete-virtual-service \ + --mesh-name am-multi-account-mesh \ + --virtual-service-name yelb-db + +aws --profile frontend appmesh delete-virtual-service \ + --mesh-name am-multi-account-mesh \ + --virtual-service-name redis-server + +aws --profile frontend appmesh delete-virtual-service \ + --mesh-name am-multi-account-mesh \ + --virtual-service-name yelb-appserver + +aws --profile frontend appmesh delete-virtual-service \ + --mesh-name am-multi-account-mesh \ + --virtual-service-name yelb-ui + +echo "Deleting the App Mesh virtual router" +aws --profile frontend appmesh delete-route \ + --mesh-name am-multi-account-mesh \ + --virtual-router-name yelb-appserver-virtual-router \ + --route-name route-to-yelb-appserver + +aws --profile frontend appmesh delete-virtual-router \ + --mesh-name am-multi-account-mesh \ + --virtual-router-name yelb-appserver-virtual-router + +echo "Deleting the App Mesh virtual nodes" +aws --profile frontend appmesh delete-virtual-node \ + --mesh-name am-multi-account-mesh \ + --virtual-node-name redis-server_yelb + +aws --profile frontend appmesh delete-virtual-node \ + --mesh-name am-multi-account-mesh \ + --virtual-node-name yelb-db_yelb + +aws --profile frontend appmesh delete-virtual-node \ + --mesh-name am-multi-account-mesh \ + --virtual-node-name yelb-appserver_yelb + +aws --profile frontend appmesh delete-virtual-node \ + --mesh-name am-multi-account-mesh \ + --virtual-node-name yelb-ui_yelb + +echo "Deleting the App Mesh mesh" +aws --profile frontend appmesh delete-mesh \ + --mesh-name am-multi-account-mesh + +echo "Deleting Cloud Map Services" +NAMESPACE=$(aws --profile backend servicediscovery list-namespaces | \ + jq -r ' .Namespaces[] | select ( .Properties.HttpProperties.HttpName == "am-multi-account.local" ) | .Id '); +SERVICE_ID=$(aws --profile backend servicediscovery list-services --filters Name="NAMESPACE_ID",Values=$NAMESPACE,Condition="EQ" | jq -r ' .Services[] | [ .Id ] | @tsv ' ) +aws --profile backend servicediscovery list-instances --service-id $SERVICE_ID | jq -r ' .Instances[] | [ .Id ] | @tsv ' |\ + while IFS=$'\t' read -r instanceId; do + aws --profile backend servicediscovery deregister-instance --service-id $SERVICE_ID --instance-id $instanceId + done +aws --profile backend servicediscovery list-services \ + --filters Name="NAMESPACE_ID",Values=$NAMESPACE,Condition="EQ" | \ +jq -r ' .Services[] | [ .Id ] | @tsv ' | \ + while IFS=$'\t' read -r serviceId; do + aws --profile backend servicediscovery delete-service \ + --id $serviceId + done + +echo "Deleting CloudFormation templates" +aws --profile backend cloudformation delete-stack \ + --stack-name am-multi-account-routes +aws --profile backend cloudformation wait stack-delete-complete \ + --stack-name am-multi-account-routes + +aws --profile backend cloudformation delete-stack \ + --stack-name am-multi-account-infra +aws --profile backend cloudformation wait stack-delete-complete \ + --stack-name am-multi-account-infra + +aws --profile frontend cloudformation delete-stack \ + --stack-name am-multi-account-shared-mesh +aws --profile frontend cloudformation wait stack-delete-complete \ + --stack-name am-multi-account-shared-mesh + +aws --profile frontend cloudformation delete-stack \ + --stack-name am-multi-account-routes +aws --profile frontend cloudformation wait stack-delete-complete \ + --stack-name am-multi-account-routes + +aws --profile frontend cloudformation delete-stack \ + --stack-name am-multi-account-infra +aws --profile frontend cloudformation wait stack-delete-complete \ + --stack-name am-multi-account-infra + +echo "Cleanup finished" \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/eks/setup.sh b/walkthroughs/eks-app-mesh-cross-account-acm/eks/setup.sh new file mode 100755 index 00000000..8e5df871 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/eks/setup.sh @@ -0,0 +1,112 @@ +#!/bin/bash + +set -e + +echo "Creating a ClusterConfig file for the Frontend cluster..." + +FRONTEND_AWS_REGION=$(aws --profile frontend configure get region); +FRONTEND_PRIVSUB1_ID=$(aws --profile frontend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:PrivateSubnet1") | .Value'); +FRONTEND_PRIVSUB2_ID=$(aws --profile frontend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:PrivateSubnet2") | .Value'); +FRONTEND_PUBSUB1_ID=$(aws --profile frontend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:PublicSubnet1") | .Value'); +FRONTEND_PUBSUB2_ID=$(aws --profile frontend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:PublicSubnet2") | .Value'); +FRONTEND_PRIVSUB1_AZ=$(aws --profile frontend ec2 describe-subnets --subnet-ids $FRONTEND_PRIVSUB1_ID | jq -r .Subnets[].AvailabilityZone); +FRONTEND_PRIVSUB2_AZ=$(aws --profile frontend ec2 describe-subnets --subnet-ids $FRONTEND_PRIVSUB2_ID | jq -r .Subnets[].AvailabilityZone); +FRONTEND_PUBSUB1_AZ=$(aws --profile frontend ec2 describe-subnets --subnet-ids $FRONTEND_PUBSUB1_ID | jq -r .Subnets[].AvailabilityZone); +FRONTEND_PUBSUB2_AZ=$(aws --profile frontend ec2 describe-subnets --subnet-ids $FRONTEND_PUBSUB2_ID | jq -r .Subnets[].AvailabilityZone); +FRONTEND_NODES_IAM_POLICY=$(aws --profile frontend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:NodesSDPolicy") | .Value'); + +cat > /tmp/eks-frontend-configuration.yml <<-EKS_FRONTEND_CONF + apiVersion: eksctl.io/v1alpha5 + kind: ClusterConfig + metadata: + name: am-multi-account-1 + region: $FRONTEND_AWS_REGION + version: "1.18" + vpc: + subnets: + private: + $FRONTEND_PRIVSUB1_AZ: { id: $FRONTEND_PRIVSUB1_ID } + $FRONTEND_PRIVSUB2_AZ: { id: $FRONTEND_PRIVSUB2_ID } + public: + $FRONTEND_PUBSUB1_AZ: { id: $FRONTEND_PUBSUB1_ID } + $FRONTEND_PUBSUB2_AZ: { id: $FRONTEND_PUBSUB2_ID } + nodeGroups: + - name: am-multi-account-1-ng + labels: { role: workers } + instanceType: t3.large + desiredCapacity: 3 + ssh: + allow: false + privateNetworking: true + iam: + attachPolicyARNs: + - $FRONTEND_NODES_IAM_POLICY + - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy + - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy + - arn:aws:iam::aws:policy/ElasticLoadBalancingFullAccess + - arn:aws:iam::aws:policy/AWSAppMeshFullAccess + withAddonPolicies: + xRay: true + cloudWatch: true + externalDNS: true +EKS_FRONTEND_CONF + +echo "Creating the Frontend EKS cluster..." +eksctl create -p frontend cluster -f /tmp/eks-frontend-configuration.yml + +echo "Creating a ClusterConfig file for the Backend cluster..." + +BACKEND_AWS_REGION=$(aws --profile backend configure get region); +BACKEND_PRIVSUB1_ID=$(aws --profile backend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:PrivateSubnet1") | .Value'); +BACKEND_PRIVSUB2_ID=$(aws --profile backend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:PrivateSubnet2") | .Value'); +BACKEND_PUBSUB1_ID=$(aws --profile backend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:PublicSubnet1") | .Value'); +BACKEND_PUBSUB2_ID=$(aws --profile backend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:PublicSubnet2") | .Value'); +BACKEND_PRIVSUB1_AZ=$(aws --profile backend ec2 describe-subnets --subnet-ids $BACKEND_PRIVSUB1_ID | jq -r .Subnets[].AvailabilityZone); +BACKEND_PRIVSUB2_AZ=$(aws --profile backend ec2 describe-subnets --subnet-ids $BACKEND_PRIVSUB2_ID | jq -r .Subnets[].AvailabilityZone); +BACKEND_PUBSUB1_AZ=$(aws --profile backend ec2 describe-subnets --subnet-ids $BACKEND_PUBSUB1_ID | jq -r .Subnets[].AvailabilityZone); +BACKEND_PUBSUB2_AZ=$(aws --profile backend ec2 describe-subnets --subnet-ids $BACKEND_PUBSUB2_ID | jq -r .Subnets[].AvailabilityZone); +BACKEND_NODES_IAM_POLICY=$(aws --profile backend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:NodesSDPolicy") | .Value'); +BACKEND_NODES_SECURITY_GROUP=$(aws --profile backend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:NodesSecurityGroup") | .Value'); + +cat > /tmp/eks-backend-configuration.yml <<-EKS_BACKEND_CONF + apiVersion: eksctl.io/v1alpha5 + kind: ClusterConfig + metadata: + name: am-multi-account-2 + region: $BACKEND_AWS_REGION + version: "1.18" + vpc: + subnets: + private: + $BACKEND_PRIVSUB1_AZ: { id: $BACKEND_PRIVSUB1_ID } + $BACKEND_PRIVSUB2_AZ: { id: $BACKEND_PRIVSUB2_ID } + public: + $BACKEND_PUBSUB1_AZ: { id: $BACKEND_PUBSUB1_ID } + $BACKEND_PUBSUB2_AZ: { id: $BACKEND_PUBSUB2_ID } + nodeGroups: + - name: am-multi-account-2-ng + labels: { role: workers } + instanceType: t3.large + desiredCapacity: 3 + ssh: + allow: false + privateNetworking: true + securityGroups: + withShared: true + withLocal: true + attachIDs: ['$BACKEND_NODES_SECURITY_GROUP'] + iam: + attachPolicyARNs: + - $BACKEND_NODES_IAM_POLICY + - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy + - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy + - arn:aws:iam::aws:policy/ElasticLoadBalancingFullAccess + - arn:aws:iam::aws:policy/AWSAppMeshFullAccess + withAddonPolicies: + xRay: true + cloudWatch: true + externalDNS: true +EKS_BACKEND_CONF + +echo "Creating the Backend EKS cluster..." +eksctl create -p backend cluster -f /tmp/eks-backend-configuration.yml \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/backend_vpc_peering_routes.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/backend_vpc_peering_routes.yaml new file mode 100644 index 00000000..5a270f0b --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/backend_vpc_peering_routes.yaml @@ -0,0 +1,29 @@ +Parameters: + ProjectName: + Type: String + Description: Project name to link stacks + Default: am-multi-account + + PeerCIDR: + Type: String + Default: 10.192.0.0/16 + +Resources: + + PeerRoute1: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Fn::ImportValue: !Sub '${ProjectName}:PrivateRouteTable1' + DestinationCidrBlock: !Ref PeerCIDR + VpcPeeringConnectionId: + Fn::ImportValue: !Sub '${ProjectName}:VPCPeeringConnectionId' + + PeerRoute2: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Fn::ImportValue: !Sub '${ProjectName}:PrivateRouteTable2' + DestinationCidrBlock: !Ref PeerCIDR + VpcPeeringConnectionId: + Fn::ImportValue: !Sub '${ProjectName}:VPCPeeringConnectionId' \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/frontend_vpc_peering_routes.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/frontend_vpc_peering_routes.yaml new file mode 100644 index 00000000..be73fef2 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/frontend_vpc_peering_routes.yaml @@ -0,0 +1,30 @@ +Parameters: + ProjectName: + Type: String + Description: Project name to link stacks + Default: am-multi-account + + PeerCIDR: + Type: String + Default: 10.193.0.0/16 + + VPCPeeringConnectionId: + Type: String + +Resources: + + PeerRoute1: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Fn::ImportValue: !Sub '${ProjectName}:PrivateRouteTable1' + DestinationCidrBlock: !Ref PeerCIDR + VpcPeeringConnectionId: !Ref VPCPeeringConnectionId + + PeerRoute2: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Fn::ImportValue: !Sub '${ProjectName}:PrivateRouteTable2' + DestinationCidrBlock: !Ref PeerCIDR + VpcPeeringConnectionId: !Ref VPCPeeringConnectionId \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/infrastructure_backend.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/infrastructure_backend.yaml new file mode 100644 index 00000000..78f59418 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/infrastructure_backend.yaml @@ -0,0 +1,358 @@ +Parameters: + ProjectName: + Type: String + Description: Project name to link stacks + Default: am-multi-account + + VpcCIDR: + Description: Please enter the IP range (CIDR notation) for this VPC + Type: String + Default: 10.193.0.0/16 + + PublicSubnet1CIDR: + Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone + Type: String + Default: 10.193.10.0/24 + + PublicSubnet2CIDR: + Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone + Type: String + Default: 10.193.11.0/24 + + PrivateSubnet1CIDR: + Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone + Type: String + Default: 10.193.20.0/24 + + PrivateSubnet2CIDR: + Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone + Type: String + Default: 10.193.21.0/24 + + FrontendAccountId: + Type: String + + PeerVPCId: + Type: String + + PeerRoleArn: + Type: String + +Resources: + + VPC: + Type: AWS::EC2::VPC + Properties: + CidrBlock: !Ref VpcCIDR + EnableDnsSupport: true + EnableDnsHostnames: true + Tags: + - Key: Name + Value: !Ref ProjectName + + InternetGateway: + Type: AWS::EC2::InternetGateway + Properties: + Tags: + - Key: Name + Value: !Ref ProjectName + + InternetGatewayAttachment: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + InternetGatewayId: !Ref InternetGateway + VpcId: !Ref VPC + + PublicSubnet1: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + AvailabilityZone: !Select [ 0, !GetAZs '' ] + CidrBlock: !Ref PublicSubnet1CIDR + MapPublicIpOnLaunch: true + Tags: + - Key: Name + Value: !Sub ${ProjectName} Public Subnet (AZ1) + + PublicSubnet2: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + AvailabilityZone: !Select [ 1, !GetAZs '' ] + CidrBlock: !Ref PublicSubnet2CIDR + MapPublicIpOnLaunch: true + Tags: + - Key: Name + Value: !Sub ${ProjectName} Public Subnet (AZ2) + + PrivateSubnet1: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + AvailabilityZone: !Select [ 0, !GetAZs '' ] + CidrBlock: !Ref PrivateSubnet1CIDR + MapPublicIpOnLaunch: false + Tags: + - Key: Name + Value: !Sub ${ProjectName} Private Subnet (AZ1) + + PrivateSubnet2: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + AvailabilityZone: !Select [ 1, !GetAZs '' ] + CidrBlock: !Ref PrivateSubnet2CIDR + MapPublicIpOnLaunch: false + Tags: + - Key: Name + Value: !Sub ${ProjectName} Private Subnet (AZ2) + + NatGateway1EIP: + Type: AWS::EC2::EIP + DependsOn: InternetGatewayAttachment + Properties: + Domain: vpc + + NatGateway2EIP: + Type: AWS::EC2::EIP + DependsOn: InternetGatewayAttachment + Properties: + Domain: vpc + + NatGateway1: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NatGateway1EIP.AllocationId + SubnetId: !Ref PublicSubnet1 + + NatGateway2: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NatGateway2EIP.AllocationId + SubnetId: !Ref PublicSubnet2 + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + Tags: + - Key: Name + Value: !Sub ${ProjectName} Public Routes + + DefaultPublicRoute: + Type: AWS::EC2::Route + DependsOn: InternetGatewayAttachment + Properties: + RouteTableId: !Ref PublicRouteTable + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: !Ref InternetGateway + + PublicSubnet1RouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PublicRouteTable + SubnetId: !Ref PublicSubnet1 + + PublicSubnet2RouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PublicRouteTable + SubnetId: !Ref PublicSubnet2 + + PrivateRouteTable1: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + Tags: + - Key: Name + Value: !Sub ${ProjectName} Private Routes (AZ1) + + DefaultPrivateRoute1: + Type: AWS::EC2::Route + Properties: + RouteTableId: !Ref PrivateRouteTable1 + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: !Ref NatGateway1 + + PrivateSubnet1RouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable1 + SubnetId: !Ref PrivateSubnet1 + + PrivateRouteTable2: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + Tags: + - Key: Name + Value: !Sub ${ProjectName} Private Routes (AZ2) + + DefaultPrivateRoute2: + Type: AWS::EC2::Route + Properties: + RouteTableId: !Ref PrivateRouteTable2 + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: !Ref NatGateway2 + + PrivateSubnet2RouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable2 + SubnetId: !Ref PrivateSubnet2 + + NodesSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Allow traffic from frontend EKS + GroupName: frontend-eks-rules + SecurityGroupIngress: + - IpProtocol: "-1" + CidrIp: "10.192.0.0/16" + VpcId: !Ref VPC + + VPCPeeringConnection: + Type: 'AWS::EC2::VPCPeeringConnection' + Properties: + VpcId: !Ref VPC + PeerVpcId: !Ref PeerVPCId + PeerOwnerId: !Ref FrontendAccountId + PeerRoleArn: !Ref PeerRoleArn + + NodesSDPolicy: + Type: AWS::IAM::ManagedPolicy + Properties: + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: ['appmesh-preview:*'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:CreateService'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:DeleteService'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:GetService'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:GetInstance'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:RegisterInstance'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:DeregisterInstance'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:ListInstances'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:ListNamespaces'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:ListServices'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:GetOperation'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:GetInstancesHealthStatus'] + Resource: '*' + - Effect: Allow + Action: ['servicediscovery:UpdateInstanceCustomHealthStatus'] + Resource: '*' + - Effect: Allow + Action: ['route53:GetHealthCheck'] + Resource: '*' + - Effect: Allow + Action: ['route53:CreateHealthCheck'] + Resource: '*' + - Effect: Allow + Action: ['route53:UpdateHealthCheck'] + Resource: '*' + - Effect: Allow + Action: ['route53:ChangeResourceRecordSets'] + Resource: '*' + - Effect: Allow + Action: ['route53:DeleteHealthCheck'] + Resource: '*' + + AppServerServiceDiscoveryNamespace: + Type: AWS::ServiceDiscovery::HttpNamespace + Properties: + Name: !Sub '${ProjectName}.local' + +Outputs: + + VPC: + Description: A reference to the created VPC + Value: !Ref VPC + Export: + Name: !Sub '${ProjectName}:VPC' + + PublicSubnets: + Description: A list of the public subnets + Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2 ]] + + PrivateSubnets: + Description: A list of the private subnets + Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]] + + PublicSubnet1: + Description: A reference to the public subnet in the 1st Availability Zone + Value: !Ref PublicSubnet1 + Export: + Name: !Sub '${ProjectName}:PublicSubnet1' + + PublicSubnet2: + Description: A reference to the public subnet in the 2nd Availability Zone + Value: !Ref PublicSubnet2 + Export: + Name: !Sub '${ProjectName}:PublicSubnet2' + + PrivateSubnet1: + Description: A reference to the private subnet in the 1st Availability Zone + Value: !Ref PrivateSubnet1 + Export: + Name: !Sub '${ProjectName}:PrivateSubnet1' + + PrivateSubnet2: + Description: A reference to the private subnet in the 2nd Availability Zone + Value: !Ref PrivateSubnet2 + Export: + Name: !Sub '${ProjectName}:PrivateSubnet2' + + PrivateRouteTable1: + Value: !Ref PrivateRouteTable1 + Export: + Name: !Sub '${ProjectName}:PrivateRouteTable1' + + PrivateRouteTable2: + Value: !Ref PrivateRouteTable2 + Export: + Name: !Sub '${ProjectName}:PrivateRouteTable2' + + VPCPeeringConnectionId: + Value: !Ref VPCPeeringConnection + Export: + Name: !Sub '${ProjectName}:VPCPeeringConnectionId' + + NodesSecurityGroup: + Value: !Ref NodesSecurityGroup + Export: + Name: !Sub '${ProjectName}:NodesSecurityGroup' + + NodesSDPolicy: + Description: IAM Policy that will be added to the EKS nodes + Value: !Ref NodesSDPolicy + Export: + Name: !Sub '${ProjectName}:NodesSDPolicy' + + AppServerServiceDiscoveryNamespace: + Description: A SDS namespace that will be used by appserver + Value: !Ref AppServerServiceDiscoveryNamespace + Export: + Name: !Sub '${ProjectName}:AppServerServiceDiscoveryNamespace' diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/infrastructure_frontend.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/infrastructure_frontend.yaml new file mode 100644 index 00000000..b93be933 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/infrastructure_frontend.yaml @@ -0,0 +1,293 @@ +Description: This template deploys a VPC, with a pair of public and private subnets spread + across two Availability Zones. It deploys an internet gateway, with a default + route on the public subnets. It deploys a pair of NAT gateways (one in each AZ), + and default routes for them in the private subnets. + +Parameters: + ProjectName: + Type: String + Description: Project name to link stacks + Default: am-multi-account + + VpcCIDR: + Description: Please enter the IP range (CIDR notation) for this VPC + Type: String + Default: 10.192.0.0/16 + + PublicSubnet1CIDR: + Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone + Type: String + Default: 10.192.10.0/24 + + PublicSubnet2CIDR: + Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone + Type: String + Default: 10.192.11.0/24 + + PrivateSubnet1CIDR: + Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone + Type: String + Default: 10.192.20.0/24 + + PrivateSubnet2CIDR: + Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone + Type: String + Default: 10.192.21.0/24 + + BackendAccountId: + Type: String + +Resources: + + VPC: + Type: AWS::EC2::VPC + Properties: + CidrBlock: !Ref VpcCIDR + EnableDnsSupport: true + EnableDnsHostnames: true + Tags: + - Key: Name + Value: !Ref ProjectName + + InternetGateway: + Type: AWS::EC2::InternetGateway + Properties: + Tags: + - Key: Name + Value: !Ref ProjectName + + InternetGatewayAttachment: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + InternetGatewayId: !Ref InternetGateway + VpcId: !Ref VPC + + PublicSubnet1: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + AvailabilityZone: !Select [ 0, !GetAZs '' ] + CidrBlock: !Ref PublicSubnet1CIDR + MapPublicIpOnLaunch: true + Tags: + - Key: Name + Value: !Sub ${ProjectName} Public Subnet (AZ1) + + PublicSubnet2: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + AvailabilityZone: !Select [ 1, !GetAZs '' ] + CidrBlock: !Ref PublicSubnet2CIDR + MapPublicIpOnLaunch: true + Tags: + - Key: Name + Value: !Sub ${ProjectName} Public Subnet (AZ2) + + PrivateSubnet1: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + AvailabilityZone: !Select [ 0, !GetAZs '' ] + CidrBlock: !Ref PrivateSubnet1CIDR + MapPublicIpOnLaunch: false + Tags: + - Key: Name + Value: !Sub ${ProjectName} Private Subnet (AZ1) + + PrivateSubnet2: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + AvailabilityZone: !Select [ 1, !GetAZs '' ] + CidrBlock: !Ref PrivateSubnet2CIDR + MapPublicIpOnLaunch: false + Tags: + - Key: Name + Value: !Sub ${ProjectName} Private Subnet (AZ2) + + NatGateway1EIP: + Type: AWS::EC2::EIP + DependsOn: InternetGatewayAttachment + Properties: + Domain: vpc + + NatGateway2EIP: + Type: AWS::EC2::EIP + DependsOn: InternetGatewayAttachment + Properties: + Domain: vpc + + NatGateway1: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NatGateway1EIP.AllocationId + SubnetId: !Ref PublicSubnet1 + + NatGateway2: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NatGateway2EIP.AllocationId + SubnetId: !Ref PublicSubnet2 + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + Tags: + - Key: Name + Value: !Sub ${ProjectName} Public Routes + + DefaultPublicRoute: + Type: AWS::EC2::Route + DependsOn: InternetGatewayAttachment + Properties: + RouteTableId: !Ref PublicRouteTable + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: !Ref InternetGateway + + PublicSubnet1RouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PublicRouteTable + SubnetId: !Ref PublicSubnet1 + + PublicSubnet2RouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PublicRouteTable + SubnetId: !Ref PublicSubnet2 + + PrivateRouteTable1: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + Tags: + - Key: Name + Value: !Sub ${ProjectName} Private Routes (AZ1) + + DefaultPrivateRoute1: + Type: AWS::EC2::Route + Properties: + RouteTableId: !Ref PrivateRouteTable1 + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: !Ref NatGateway1 + + PrivateSubnet1RouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable1 + SubnetId: !Ref PrivateSubnet1 + + PrivateRouteTable2: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + Tags: + - Key: Name + Value: !Sub ${ProjectName} Private Routes (AZ2) + + DefaultPrivateRoute2: + Type: AWS::EC2::Route + Properties: + RouteTableId: !Ref PrivateRouteTable2 + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: !Ref NatGateway2 + + PrivateSubnet2RouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTable2 + SubnetId: !Ref PrivateSubnet2 + + NodesSDPolicy: + Type: AWS::IAM::ManagedPolicy + Properties: + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: ['servicediscovery:UpdateInstanceCustomHealthStatus'] + Resource: '*' + + VPCPeerRole: + Type: 'AWS::IAM::Role' + Properties: + AssumeRolePolicyDocument: + Statement: + - Principal: + AWS: !Ref BackendAccountId + Action: + - 'sts:AssumeRole' + Effect: Allow + Path: / + Policies: + - PolicyName: root + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: 'ec2:AcceptVpcPeeringConnection' + Resource: '*' + +Outputs: + VPC: + Description: A reference to the created VPC + Value: !Ref VPC + Export: + Name: !Sub '${ProjectName}:VPC' + + PublicSubnets: + Description: A list of the public subnets + Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2 ]] + + PrivateSubnets: + Description: A list of the private subnets + Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]] + + PublicSubnet1: + Description: A reference to the public subnet in the 1st Availability Zone + Value: !Ref PublicSubnet1 + Export: + Name: !Sub '${ProjectName}:PublicSubnet1' + + PublicSubnet2: + Description: A reference to the public subnet in the 2nd Availability Zone + Value: !Ref PublicSubnet2 + Export: + Name: !Sub '${ProjectName}:PublicSubnet2' + + PrivateSubnet1: + Description: A reference to the private subnet in the 1st Availability Zone + Value: !Ref PrivateSubnet1 + Export: + Name: !Sub '${ProjectName}:PrivateSubnet1' + + PrivateRouteTable1: + Value: !Ref PrivateRouteTable1 + Export: + Name: !Sub '${ProjectName}:PrivateRouteTable1' + + PrivateRouteTable2: + Value: !Ref PrivateRouteTable2 + Export: + Name: !Sub '${ProjectName}:PrivateRouteTable2' + + PrivateSubnet2: + Description: A reference to the private subnet in the 2nd Availability Zone + Value: !Ref PrivateSubnet2 + Export: + Name: !Sub '${ProjectName}:PrivateSubnet2' + + NodesSDPolicy: + Description: IAM Policy that will be added to the EKS nodes + Value: !Ref NodesSDPolicy + Export: + Name: !Sub '${ProjectName}:NodesSDPolicy' + + VPCPeerRole: + Value: !GetAtt + - VPCPeerRole + - Arn + Export: + Name: !Sub '${ProjectName}:VPCPeerRole' \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/setup.sh b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/setup.sh new file mode 100755 index 00000000..ec47b185 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/infrastructure/setup.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -e + +echo "Creating the Frontend Account VPC..." + +aws --profile frontend cloudformation deploy \ +--template-file infrastructure/infrastructure_frontend.yaml \ +--parameter-overrides \ +"BackendAccountId=$(aws --profile backend sts get-caller-identity | jq -r .Account)" \ +--stack-name am-multi-account-infra \ +--capabilities CAPABILITY_IAM + +echo "Creating the Backend Account VPC..." + +aws --profile backend cloudformation deploy \ +--template-file infrastructure/infrastructure_backend.yaml \ +--parameter-overrides \ +"FrontendAccountId=$(aws --profile frontend sts get-caller-identity | jq -r .Account)" \ +"PeerVPCId=$(aws --profile frontend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:VPC") | .Value')" \ +"PeerRoleArn=$(aws --profile frontend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:VPCPeerRole") | .Value')" \ +--stack-name am-multi-account-infra \ +--capabilities CAPABILITY_IAM + +echo "Creating the VPC peering routes..." + +aws --profile frontend cloudformation deploy \ +--template-file infrastructure/frontend_vpc_peering_routes.yaml \ +--parameter-overrides \ +"VPCPeeringConnectionId=$(aws --profile backend cloudformation list-exports | jq -r '.Exports[] | select(.Name=="am-multi-account:VPCPeeringConnectionId") | .Value')" \ +--stack-name am-multi-account-routes \ +--capabilities CAPABILITY_IAM + +aws --profile backend cloudformation deploy \ +--template-file infrastructure/backend_vpc_peering_routes.yaml \ +--stack-name am-multi-account-routes \ +--capabilities CAPABILITY_IAM + diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/Config b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/Config new file mode 100644 index 00000000..7b359f7e --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/Config @@ -0,0 +1,26 @@ +package.Appmeshtls_multiaccounts = { + interfaces = (1.0); + + # Use NoOpBuild. See https://w.amazon.com/index.php/BrazilBuildSystem/NoOpBuild + build-system = no-op; + build-tools = { + 1.0 = { + NoOpBuild = 1.0; + }; + }; + + # Use runtime-dependencies for when you want to bring in additional + # packages when deploying. + # Use dependencies instead if you intend for these dependencies to + # be exported to other packages that build against you. + dependencies = { + 1.0 = { + }; + }; + + runtime-dependencies = { + 1.0 = { + }; + }; + +}; diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/apply_tls_on_yelb_nodes.sh b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/apply_tls_on_yelb_nodes.sh new file mode 100755 index 00000000..872d0ef5 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/apply_tls_on_yelb_nodes.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +#CreateCA +export certificateAuthorityArn=$(aws acm-pca create-certificate-authority --certificate-authority-configuration file://ca_config.txt --revocation-configuration file://revoke_config.txt --certificate-authority-type "ROOT" --idempotency-token 98256344 --tags Key=Name,Value=MyAppMeshPCA --profile frontend |jq -r '.CertificateAuthorityArn' ) + +sleep 0.5 + +export csr1=$(aws acm-pca get-certificate-authority-csr --certificate-authority-arn $certificateAuthorityArn --profile frontend |jq '.Csr') + +echo $csr1 > ca.csr +awk '{gsub(/\\n/,"\n")}1' ca.csr > ca_csr.csr +sed -i 's/\"//g' ca_csr.csr + + + +export CertificateArn=$(aws acm-pca issue-certificate --certificate-authority-arn $certificateAuthorityArn --csr file://ca_csr.csr --signing-algorithm SHA256WITHRSA --template-arn arn:aws:acm-pca:::template/RootCACertificate/V1 --validity Value=10,Type="YEARS" --idempotency-token 1234 --profile frontend | jq -r '.CertificateArn' ) + + +certificate=$(aws acm-pca get-certificate --certificate-authority-arn $certificateAuthorityArn --certificate-arn $CertificateArn --profile frontend |jq '.Certificate') + +echo $certificate > certificate.cer +awk '{gsub(/\\n/,"\n")}1' certificate.cer > cert.cer +sed -i 's/\"//g' cert.cer +aws acm-pca import-certificate-authority-certificate --certificate-authority-arn $certificateAuthorityArn --certificate file://cert.cer --profile frontend + +aws acm-pca create-permission --certificate-authority-arn $certificateAuthorityArn --actions IssueCertificate GetCertificate ListPermissions --principal acm.amazonaws.com --profile frontend + +#RAMShareCA +export frontendaccount=$(aws sts get-caller-identity --profile frontend | jq -r .'Account') +export backendaccount=$(aws sts get-caller-identity --profile backend | jq -r .'Account') + +export resourceshareArn=$(aws ram create-resource-share --name Shared_Private_CA_MESH --resource-arn $certificateAuthorityArn --principals $backendaccount --profile frontend | jq -r '.resourceShare.resourceShareArn') + +sleep 1 + +export CA_RESOURCE_INVITE_ARN=$(aws --profile backend ram get-resource-share-invitations | jq -r '.resourceShareInvitations[]|select (.resourceShareArn=='\"$resourceshareArn\"')|.resourceShareInvitationArn') + +aws --profile backend ram accept-resource-share-invitation --resource-share-invitation-arn $CA_RESOURCE_INVITE_ARN + + +#UpdateVirtualNodes +export backend_certificate_arn=$(aws acm request-certificate --domain-name "*.example.com" --certificate-authority-arn $certificateAuthorityArn --query CertificateArn --output text --profile backend) +export frontend_certificate_arn=$(aws acm request-certificate --domain-name "*.example.com" --certificate-authority-arn $certificateAuthorityArn --query CertificateArn --output text --profile frontend) + + +export frontendworkerrole=$(eksctl get iamidentitymapping --profile frontend --cluster am-multi-account-1 -o json |jq -r '.[].rolearn |split("/")|.[1]') +export backendworkerrole=$(eksctl get iamidentitymapping --profile backend --cluster am-multi-account-2 -o json |jq -r '.[].rolearn |split("/")|.[1]') + +aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSCertificateManagerReadOnly --role-name $frontendworkerrole --profile frontend +aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSCertificateManagerPrivateCAReadOnly --role-name $frontendworkerrole --profile frontend +aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSAppMeshPreviewEnvoyAccess --role-name $frontendworkerrole --profile frontend + + +aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSCertificateManagerReadOnly --role-name $backendworkerrole --profile backend +aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSCertificateManagerPrivateCAReadOnly --role-name $backendworkerrole --profile backend +aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AWSAppMeshPreviewEnvoyAccess --role-name $backendworkerrole --profile backend + + + +sed -e "s%CERTIFICATE_ARN%"$backend_certificate_arn"%g" -e "s%CA_ARN%"$certificateAuthorityArn"%g" -e "s%FRONTEND_ACCOUNT%"$frontendaccount"%g" redis_update > redis_update.json +sed -e "s%CERTIFICATE_ARN%"$backend_certificate_arn"%g" -e "s%CA_ARN%"$certificateAuthorityArn"%g" -e "s%FRONTEND_ACCOUNT%"$frontendaccount"%g" appserver_update > appserver_update.json +sed -e "s%CERTIFICATE_ARN%"$backend_certificate_arn"%g" -e "s%CA_ARN%"$certificateAuthorityArn"%g" -e "s%FRONTEND_ACCOUNT%"$frontendaccount"%g" yelb_db_update > yelb_db_update.json +sed -e "s%FRONTEND_CERTIFICATE_ARN%"$frontend_certificate_arn"%g" -e "s%CA_ARN%"$certificateAuthorityArn"%g" -e "s%FRONTEND_ACCOUNT%"$frontendaccount"%g" yelb_ui_update > yelb_ui_update.json + + +kubectl apply -f mesh/redis_update.yaml +kubectl apply -f mesh/appserver_update.yaml +kubectl apply -f mesh/yelb_db_update.yaml +kubectl apply -f mesh/yelb_ui_update.yaml + + diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/appserver_update.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/appserver_update.yaml new file mode 100644 index 00000000..59aebf37 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/appserver_update.yaml @@ -0,0 +1,81 @@ +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualNode +metadata: + name: yelb-appserver + namespace: yelb +spec: + backendDefaults: + clientPolicy: + tls: + enforce: true, + validation: + trust: + acm: + certificateAuthorityArns: CA_ARN + podSelector: + matchLabels: + app: yelb-appserver + listeners: + - portMapping: + port: 4567 + protocol: http + - tls: + mode: STRICT + certificate: + acm: + certificateArn: + protocol: http + serviceDiscovery: + awsCloudMap: + namespaceName: am-multi-account.local + serviceName: yelb-appserver + backends: + - virtualService: + virtualServiceRef: + name: yelb-db + - virtualService: + virtualServiceRef: + name: redis-server +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualRouter +metadata: + namespace: yelb + name: yelb-appserver +spec: + awsName: yelb-appserver-virtual-router + listeners: + - portMapping: + port: 4567 + protocol: http + routes: + - name: route-to-yelb-appserver + httpRoute: + match: + prefix: / + action: + weightedTargets: + - virtualNodeRef: + name: yelb-appserver + weight: 1 + retryPolicy: + maxRetries: 2 + perRetryTimeout: + unit: ms + value: 2000 + httpRetryEvents: + - server-error + - client-error + - gateway-error +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualService +metadata: + name: yelb-appserver + namespace: yelb +spec: + awsName: yelb-appserver + provider: + virtualRouter: + virtualRouterRef: + name: yelb-appserver diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/ca_config.txt b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/ca_config.txt new file mode 100644 index 00000000..8da6573e --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/ca_config.txt @@ -0,0 +1,12 @@ +{ + "KeyAlgorithm":"RSA_2048", + "SigningAlgorithm":"SHA256WITHRSA", + "Subject":{ + "Country":"US", + "Organization":"Example Corp", + "OrganizationalUnit":"Sales", + "State":"WA", + "Locality":"Seattle", + "CommonName":"www.example.com" + } +} diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/create_mesh.sh b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/create_mesh.sh new file mode 100755 index 00000000..eece4d93 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/create_mesh.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +MESH_OWNER=$(aws --profile frontend sts get-caller-identity | jq -r .Account) + +cat > /tmp/app-mesh.yml <<-EKS_CONF + apiVersion: appmesh.k8s.aws/v1beta2 + kind: Mesh + metadata: + name: am-multi-account-mesh + spec: + meshOwner: "$MESH_OWNER" + namespaceSelector: + matchLabels: + mesh: am-multi-account-mesh +EKS_CONF + +kubectl apply -f /tmp/app-mesh.yml diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/redis_update.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/redis_update.yaml new file mode 100644 index 00000000..fdf91d69 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/redis_update.yaml @@ -0,0 +1,43 @@ +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualNode +metadata: + name: redis-server + namespace: yelb +spec: + backendDefaults: + clientPolicy: + tls: + enforce: true, + validation: + trust: + acm: + certificateAuthorityArns: CA_ARN + podSelector: + matchLabels: + app: redis-server + listeners: + - portMapping: + port: 6379 + protocol: tcp + - tls: + mode: STRICT + certificate: + acm: + certificateArn: + protocol: http + serviceDiscovery: + dns: + hostname: redis-server.yelb.svc.cluster.local + +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualService +metadata: + name: redis-server + namespace: yelb +spec: + awsName: redis-server + provider: + virtualNode: + virtualNodeRef: + name: redis-server diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/revoke_config.txt b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/revoke_config.txt new file mode 100644 index 00000000..3c7f664e --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/revoke_config.txt @@ -0,0 +1,8 @@ +{ + "CrlConfiguration":{ + "Enabled":false, + "ExpirationInDays":7, + "CustomCname":"some_name.crl", + "S3BucketName":"your-bucket-name" + } +} diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-appserver.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-appserver.yaml new file mode 100644 index 00000000..766c54b8 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-appserver.yaml @@ -0,0 +1,67 @@ +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualNode +metadata: + name: yelb-appserver + namespace: yelb +spec: + podSelector: + matchLabels: + app: yelb-appserver + listeners: + - portMapping: + port: 4567 + protocol: http + serviceDiscovery: + awsCloudMap: + namespaceName: am-multi-account.local + serviceName: yelb-appserver + backends: + - virtualService: + virtualServiceRef: + name: yelb-db + - virtualService: + virtualServiceRef: + name: redis-server +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualRouter +metadata: + namespace: yelb + name: yelb-appserver +spec: + awsName: yelb-appserver-virtual-router + listeners: + - portMapping: + port: 4567 + protocol: http + routes: + - name: route-to-yelb-appserver + httpRoute: + match: + prefix: / + action: + weightedTargets: + - virtualNodeRef: + name: yelb-appserver + weight: 1 + retryPolicy: + maxRetries: 2 + perRetryTimeout: + unit: ms + value: 2000 + httpRetryEvents: + - server-error + - client-error + - gateway-error +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualService +metadata: + name: yelb-appserver + namespace: yelb +spec: + awsName: yelb-appserver + provider: + virtualRouter: + virtualRouterRef: + name: yelb-appserver \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-db.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-db.yaml new file mode 100644 index 00000000..ee1e4192 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-db.yaml @@ -0,0 +1,28 @@ +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualNode +metadata: + name: yelb-db + namespace: yelb +spec: + podSelector: + matchLabels: + app: yelb-db + listeners: + - portMapping: + port: 5432 + protocol: tcp + serviceDiscovery: + dns: + hostname: yelb-db.yelb.svc.cluster.local +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualService +metadata: + name: yelb-db + namespace: yelb +spec: + awsName: yelb-db + provider: + virtualNode: + virtualNodeRef: + name: yelb-db \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-redis.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-redis.yaml new file mode 100644 index 00000000..f96fcce0 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-redis.yaml @@ -0,0 +1,28 @@ +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualNode +metadata: + name: redis-server + namespace: yelb +spec: + podSelector: + matchLabels: + app: redis-server + listeners: + - portMapping: + port: 6379 + protocol: tcp + serviceDiscovery: + dns: + hostname: redis-server.yelb.svc.cluster.local +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualService +metadata: + name: redis-server + namespace: yelb +spec: + awsName: redis-server + provider: + virtualNode: + virtualNodeRef: + name: redis-server diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-ui.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-ui.yaml new file mode 100644 index 00000000..74e4c922 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb-ui.yaml @@ -0,0 +1,32 @@ +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualNode +metadata: + name: yelb-ui + namespace: yelb +spec: + podSelector: + matchLabels: + app: yelb-ui + listeners: + - portMapping: + port: 4567 + protocol: http + serviceDiscovery: + dns: + hostname: yelb-ui.yelb.svc.cluster.local + backends: + - virtualService: + virtualServiceARN: + +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualService +metadata: + name: yelb-ui + namespace: yelb +spec: + awsName: yelb-ui + provider: + virtualNode: + virtualNodeRef: + name: yelb-ui \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb_db_update.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb_db_update.yaml new file mode 100644 index 00000000..670e7ede --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb_db_update.yaml @@ -0,0 +1,43 @@ +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualNode +metadata: + name: yelb-db + namespace: yelb +spec: + backendDefaults: + clientPolicy: + tls: + enforce: true, + validation: + trust: + acm: + certificateAuthorityArns: CA_ARN + podSelector: + matchLabels: + app: yelb-db + listeners: + - portMapping: + port: 5432 + protocol: tcp + - tls: + mode: STRICT + certificate: + acm: + certificateArn: + protocol: http + serviceDiscovery: + dns: + hostname: yelb-db.yelb.svc.cluster.local + +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualService +metadata: + name: yelb-db + namespace: yelb +spec: + awsName: yelb-db + provider: + virtualNode: + virtualNodeRef: + name: yelb-db diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb_ui_update.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb_ui_update.yaml new file mode 100644 index 00000000..df767670 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/mesh/yelb_ui_update.yaml @@ -0,0 +1,46 @@ +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualNode +metadata: + name: yelb-ui + namespace: yelb +spec: + backendDefaults: + clientPolicy: + tls: + enforce: true, + validation: + trust: + acm: + certificateAuthorityArns: CA_ARN + podSelector: + matchLabels: + app: yelb-ui + listeners: + - portMapping: + port: 4567 + protocol: http + - tls: + mode: STRICT + certificate: + acm: + certificateArn: + protocol: http + serviceDiscovery: + dns: + hostname: yelb-ui.yelb.svc.cluster.local + backends: + - virtualService: + virtualServiceARN: + +--- +apiVersion: appmesh.k8s.aws/v1beta2 +kind: VirtualService +metadata: + name: yelb-ui + namespace: yelb +spec: + awsName: yelb-ui + provider: + virtualNode: + virtualNodeRef: + name: yelb-ui diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/readme.md b/walkthroughs/eks-app-mesh-cross-account-acm/readme.md new file mode 100644 index 00000000..7f5a0b1f --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/readme.md @@ -0,0 +1,155 @@ +## Configure Frontend and Backend Account Profiles + +``` +cat ~/.aws/credentials + +[frontend] +aws_access_key_id = ... +aws_secret_access_key = ... +[backend] +aws_access_key_id = ... +aws_secret_access_key = ... + +cat ~/.aws/config + +[profile frontend] +region = us-west-2 +[profile backend] +region = us-west-2 +``` + +## Deploy the + +``` +./infrastructure/setup.sh +``` + +## Deploy EKS + +``` +./eks/setup.sh +``` + +## Deploy the App Mesh Controller on our Frontend Cluster + +``` +kubectl config use-context @am-multi-account-1..eksctl.io +``` + +``` +helm repo add eks https://aws.github.io/eks-charts +``` + +``` +kubectl create ns appmesh-system +helm upgrade -i appmesh-controller eks/appmesh-controller \ +--namespace appmesh-system + +kubectl -n appmesh-system get pods +``` + +## Deploy and Share Mesh + +``` +kubectl create ns yelb +kubectl label namespace yelb mesh=am-multi-account-mesh +kubectl label namespace yelb "appmesh.k8s.aws/sidecarInjectorWebhook"=enabled +``` + +``` +./mesh/create_mesh.sh +``` + +``` +aws --profile frontend cloudformation deploy \ +--template-file shared_resources/shared_mesh.yaml \ +--parameter-overrides \ +"BackendAccountId=$(aws --profile backend sts get-caller-identity | jq -r .Account)" \ +--stack-name am-multi-account-shared-mesh \ +--capabilities CAPABILITY_IAM +``` + +## Accept the invitation + +``` +aws --profile backend ram get-resource-share-invitations + +aws --profile backend ram accept-resource-share-invitation \ +--resource-share-invitation-arn +``` + +## Deploy the App Mesh Controller on our Backend Cluster + +``` +kubectl config use-context .eksctl.io +``` + +``` +helm repo add eks https://aws.github.io/eks-charts +``` + +``` +kubectl create ns appmesh-system +helm upgrade -i appmesh-controller eks/appmesh-controller \ +--namespace appmesh-system + +kubectl -n appmesh-system get pods +``` + +## Create the App Mesh Service Role on our Backend Account + +``` +aws --profile backend iam create-service-linked-role --aws-service-name appmesh.amazonaws.com +``` + +## Deploy Mesh Resources on our Backend Cluster + +``` +kubectl create ns yelb + +kubectl label namespace yelb mesh=am-multi-account-mesh +kubectl label namespace yelb "appmesh.k8s.aws/sidecarInjectorWebhook"=enabled +``` + +``` +./mesh/create_mesh.sh + +kubectl apply -f mesh/yelb-redis.yaml +kubectl apply -f mesh/yelb-db.yaml +kubectl apply -f mesh/yelb-appserver.yaml +``` + +## Deploy Yelb Resources on our Backend Cluster + +``` +kubectl apply -f yelb/resources_backend.yaml +``` + +## Deploy Mesh Resources on our Primary Cluster + +``` +kubectl config use-context @am-multi-account-1..eksctl.io +``` + +**Get the ```yelb-appserver``` VirtualService ARN value using below command and update ```mesh/yelb-ui.yaml``` accordingly**. + +``` +kubectl --context=@am-multi-account-2..eksctl.io \ +-n yelb get virtualservice yelb-appserver +``` + +``` +kubectl apply -f mesh/yelb-ui.yaml +``` + +## Deploy Yelb Resources on our Frontend Cluster + +``` +kubectl apply -f yelb/resources_frontend.yaml +``` + +## Cleanup + +``` +./cleanup.sh +``` diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/shared_resources/shared_mesh.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/shared_resources/shared_mesh.yaml new file mode 100644 index 00000000..dc0d304c --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/shared_resources/shared_mesh.yaml @@ -0,0 +1,19 @@ +Parameters: + ProjectName: + Type: String + Description: Project name to link stacks + Default: am-multi-account + BackendAccountId: + Type: String + Description: Account Id to share resources with + +Resources: + MeshShare: + Type: AWS::RAM::ResourceShare + Properties: + AllowExternalPrincipals: true + Name: mesh-share + Principals: + - !Ref BackendAccountId + ResourceArns: + - !Sub 'arn:aws:appmesh:${AWS::Region}:${AWS::AccountId}:mesh/${ProjectName}-mesh' \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/yelb/resources_backend.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/yelb/resources_backend.yaml new file mode 100644 index 00000000..e6b49758 --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/yelb/resources_backend.yaml @@ -0,0 +1,100 @@ +apiVersion: v1 +kind: Service +metadata: + namespace: yelb + name: redis-server + labels: + app: redis-server + tier: cache +spec: + type: ClusterIP + ports: + - port: 6379 + selector: + app: redis-server + tier: cache +--- +apiVersion: v1 +kind: Service +metadata: + namespace: yelb + name: yelb-db + labels: + app: yelb-db + tier: backenddb +spec: + type: ClusterIP + ports: + - port: 5432 + selector: + app: yelb-db + tier: backenddb +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: yelb + name: redis-server +spec: + selector: + matchLabels: + app: redis-server + tier: cache + replicas: 1 + template: + metadata: + labels: + app: redis-server + tier: cache + spec: + containers: + - name: redis-server + image: redis:4.0.2 + ports: + - containerPort: 6379 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: yelb + name: yelb-db +spec: + replicas: 1 + selector: + matchLabels: + app: yelb-db + tier: backenddb + template: + metadata: + labels: + app: yelb-db + tier: backenddb + spec: + containers: + - name: yelb-db + image: mreferre/yelb-db:0.5 + ports: + - containerPort: 5432 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: yelb + name: yelb-appserver +spec: + replicas: 1 + selector: + matchLabels: + app: yelb-appserver + tier: middletier + template: + metadata: + labels: + app: yelb-appserver + tier: middletier + spec: + containers: + - name: yelb-appserver + image: mreferre/yelb-appserver:0.5 + ports: + - containerPort: 4567 \ No newline at end of file diff --git a/walkthroughs/eks-app-mesh-cross-account-acm/yelb/resources_frontend.yaml b/walkthroughs/eks-app-mesh-cross-account-acm/yelb/resources_frontend.yaml new file mode 100644 index 00000000..bae0423a --- /dev/null +++ b/walkthroughs/eks-app-mesh-cross-account-acm/yelb/resources_frontend.yaml @@ -0,0 +1,50 @@ +apiVersion: v1 +kind: Service +metadata: + namespace: yelb + name: yelb-ui + labels: + app: yelb-ui + tier: frontend +spec: + type: LoadBalancer + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: yelb-ui + tier: frontend +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: yelb + name: yelb-ui +spec: + replicas: 1 + selector: + matchLabels: + app: yelb-ui + tier: frontend + template: + metadata: + labels: + app: yelb-ui + tier: frontend + spec: + containers: + - name: yelb-ui + image: mreferre/yelb-ui:0.6 + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: yelb + name: yelb-appserver +spec: + type: ClusterIP + ports: + - port: 4567 \ No newline at end of file