Loading repository data…
Loading repository data…
aws-samples / repository
This repo contains a simple application that consists of three microservices. Each application is deployed using different Compute options on AWS.
= Deploying Microservices on AWS Cloud :toc:
This repo contains a simple application that consists of three microservices. The sample application uses three services:
. webapp: Web application microservice calls greeting and name microservice to generate a greeting for a person.
. greeting: A microservice that returns a greeting.
. name: A microservice that returns a person’s name based upon {id} in the URL.
Each application is deployed using different AWS Compute options.
== Build and Test Services using Maven
. Each microservice is in a different repo:
+
[cols="1,3"]
|====
| greeting | https://github.com/arun-gupta/microservices-greeting
| name | https://github.com/arun-gupta/microservices-name
| webapp | https://github.com/arun-gupta/microservices-webapp
|====
+
. Clone all the repos. Open each one in a separate terminal.
. Run greeting service: mvn wildfly-swarm:run
.. Optionally test: curl http://localhost:8081/resources/greeting
. Run name service: mvn wildfly-swarm:run
.. Optionally test:
... curl http://localhost:8082/resources/names
... curl http://localhost:8082/resources/names/1
. Run webapp service: mvn wildfly-swarm:run
. Run the application: curl http://localhost:8080/
== Docker
=== Create Docker Images
mvn package -Pdocker for each repo will create the Docker image.
By default, the Docker image name is arungupta/<service> where <service> is greeting, name or webapp. The image can be created in your repo:
mvn package -Pdocker -Ddocker.repo=
By default, the latest tag is used for the image. A different tag may be specified as:
mvn package -Pdocker -Ddocker.tag=
=== Push Docker Images to Registry
Push Docker images to the registry:
mvn install -Pdocker
=== Deployment to Docker Swarm
. docker swarm init
. cd apps/docker
. docker stack deploy --compose-file docker-compose.yaml myapp
. Access the application: curl http://localhost:8080
.. Optionally test the endpoints:
... Greeting endpoint: curl http://localhost:8081/resources/greeting
... Name endpoint: curl http://localhost:8082/resources/names/1
. Remove the stack: docker stack rm myapp
==== Debug
. List stack:
docker stack ls
. List services in the stack:
docker stack services myapp
. List containers:
docker container ls -f name=myapp*
. Get logs for all the containers in the webapp service:
docker service logs myapp_webapp-service
== Amazon ECS and AWS Fargate
This section will explain how to deploy these microservices using Fargate on Amazon ECS cluster.
NOTE: AWS Fargate is not supported in all AWS regions. These instructions will only work in supported regions. Check the AWS's link:https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/[Regions Table] for details.
=== Deployment: Create Cluster using AWS Console
This section will explain how to create an ECS cluster using AWS Console.
Complete instructions are available at https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create_cluster.html.
Use the cluster name fargate-cluster.
=== Deployment: Create Cluster using AWS CloudFormation
This section will explain how to create an ECS cluster using CloudFormation.
The following resources are needed in order to deploy the sample application:
greeting and name and a public ALB for webapp. Create an ECS cluster with these resources:
cd apps/ecs/fargate/templates
aws cloudformation deploy
--stack-name fargate-cluster
--template-file infrastructure.yaml
--region us-east-1
--capabilities CAPABILITY_IAM
. View the output from the cluster:
aws cloudformation
describe-stacks
--region us-east-1
--stack-name fargate-cluster
--query 'Stacks[].Outputs[]'
--output text
==== Deployment: Simple ECS Cluster
This section explains how to create a ECS cluster with no additional resources. The cluster can be created with a private VPC or a public VPC. The CloudFormation templates for different types are available at https://github.com/awslabs/aws-cloudformation-templates/tree/master/aws/services/ECS/EC2LaunchType/clusters.
This section will create a 3-instance cluster using a public VPC:
curl -O https://raw.githubusercontent.com/awslabs/aws-cloudformation-templates/master/aws/services/ECS/EC2LaunchType/clusters/public-vpc.yml
aws cloudformation deploy
--stack-name MyECSCluster
--template-file public-vpc.yml
--region us-east-1
--capabilities CAPABILITY_IAM
List the cluster using aws ecs list-clusters command:
{ "clusterArns": [ "arn:aws:ecs:us-east-1:091144949931:cluster/MyECSCluster-ECSCluster-197YNE1ZHPSOP" ] }
=== Deployment: Create Cluster and Deploy Services using Fargate CLI
This section explains how to create a Fargate cluster and run services on it.
. Download CLI from http://somanymachines.com/fargate/ . Create the LoadBalancer:
fargate lb create
microservices-lb
--port 80
. Create greeting service:
fargate service create greeting-service
--lb microservices-lb
-m 1024
-i arungupta/greeting
-p http:8081
--rule path=/resources/greeting
. Create name service:
fargate service create name-service
--lb microservices-lb
-m 1024
-i arungupta/name
-p http:8082
--rule path=/resources/names/*
. Get URL of the LoadBalancer:
fargate lb info microservices-lb
. Create webapp service:
fargate service create webapp-service
--lb microservices-lb
-m 1024
-i arungupta/webapp
-p http:8080
-e GREETING_SERVICE_HOST=
-e GREETING_SERVICE_PORT=80
-e GREETING_SERVICE_PATH=/resources/greeting
-e NAME_SERVICE_HOST=
-e NAME_SERVICE_PORT=80
-e NAME_SERVICE_PATH=/resources/names
. Test the application:
curl http:// curl http:///0
. Scale the service: fargate service scale webapp-service +3
. Clean up the resources:
fargate service scale greeting-service 0 fargate service scale name-service 0 fargate service scale webapp-service 0 fargate lb destroy microservices-lb
NOTE: As described at https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_limits.html, the number of tasks using the Fargate launch type, per region, per account is 20. This limit can be increased by filing a support ticket from the AWS Console.
=== Deployment: Deploy Tasks and Service using ECS CLI
This section will explain how to create an ECS cluster using a CloudFormation template. The tasks are then deployed using ECS CLI and Docker Compose definitions.
==== Pre-requisites
. Install https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_CLI.html[ECS CLI]. . Install - https://www.perl.org/get.html[Perl].
==== Deploy the application
. Run the CloudFormation template to create the AWS resources:
+
|===
|Region | Launch Template
| N. Virginia (us-east-1)
a| image::./images/deploy-to-aws.png[link=https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=aws-microservices-deploy-options-ecscli&templateURL=https://s3.amazonaws.com/aws-microservices-deploy-options/infra.yaml]
|===
+
. Run the follow command to capture the output from the CloudFormation template as key/value pairs in the file ecs-cluster.props. These will be used to setup environment variables which are used subseqently.
aws cloudformation describe-stacks \
--stack-name aws-microservices-deploy-options-ecscli \
--query 'Stacks[0].Outputs' \
--output=text | \
perl -lpe 's/\s+/=/g' | \
tee ecs-cluster.props
. Setup the environment variables using this file:
set -o allexport
source ecs-cluster.props
set +o allexport
. Configure ECS CLI:
ecs-cli configure --cluster $ECSCluster --region us-east-1 --default-launch-type FARGATE
. Create the task definition parameters for each of the service:
ecs-params-create.sh greeting
ecs-params-create.sh name
ecs-params-create.sh webapp
. Start the greeting service up:
ecs-cli compose --verbose \
--file greeting-docker-compose.yaml \
--task-role-arn $ECSRole \
--ecs-params ecs-params_greeting.yaml \
--project-name greeting \
service up \
--target-group-arn $GreetingTargetGroupArn \
--container-name greeting-service \
--container-port 8081
. Bring the name service up:
ecs-cli compose --verbose \
--file name-docker-compose.yaml \
--task-role-arn $ECSRole \
--ecs-params ecs-params_name.yaml \
--project-name name \
service up \
--target-group-arn $NameTargetGroupArn \
--container-name name-service \
--container-port 8082
. Bring the webapp service up:
+
ecs-cli compose --verbose
--file webapp-docker-compose.yaml
--task-role-arn $ECSRole
--ecs-params ecs-params_webapp.yaml
--project-name webapp
service up
--target-group-arn $WebappTargetGroupArn
--container-name webapp-service
--container-port 8080
+
Docker Compose supports environment variable substitution. The webapp-docker-compose.yaml uses $PrivateALBCName to refer to the private Application Load Balancer for greeting and name service.
+
. Check the healthy status of different services:
aws elbv2 describe-target-health \
--target-group-arn $GreetingTargetGroupArn \
--query 'TargetHealthDescriptions[0].TargetHealth.State' \
--output text
aws elbv2 describe-target-health \
--target-group-arn $NameTargetGroupArn \
--query 'TargetHealthDescriptions[0].TargetHealth.State' \
--output text
aws elbv2 describe-target-health \
--target-group-arn $WebappTargetGroupArn \
--query 'TargetHealthDescriptions[0].TargetHealth.State' \
--output text
. Once all the services are in healthy state, get a response from the webapp service:
curl http://"$ALBPublicCNAME" Hello Sheldon
==== Tear down the resources
ecs-cli compose --verbose
--file greeting-docker-compose.yaml
--task-role-arn $ECSRole
--ecs-params ecs-params_greeting.yaml
--project-name greeting
service down
ecs-cli compose --verbose
--file name-docker-compose.yaml
--task-role-arn $ECSRole
--ecs-params ecs-params_name.yaml
--project-name name
service down
ecs-cli compose --verbose
--file webapp-docker-compose.yaml
--task-role-arn $ECSRole
--ecs-params ecs-params_webapp.yaml
--project-name webapp
service down
aws cloudformation delete-stack --region us-east-1 --stack-name aws-microservices-deploy-options-ecscli
=== Deployment: Create Cluster and Deploy Fargate Tasks using CloudFormation
This section creates an ECS cluster and deploys Fargate tasks to the cluster:
|=== |Region | Launch Template | N. Virginia (us-east-1) a| image::./images/deploy-to-aws.png[link=https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=aws-compute-options-fargate&templateURL=https://s3.amazonaws.com/DOC-EXAMPLE-BUCKET/master.yaml] |===
Retrieve the public endpoint to test your application deployment:
aws cloudformation
describe-stacks
--region us-east-1
--stack-name aws-compute-options-fargate
--query 'Stacks[].Outputs[?OutputKey==PublicALBCNAME].[OutputValue]'
--output text
Use the command to test:
curl http://<public_endpoint>
=== Deployment: Create Cluster and Deploy EC2 Tasks using CloudFormation
This section creates an ECS cluster and deploys EC2 tasks to the cluster:
|=== |Region | Launch Template | N. Virginia (us-east-1) a| image: