Using Amazon API Gateway with microservices deployed on Amazon ECS
One convenient way to run microservices is to deploy them as Docker containers. Docker containers are quick to provision, easily portable, and provide process isolation. Amazon EC2 Container Service (Amazon ECS) provides a highly scalable, high performance container management service. This service supports Docker containers and enables you to easily run microservices on a managed cluster of Amazon EC2 instances.
Microservices usually expose REST APIs for use in front ends, third-party applications, and other microservices. A best practice is to manage these APIs with an API gateway. This provides a unique entry point for all of your APIs and also eliminates the need to implement API-specific code for things like security, caching, throttling, and monitoring for each of your microservices. You can implement this pattern in a few minutes using Amazon API Gateway. Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale.
In this post, we’ll explain how to use Amazon API Gateway to expose APIs for microservices running on Amazon ECS by leveraging the HTTP proxy mode of Amazon API Gateway. Amazon API Gateway can make proxy calls to any publicly accessible endpoint; for example, an Elastic Load Balancing load balancer endpoint in front of a microservice that is deployed on Amazon ECS. The following diagram shows the high level architecture described in this article:
You will see how you can benefit from stage variables to dynamically set the endpoint value depending on the stage of the API deployment.
In the first part of this post, we will walk through the AWS Management Console to create the dev
environment (ECS cluster, ELB load balancers, and API Gateway configuration). The second part explains how to automate the creation of a production environment with AWS CloudFormation and AWS CLI.
Creating a dev environment with the AWS Management Console
Let’s begin by provisioning a sample helloworld microservice using the Getting Started wizard.
Sign in to Amazon ECS console. If this is the first time you’re using the Amazon ECS console, you’ll see a welcome page. Otherwise, you’ll see the console home page and the Create Cluster button.
Step 1: Create a task definition
- In the Amazon ECS console, do one of the following:
- If Get Started Now is displayed, choose it.
- If it is not displayed, go to the Getting Started wizard.
- Optional: (depending on the AWS Region) Deselect the Store container images securely with Amazon ECR checkbox and choose Continue.
- For Task definition name, type
ecsconsole-helloworld
. - For Container name, type
helloworld
. - Choose Advanced options and type the following text in the Command field:
/bin/sh -c "echo '{ \"hello\" : \"world\" }' > /usr/local/apache2/htdocs/index.html && httpd-foreground"
- Choose Update and then choose Next step
Step 2: Configure service
- For Service name, type
ecsconsole-service-helloworld
. - For Desired number of tasks, type
2
. - In the Elastic load balancing section, for Container name: host port, choose
helloworld:80
. - For Select IAM role for service, choose Create new role or use an existing
ecsServiceRole
if you already created the required role. - Choose Next Step.
Step 3: Configure cluster
- For Cluster name, type
dev
. - For Number of instances, type
2
. - For Select IAM role for service, choose Create new role or use an existing
ecsInstanceRole
if you already created the required role. - Choose Review and Launch and then choose Launch Instance & Run Service.
At this stage, after a few minutes of pending process, the helloworld microservice will be running in the dev ECS cluster with an ELB load balancer in front of it. Make note of the DNS Name of the ELB load balancer for later use; you can find it in the Load Balancers section of the EC2 console.
Configuring API Gateway
Now, let’s configure API Gateway to expose the APIs of this microservice. Sign in to the API Gateway console. If this is your first time using the API Gateway console, you’ll see a welcome page. Otherwise, you’ll see the API Gateway console home page and the Create API button.
Step 1: Create an API
- In the API Gateway console, do one of the following:
- If Get Started Now is displayed, choose it.
- If Create API is displayed, choose it.
- If neither is displayed, in the secondary navigation bar, choose the API Gateway console home button, and then choose Create API.
- For API name, type
EcsDemoAPI
. - Choose Create API.
Step 2: Create Resources
- In the API Gateway console, choose the root resource (/), and then choose Create Resource.
- For Resource Name, type
HelloWorld
. - For Resource Path, leave the default value of
/helloworld
. - Choose Create Resource.
Step 3: Create GET Methods
- In the Resources pane, choose /helloworld, and then choose Create Method.
- For the HTTP method, choose GET, and then save your choice.
Step 4: Specify Method Settings
- In the Resources pane, in /helloworld, choose GET.
- In the Setup pane, for Integration type, choose HTTP Proxy.
- For HTTP method, choose GET.
- For Endpoint URL, type
http://${stageVariables.helloworldElb}
- Choose Save.
Step 5: Deploy the API
- In the Resources pane, choose Deploy API.
- For Deployment stage, choose New Stage.
- For Stage name, type
dev
. - Choose Deploy.
- In the stage settings page, choose the Stage Variables tab.
- Choose Add Stage Variable, type
helloworldElb
for Name, type the DNS Name of the ELB in the Value field and then save.
Step 6: Test the API
- In the Stage Editor pane, next to Invoke URL, copy the URL to the clipboard. It should look something like this:
https://.execute-api..amazonaws.com/dev
- Paste this URL in the address box of a new browser tab.
- Append
/helloworld
to the URL and validate. You should see the following JSON document:{ "hello": "world" }
Automating prod environment creation
Now we’ll improve this setup by automating the creation of the prod environment. We use AWS CloudFormation to set up the prod ECS cluster, deploy the helloworld service, and create an ELB in front of the service. You can use the template with your preferred method:
Using AWS CLI
aws cloudformation create-stack --stack-name EcsHelloworldProd --template-url https://s3.amazonaws.com/rko-public-bucket/ecs_cluster.template --parameters ParameterKey=AsgMaxSize,ParameterValue=2 ParameterKey=CreateElasticLoadBalancer,ParameterValue=true ParameterKey=EcsInstanceType,ParameterValue=t2.micro
Using AWS console
Launch the AWS CloudFormation stack with the Launch Stack button below and use these parameter values:
- AsgMaxSize:
2
- CreateElasticLoadBalancer:
true
- EcsInstanceType:
t2.micro
Configuring API Gateway with AWS CLI
We’ll use the API Gateway configuration that we created earlier and simply add the prod stage.
Here are the commands to create the prod stage and configure the stage variable to point to the ELB load balancer:
#Retrieve API ID API_ID=$(aws apigateway get-rest-apis --output text --query "items[?name=='EcsDemoAPI'].{ID:id}") #Retrieve ELB DNS name from CloudFormation Stack outputs ELB_DNS=$(aws cloudformation describe-stacks --stack-name EcsHelloworldProd --output text --query "Stacks[0].Outputs[?OutputKey=='EcsElbDnsName'].{DNS:OutputValue}") #Create prod stage and set helloworldElb variable aws apigateway create-deployment --rest-api-id $API_ID --stage-name prod --variables helloworldElb=$ELB_DNS
You can then test the API on the prod stage using this simple cURL command:
AWS_REGION=$(aws configure get region) curl https://$API_ID.execute-api.$AWS_REGION.amazonaws.com/prod/helloworld
You should see { "hello" : "world" }
as the result of the cURL request. If the result is an error message like {"message": "Internal server error"}
, verify that you have healthy instances behind your ELB load balancer. It can take some time to pass the health checks, so you’ll have to wait for a minute before trying again.
From the stage settings page you also have the option to export the API configuration to a Swagger file, including the API Gateway extension. Exporting the API configuration as a Swagger file enables you to keep the definition in your source repository. You can then import it at any time, either by overwriting the existing API or by importing it as a brand new API. The API Gateway import tool helps you parse the Swagger definition and import it into the service.
Conclusion
In this post, we looked at how to use Amazon API Gateway to expose APIs for microservices deployed on Amazon ECS. The integration with the HTTP proxy mode pointing to ELB load balancers is a simple method to ensure the availability and scalability of your microservice architecture. With ELB load balancers, you don’t have to worry about how your containers are deployed on the cluster.
We also saw how stage variables help you connect your APIs on different ELB load balancers, depending on the stage where the API is deployed.
https://aws.amazon.com/cn/blogs/compute/using-amazon-api-gateway-with-microservices-deployed-on-amazon-ecs/