I've successfully connected one of our microservices to Eureka using Fargate. Eureka is currently on an actual EC2 instance and microservices will be running from Fargate (hopefully Eureka too if I manage to get it to work). I have already got this running properly (or it seems as microservices connect to Eureka), with that said, I am getting a FreeMarker template error on the Eureka status page under the AMIs columns in "Instances currently registered with Eureka".

What I have done to achieve this Fargate to EC2 Eureka connection with private IP is the following. This dockerfile loads an entrypoint file which runs a shell script.

Dockerfile:

#############
### build ###
#############

# base image
FROM maven:3.6.2-ibmjava-8-alpine as build

# set working directory
WORKDIR /app


# install and cache app dependencies
COPY . /app
RUN mvn clean package


############
### prod ###
############

# base image
FROM openjdk:8-alpine

RUN apk add jq

# set working directory
WORKDIR /app

# copy entrypoint from the 'build environment'
COPY --from=build /app/entrypoint.sh /app/entrypoint.sh

# copy artifact build from the 'build environment'
COPY --from=build /app/target/user-service-0.0.1-SNAPSHOT.jar /app/user-service-0.0.1-SNAPSHOT.jar

# expose port 8081
EXPOSE 8081

# run entrypoint
ENTRYPOINT ["/bin/sh", "./entrypoint.sh"]

This entrypoint shell script saves the private IP from the Fargate metadata endpoint into the shell session. entrypoint.sh:

#!/bin/sh
export FARGATE_IP=$(wget -q -O - http://169.254.170.2/v2/metadata | jq -r .Containers[0].Networks[0].IPv4Addresses[0])
echo $FARGATE_IP
java -jar user-service-0.0.1-SNAPSHOT.jar

The application property file loads the Fargate private IP so the microservice connects successfully. application-aws.properties

eureka.client.region=us-east-1
eureka.client.use-dns-for-fetching-service-urls=true
eureka.client.eureka-server-u-r-l-context=eureka
eureka.client.eureka-server-d-n-s-name=eureka.domain.com
eureka.client.eureka-server-port=8761
eureka.instance.prefer-ip-address=true
eureka.instance.ip-address=${FARGATE_IP}
eureka.instance.non-secure-port=8081

This is the error I receive on the Eureka page under the AMIs column even though the services seem to work. Any ideas?

FreeMarker template error (DEBUG mode; use RETHROW in production!): 
The following has evaluated to null or missing: ==> amiCount.key [in template "eureka/status.ftl" at line 35, column 26] 
---- Tip: It's the step after the last dot that caused this error, not those before it.
---- Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- 
---- FTL stack trace ("~" means nesting-related): - Failed at: ${amiCount.key} [in template "eureka/status.ftl" at line 35, column 24] ---- Java stack trace (for programmers): 
---- freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...]
 at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134)
 at freemarker.core.EvalUtil.coerceModelToTextualCommon(EvalUtil.java:467)
 at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:389)
 at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:358)
 at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:100)
 at freemarker.core.DollarVariable.accept(DollarVariable.java:63)
 at freemarker.core.Environment.visit(Environment.java:366)
 at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:317)
 at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271)
 at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:242)
 at freemarker.core.Environment.visitIteratorBlock(Environment.java:642)
 at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:107)
 at freemarker.core.IteratorBlock.accept(IteratorBlock.java:93)
 at freemarker.core.Environment.visit(Environment.java:366)
 at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:317)
 at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271)
 at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:242)
 at freemarker.core.Environment.visitIteratorBlock(Environment.java:642)
 at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:107)
 at freemarker.core.IteratorBlock.accept(IteratorBlock.java:93)
 at freemarker.core.Environment.visit(Environment.java:330)
 at freemarker.core.Environment.visit(Environment.java:336)
 at freemarker.core.Environment.visit(Environment.java:336)
 at freemarker.core.Environment.process(Environment.java:309)
 at freemarker.template.Template.process(Template.java:384)
 at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:389)
 at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:302)
 at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:253)
 at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:178)
 at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316)
 at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1371)
 at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1117)
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1056)
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
 at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
 at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:88)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:114)
 at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:104)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
 at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
 at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
 at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
 at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
 at java.lang.Thread.run(Thread.java:748)

Comment From: spencergibb

I'm not sure why amiCount isn't populated, but it would probably be as simple as providing a default.

Comment From: lucasobsidiam

Is there a simple way of doing that without modifying source code? To temporarily show the connected micro-services properly.

Comment From: spencergibb

Not that I know of. You could copy the template into your local app's src/main/resources/templates/eureka/status.ftlh and it should find that first.

Comment From: fwuen

Is there any elegant solution for this by now? @lucasobsidiam @spencergibb

Comment From: amit-github-personal

+1 facing same issue when deployed service on kubernetes

Comment From: rohitkrishna-marneni

any update on this?

Comment From: spencergibb

no, there isn't