3. Deploy infrastructure for the application

Create the VPC and other core Infrastructure

An Amazon Virtual Private Cloud (VPC) is a virtual network that provides isolation from other applications in other networks running on AWS. The following CloudFormation template will be used to create a VPC for our mesh sample applications:

examples/infrastructure/vpc.yaml

Set the following environment variables:

AWS_PROFILE - your AWS CLI profile (set to default or a named profile)

- your AWS CLI profile (set to or a named profile) AWS_DEFAULT_REGION - set to one of the Currently available AWS regions for App Mesh

- set to one of the Currently available AWS regions for App Mesh ENVIRONMENT_NAME - will be applied as a prefix to deployed CloudFormation stack names

Run the vpc.sh script to create a VPC for the application in the region you specify. It will be configured for two availability zones (AZs); each AZ will be configured with a public and a private subnet.

You can choose from one of the nineteen Currently available AWS regions for App Mesh. The deployment will include an Internet Gateway and a pair of NAT Gateways (one in each AZ) with default routes for them in the private subnets.

Create the VPC

examples/infrastructure/vpc.sh

$ export AWS_PROFILE=default

$ export AWS_DEFAULT_REGION=us-west-2

$ export ENVIRONMENT_NAME=DEMO

$ ./examples/infrastructure/vpc.sh

...

+ aws --profile default --region us-west-2 cloudformation deploy --stack-name DEMO-vpc --capabilities CAPABILITY_IAM --template-file examples/infrastructure/vpc.yaml --parameter-overrides EnvironmentName=DEMO

Waiting for changeset to be created..

Waiting for stack create/update to complete

...

Successfully created/updated stack - DEMO-vpc

$

Create an App Mesh

A service mesh a logical boundary for network traffic between services that reside in it. AWS App Mesh is a managed service mesh control plane. It provides application-level networking support, standardizing how you control and monitor your services across multiple types of compute infrastructure.

The following CloudFormation template will be used to create an App Mesh mesh for our application:

examples/infrastructure/appmesh-mesh.yaml

We will use the same environment variables from the previous step, plus one additional one ( MESH_NAME ), to deploy the stack.

