Hi ... had a similar request ...... here is the txt version of the write up .. HTH
GTM Configuration to allow:
1. Monitor a remote site (eg: AWS_FQDN/health.html) via FQDN (not IP Address)
a. If health is good then serve up a CNAME
b. If the health is bad then serve up a IP address from a GTM Pool
The above requirement can be accomplished by assigning an iRule to the GTM WideIP, and calling on an External Monitor to check the availability of the Cloud based service.
The Steps are:
• Create a Server object to reference the AWS Cloud
a. This will be used in the GTM Pool
i. The IP Address is not important as the External Monitor will do a dynamic lookup
• Create an External Monitor to check the availability of the Cloud service
a. The Health monitor will control the GTM Pool status
(based on using CURL -s
https://aws.amazon.com)
• Assign an CNAME iRule to a GTM Wide-IP with pool members
1) AWS Cloud Pool and
2) ‘GTM owned’ virtual server pool
== Step 1: ==
Create the AWS ‘Generic Server Object’, which will be used in the GTM Pool ‘gtmpool_AWS’
== Step 2:==
Create an External Monitor to check the availability of the Cloud service
• The “Arguments” form the basis of the $3 variables within the monitor script
• The RESPONSE_CHECK is used to verify the successful connection to the site in $3
• The DEBUG variable is used to enable/disable logging to /var/log/ltm
o Set to 1 initially to see if check it successful
o Manually run CURL command without the ‘grep’ to see what the site returns
Part of Step 2 is to create an External health monitor.
A good reference on EAV is on DevCentral: https://devcentral.f5.com/Tutorials...itors.aspx
The External monitor we will use, makes use of CURL to a 443 site.
We will look for the tag, which shows the DNS lookup and the connection was successful<br />
• curl -s <a href="https://${MY_FQDN">https://${MY_FQDN</a>} | grep "<title>" 2>&1 > /dev/null</p>
<p><br />
External GTM Monitor file : cloud_dns_monitor<br />
---------------------------------------------</p>
<p>!/bin/bash</p>
<p> These arguments are normally supplied automatically based on the<br />
pool members that the EAV is assigned to<br />
$1 = IP (::ffff:nnn.nnn.nnn.nnn notation or hostname)<br />
$2 = port (decimal, host byte order)<br />
<br />
Our EAV will not really use $1 or $2, as it is based off CURL<br />
dynamically resolving the host, and looking at the response.</p>
<p> Log debug to /var/log/ltm<br />
Check if a variable named DEBUG exists from the monitor definition<br />
DEBUG=0 or 1 must be set in the EAV GUI<br />
RESPONSE_CHECK must be set in the EAV GUI</p>
<p><br />
if [ -n "$DEBUG" ]<br />
then<br />
if [ $DEBUG -eq 1 ]; then echo "EAV `basename $0`: \$DEBUG: $DEBUG" | logger -p local0.debug; fi<br />
fi</p>
<p> Remove IPv6/IPv4 compatibility prefix (LTM passes addresses in IPv6 format)<br />
We are not actually using it in this monitor<br />
IP=`echo $1 | sed 's/::ffff://'`</p>
<p> Save the port for use in the shell command<br />
We are not actually using it in this monitor<br />
PORT=$2</p>
<p> Save the FQDN of the server for use in the shell command<br />
$3 is supplied in the GUI of the EAV<br />
MY_FQDN=$3</p>
<p> Check if there is a prior instance of the monitor running<br />
pidfile="/var/run/`basename $0`.$IP.$PORT.pid"<br />
if [ -f $pidfile ]<br />
then<br />
kill -9 `cat $pidfile` > /dev/null 2>&1<br />
echo "EAV `basename $0`: exceeded monitor interval, needed to kill ${MY_FQDN} with PID `cat $pidfile`" | logger -p local0.error</p>
<p>fi</p>
<p> Add the current PID to the pidfile<br />
echo "$$" > $pidfile</p>
<p> Debug<br />
if [ $DEBUG -eq 1 ]<br />
then<br />
Customize the log statement here if you want to log the command run or the output<br />
echo "EAV `basename $0`: Running for ${MY_FQDN} using CURL to <a href="https://${MY_FQDN">https://${MY_FQDN</a>}" | logger -p local0.debug</p>
<p>fi</p>
<p><br />
Customize the shell command to run here. <br />
Use $IP and $PORT to specify which host/port to perform the check against<br />
Modify the netcat example portion of the line:<br />
curl -s –I <a href="http://${MY_FQDN">http://${MY_FQDN</a>} | grep 200<br />
And leave this portion as is:<br />
'2>&1 > /dev/null'<br />
The above code redirects stderr and stdout to nothing to ensure we<br />
don't errantly mark the pool member up</p>
<p> Send the request and check the response<br />
eg: curl -s -I <a href="http://${MY_FQDN">http://${MY_FQDN</a>} | grep 200 2>&1 > /dev/null<br />
We will look for the <title> tag, which shows the DNS lookup and the<br />
connection was successful<br />
RESPONSE_CHECK must be set in the EAV GUI<br />
curl -s <a href="http://${MY_FQDN">http://${MY_FQDN</a>} | grep "<title>Amazon Web Services" 2>&1 > /dev/null
curl -s } | grep “${RESPONSE_CHECK}” 2>&1 > /dev/null
Check if the command ran successfully
Note that any standard output will result in the script execution being stopped
So do any cleanup before echoing to STDOUT
if [ $? -eq 0 ]
then
rm -f $pidfile
if [ $DEBUG -eq 1 ]; then echo "EAV `basename $0`: Succeeded for ${MY_FQDN}" | logger -p local0.debug; fi
echo "UP"
else
rm -f $pidfile
if [ $DEBUG -eq 1 ]; then echo "EAV `basename $0`: Failed for ${MY_FQDN}" | logger -p local0.debug; fi
fi
----end-----
== Step 3 ==
Create an GTM Wide-IP
- The pool members will be (1) the AWS Cloud Pool and (2) the ‘GTM owned’ virtual servers
Attach the iRule to the WideIP , that returns
- the CNAME, or
- the IP address of the GTM pool member in ‘gtmpool_CBA’
iRule: AWS-CNAME-return
-----------------------
when DNS_REQUEST {
GTM External Monitor will determine the health of gtmpool_AWS
based on DNS lookup, and HTTP GET
if { [ active_members gtmpool_AWS] > 0 } {
log local0. "Positive External check to aws.amazon.com using CURL,
puts 'gtmpool_AWS' as Active -- therefore Returning cname aws.amazon.com"
cname aws.amazon.com
} else {
GTM monitor will determine the health of internal
internal pool gtmpool_CBA based on known IP, and HTTP GET
if { [ active_members gtmpool_ACME] > 0 } {
log local0. "External health check to aws.amazon.com failed -- BUT
there are active pool members in 'gtmpool_ACME' -- therefore
Responding with local address from 'gtmpool_ACME'"
pool gtmpool_ACME
}
}
}
--end ---
Details of the iRule components can be found at : https://devcentral.f5.com/wiki/iRules.GTM.ashx
• active_members : Returns the number or list of active members in the specified pool.
• cname : Causes the specified name to be sent as a CNAME response.
• pool : Causes the system to load balance traffic to the specified pool or pool member regardless of monitor status.