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:

  1. 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

  2. Create a service with DNS Records with AWS-CLI command

  3. Add health checks or custom health checks (optional)

  4. Add Service ID to your application configuration file like so:

Sample application.yml

  1. aws:
  2. route53:
  3. registration
  4. enabled: true
  5. aws-service-id: srv-978fs98fsdf
  6. namespace: micronaut.io
  7. micronaut:
  8. application:
  9. name: something
  1. Make sure you have the following dependencies included in your build file:
  1. implementation("io.micronaut.aws:micronaut-aws-route53")
  1. <dependency>
  2. <groupId>io.micronaut.aws</groupId>
  3. <artifactId>micronaut-aws-route53</artifactId>
  4. </dependency>
  1. On the client side, you will need the same dependencies and less configuration options:

Sample application.yml

  1. aws:
  2. route53:
  3. discovery:
  4. client:
  5. enabled: true
  6. aws-service-id: srv-978fs98fsdf
  7. 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

  1. DiscoveryClient discoveryClient = embeddedServer.applicationContext.getBean(DiscoveryClient);
  2. List<String> serviceIds = Flowable.fromPublisher(discoveryClient.getServiceIds()).blockingFirst();
  3. 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

  1. $ aws servicediscovery create-public-dns-namespace --name micronaut.io --create-request-id create-1522767790 --description adescriptionhere
  2. or
  3. $ aws servicediscovery create-private-dns-namespace --name micronaut.internal.io --create-request-id create-1522767790 --description adescriptionhere --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

  1. $ 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

  1. $ aws create-service --name yourservicename --create-request-id somenumber --description someservicedescription --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

  1. 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

  1. aws:
  2. route53:
  3. registration:
  4. enabled: true
  5. aws-service-id=<enter the service id you got after creation on aws cli>
  6. discovery:
  7. namespace-id=<enter the namespace id you got after creating the namespace>

Discovery Client Configuration

Discovery Properties

  1. aws:
  2. route53:
  3. discovery:
  4. client
  5. enabled: true
  6. 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

  1. // if serviceId is null it will use property "aws.route53.discovery.client.awsServiceId"
  2. Publisher<List<ServiceInstance>> getInstances(String serviceId)
  3. // reads property "aws.route53.discovery.namespaceId"
  4. 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.