8.2.4 AWS Route 53 Support
To use the Route 53 Service Discovery, you must meet the following criteria:
Run EC2 instances of some type
Have a domain name hosted in Route 53
Have a newer version of AWS-CLI (such as 14+)
Assuming you have those things, you are ready. It is not as fancy as Consul or Eureka, but other than some initial setup with the AWS-CLI, there is no other software running to go wrong. You can even support health checks if you add a custom health check to your service. If you would like to test if your account can create and use Service Discovery see the Integration Test section. More information can be found at https://docs.aws.amazon.com/Route53/latest/APIReference/overview-service-discovery.html.
Here are the steps:
Use AWS-CLI to create a namespace. You can make either a public or private one depending on what IPs or subnets you are using
Create a service with DNS Records with AWS-CLI command
Add health checks or custom health checks (optional)
Add Service ID to your application configuration file like so:
Sample application.yml
aws:
route53:
registration
enabled: true
aws-service-id: srv-978fs98fsdf
namespace: micronaut.io
micronaut:
application:
name: something
- Make sure you have the following dependencies included in your build file:
Sample build.gradle
compile "io.micronaut:micronaut-discovery-client"
compile "io.micronaut.configuration:micronaut-aws-common"
compile group: 'com.amazonaws', name: 'aws-java-sdk-route53', version: '1.11.297'
compile group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.297'
compile group: 'com.amazonaws', name: 'jmespath-java', version: '1.11.297'
compile group: 'com.amazonaws', name: 'aws-java-sdk-servicediscovery', version: '1.11.297'
- On the client side, you will need the same dependencies and less configuration options:
Sample application.yml
aws:
route53:
discovery:
client:
enabled: true
aws-service-id: srv-978fs98fsdf
namespace-id: micronaut.io
You can then use the DiscoveryClient API to find other services registered via Route 53. For example:
Sample code for client
DiscoveryClient discoveryClient = embeddedServer.applicationContext.getBean(DiscoveryClient);
List<String> serviceIds = Flowable.fromPublisher(discoveryClient.getServiceIds()).blockingFirst();
List<ServiceInstance> instances = Flowable.fromPublisher(discoveryClient.getInstances(serviceIds.get(0))).blockingFirst();
Creating the Namespace
Namespaces are similar to a regular Route53 hosted zone, and they appear in the Route53 console but the console doesn’t support modifying them. You must use the AWS-CLI at this time for any Service Discovery functionality.
First decide if you are creating a public facing namespace or a private one, as the commands are different:
Creating Namespace
$ aws servicediscovery create-public-dns-namespace --name micronaut.io --create-request-id create-1522767790 --description adescrptionhere
or
$ aws servicediscovery create-private-dns-namespace --name micronaut.internal.io --create-request-id create-1522767790 --description adescrptionhere --vpc yourvpcID
When you run this you will get an operation ID. You can check the status with the get-operation
CLI command:
Get Operation Results
$ aws servicediscovery get-operation --operation-id asdffasdfsda
You can use this command to get the status of any call you make that returns an operation id.
The result of the command will tell you the ID of the namespace. Write that down, you’ll need it for the next steps. If you get an error it will say what the error was.
Creating the Service & DNS Records
The next step is creating the Service and DNS records.
Create Service
$ aws create-service --name yourservicename --create-request-id somenumber --description someservicedescrption --dns-config NamespaceId=yournamespaceid,RoutingPolicy=WEIGHTED,DnsRecords=[{Type=A,TTL=1000},{Type=A,TTL=1000}]
The DnsRecord
type can be A
(ipv4),AAAA
(ipv6),SRV
, or CNAME
. RoutingPolicy
can be WEIGHTED
or MULTIVALUE
. Keep in mind CNAME
must use weighted routing type, SRV
must have a valid port configured.
If you want to add a health check, you can use the following syntax on the CLI:
Specifying a Health Check
Type=string,ResourcePath=string,FailureThreshold=integer
Type can be ‘HTTP’,’HTTPS’, or ‘TCP’. You can only use a standard health check on a public namespace. See Custom Health Checks for private namespaces. Resource path should be a url that returns 200 OK if it’s healthy.
For a custom health check, you only need to specify --health-check-custom-config FailureThreshold=integer
which will work on private namespaces as well.
This is also good because Micronaut will send out pulsation commands to let AWS know the instance is still healthy.
For more help run ‘aws discoveryservice create-service help’.
You will get a service ID and an ARN back from this command if successful. Write that down, it’s going to go into the Micronaut configuration.
Setting up the configuration in Micronaut
Auto Naming Registration
You will need to add the configuration to make your applications register with Route 53 Auto-discovery:
Registration Properties
aws:
route53:
registration:
enabled: true
aws-service-id=<enter the service id you got after creation on aws cli>
discovery:
namespace-id=<enter the namespace id you got after creating the namespace>
Discovery Client Configuration
Discovery Properties
aws:
route53:
discovery:
client
enabled: true
aws-service-id: <enter the service id you got after creation on aws cli>
You can also call the following methods by getting the bean “Route53AutoNamingClient”:
Discovery Methods
// if serviceId is null it will use property "aws.route53.discovery.client.awsServiceId"
Publisher<List<ServiceInstance>> getInstances(String serviceId)
// reads property "aws.route53.discovery.namespaceId"
Publisher<List<String>> getServiceIds()
Integration Tests
If you set the environment variable AWS_SUBNET_ID and have credentials configured in your home directory that are valid (in ~/.aws/credentials
) you can run the integration tests. You will still need a domain hosted on route53 as well. This test will create a t2.nano instance, a namespace, service, and register that instance to service discovery. When the test completes it will remove/terminate all resources it spun up.