MESH_NAME - name to use to identify the mesh you create (we'll use appmesh-mesh )

Create the mesh

examples/infrastructure/appmesh-mesh.sh

$ export AWS_PROFILE=default

$ export AWS_DEFAULT_REGION=us-west-2

$ export ENVIRONMENT_NAME=DEMO

$ export MESH_NAME=appmesh-mesh

$ ./examples/infrastructure/appmesh-mesh.sh

...

+ aws --profile default --region us-west-2 cloudformation deploy --stack-name DEMO-appmesh-mesh --capabilities CAPABILITY_IAM --template-file /home/ec2-user/projects/aws/aws-app-mesh-examples/examples/infrastructure/appmesh-mesh.yaml --parameter-overrides EnvironmentName=DEMO AppMeshMeshName=appmesh-mesh Waiting for changeset to be created..

Waiting for stack create/update to complete

...

Successfully created/updated stack - DEMO-appmesh-mesh

$

At this point we have now created our networking resources (VPC and App Mesh), but we have not yet deployed:

compute resources to run our services on

mesh configuration for our services

actual services

Create compute resources

Our infrastructure requires compute resources to run our services on. The following CloudFormation template will be used to create these resources for our application:

examples/infrastructure/ecs-cluster.yaml

In addition to the previously defined environment variables, you will also need to export the following:

SERVICES_DOMAIN - the base namespace to use for service discovery (e.g., cluster.local ). For this demo, we will use demo.local . This means that the gateway virtual service will send requests to the colorteller virtual service at colorteller.demo.local .

- the base namespace to use for service discovery (e.g., ). For this demo, we will use . This means that the gateway virtual service will send requests to the colorteller virtual service at . KEY_PAIR_NAME - your Amazon EC2 Key Pair to log into your EC2 instances.

Create the ECS cluster

examples/infrastructure/ecs-cluster.sh

$ export AWS_PROFILE=default

$ export AWS_DEFAULT_REGION=us-west-2

$ export ENVIRONMENT_NAME=DEMO

$ export SERVICES_DOMAIN=demo.local

$ export KEY_PAIR_NAME=tony_devbox2

$ ./examples/infrastructure/ecs-cluster.sh

...

+ aws --profile default --region us-west-2 cloudformation deploy --stack-name DEMO-ecs-cluster --capabilities CAPABILITY_IAM --template-file /home/ec2-user/projects/aws/aws-app-mesh-examples/examples/infrastructure/ecs-cluster.yaml --parameter-overrides EnvironmentName=DEMO KeyName=tony_devbox2 ECSServicesDomain=demo.local ClusterSize=5 Waiting for changeset to be created..

Waiting for stack create/update to complete

...

Successfully created/updated stack - DEMO-ecs-cluster

$

Review

You have provisioned the infrastructure you need. You can confirm in the AWS Console that all of your CloudFormation stacks have been successfully deployed. You should see something like this:

Figure 4. AWS Cloudformation stack deployments.

You can also confirm status with the AWS CLI:

$ aws cloudformation describe-stacks --stack-name DEMO-vpc --query 'Stacks[0].StackStatus'

"CREATE_COMPLETE" $ aws cloudformation describe-stacks --stack-name DEMO-appmesh-mesh --query 'Stacks[0].StackStatus'

"CREATE_COMPLETE" $ aws cloudformation describe-stacks --stack-name DEMO-ecs-cluster --query 'Stacks[0].StackStatus'

"CREATE_COMPLETE"

4. Deploy the application

Now that we’ve deployed our infrastructure resources for testing, let’s configure our mesh and finally deploy the Color App.

Configure App Mesh resources

We will now add our mesh resource definitions so that when we finally deploy our services, the mesh will be able to push computed configuration down to each Envoy proxy running as a sidecar for each ECS task. The following CloudFormation template will be used to create these resources for our application:

examples/apps/colorapp/servicemesh/appmesh-colorapp.yaml

We will use the same exported environment variables created previously. No new environment variables are needed.

Create mesh resources

examples/apps/colorapp/servicemesh/appmesh-colorapp.sh

$ export AWS_PROFILE=default

$ export AWS_DEFAULT_REGION=us-west-2

$ export ENVIRONMENT_NAME=DEMO

$ export SERVICES_DOMAIN=demo.local

$ export MESH_NAME=appmesh-mesh

$ ./examples/apps/colorteller/servicemesh/appmesh-colorapp.sh

...

+ aws --profile default --region us-west-2 cloudformation deploy --stack-name DEMO-appmesh-colorapp --capabilities CAPABILITY_IAM --template-file /home/ec2-user/projects/aws/aws-app-mesh-examples/examples/apps/colorapp/servicemesh/appmesh-colorapp.yaml --parameter-overrides EnvironmentName=DEMO ServicesDomain=demo.local AppMeshMeshName=appmesh-mesh Waiting for changeset to be created..

Waiting for stack create/update to complete

...

Successfully created/updated stack - DEMO-appmesh-colorapp

$

Note: the App Mesh resources for the Color App are created before the app itself is deployed in the final step; this is so Envoy, which is deployed as a task sidecar, is able to communicate with the Envoy Management Service. If the mesh itself isn’t configured first, the sidecar will remain unhealthy and eventually the task will fail.

Deploy services to ECS

Deploy images to ECR for your account

Before you can deploy the services, you will need to deploy the images that ECS will use for gateway and colorteller to ECR image repositories for your account. You can build these images from source under the examples/apps/colorteller/src and push them using the provided deploy scripts after you create repositories for them on ECR, as shown below.

Deploy the gateway image:

# from the colorapp repo root...

$ cd examples/apps/colorapp/src/gateway

$ aws ecr create-repository --repository-name=gateway

$ export COLOR_GATEWAY_IMAGE=$(aws ecr describe-repositories --repository-names=gateway --query 'repositories[0].repositoryUri' --output text)

$ ./deploy.sh

+ '[' -z 226767807331.dkr.ecr.us-west-2.amazonaws.com/gateway ']'

+ docker build -t 226767807331.dkr.ecr.us-west-2.amazonaws.com/gateway .

Sending build context to Docker daemon 1MB

Step 1/11 : FROM golang:1.10 AS builder

...

+ docker push 226767807331.dkr.ecr.us-west-2.amazonaws.com/gateway

The push refers to repository [226767807331.dkr.ecr.us-west-2.amazonaws.com/gateway]

latest: digest: sha256:ce597511c0230af89b81763eb51c808303e9ef8e1fbe677af02109d1f73a868c size: 528

$

Deploy the colorteller image:

# from the colorapp repo root....

$ cd examples/apps/colorapp/src/colorteller

$ aws ecr create-repository --repository-name=colorteller

$ export COLOR_TELLER_IMAGE=$(aws ecr describe-repositories --repository-names=colorteller --query 'repositories[0].repositoryUri' --output text)

$ ./deploy.sh

+ '[' -z 226767807331.dkr.ecr.us-west-2.amazonaws.com/colorteller:latest ']'

+ docker build -t 226767807331.dkr.ecr.us-west-2.amazonaws.com/colorteller:latest .

Sending build context to Docker daemon 996.4kB

Step 1/11 : FROM golang:1.10 AS builder

...

+ docker push 226767807331.dkr.ecr.us-west-2.amazonaws.com/colorteller:latest

The push refers to repository [226767807331.dkr.ecr.us-west-2.amazonaws.com/colorteller]

69856c2b3fc6: Layer already exists

latest: digest: sha256:ca16f12268907c32140586e2568e2032f04b95d70b373c00fcee7e776e2d29da size: 528

$

Deploy gateway and colorteller services

We will now deploy our services on ECS. The following CloudFormation template will be used to create these resources for our application:

examples/apps/colorapp/ecs/ecs-colorapp.yaml

In addition to the previously defined environment variables, you will also need to export the following:

ENVOY_IMAGE - see Envoy Image for latest recommended Docker image (currently: 111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.9.0.0-prod )

- see Envoy Image for latest recommended Docker image (currently: ) COLOR_GATEWAY_IMAGE - Docker image for the Color App gateway microservice (see example below).

- Docker image for the Color App gateway microservice (see example below). COLOR_TELLER_IMAGE - Docker image for the Color App colorteller microservice (see example below).

Deploy services to ECS

examples/apps/colorapp/ecs/ecs-colorapp.sh

$ export AWS_PROFILE=default

$ export AWS_DEFAULT_REGION=us-west-2

$ export ENVIRONMENT_NAME=DEMO

$ export SERVICES_DOMAIN=demo.local

$ export KEY_PAIR_NAME=tony_devbox2

$ export ENVOY_IMAGE=111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.9.0.0-prod

$ export COLOR_GATEWAY_IMAGE=$(aws ecr describe-repositories --repository-names=gateway --query 'repositories[0].repositoryUri' --output text)

$ export COLOR_TELLER_IMAGE=$(aws ecr describe-repositories --repository-names=colorteller --query 'repositories[0].repositoryUri' --output text)

$ ./examples/apps/colorapp/ecs/ecs-colorapp.sh

...

Waiting for changeset to be created..

Waiting for stack create/update to complete

...

Successfully created/updated stack - DEMO-ecs-colorapp

$

Test the application

Once we have deployed the app, we can curl the frontend service ( gateway ). To get the endpoint, run the following code:

$ colorapp=$(aws cloudformation describe-stacks --stack-name=$ENVIRONMENT_NAME-ecs-colorapp --query="Stacks[0

].Outputs[?OutputKey=='ColorAppEndpoint'].OutputValue" --output=text); echo $colorapp

http://DEMO-Publi-M7WJ5RU13M0T-553915040.us-west-2.elb.amazonaws.com $ curl $colorapp/color

{"color":"red", "stats": {"red":1}}