This is a collected patch of following commits:
78d8ac1f47fee5dec37aae52f567413aa2a27ac7 Add missing quotes in ec2ip_stop()
bd28c531265a201ac5fc1da0fe3f4f6a96a5f354 Change in function names from ec2ip_* to r53_*
907e8af6451e2ebb37964049864f1e52cf17e213 Add binary check for curl and dig
d6f86c48045b53b0734de8659b29f6a6eaf40dda Changes and improvements to r53_monitor function
5b4ff04904bd99fa83f9c974b1debf0219b2a8a5 Changes and improvements to Changes and improvements to _update_record function
eb866026d6ab3274b31575d93a9c37f22c17c929 Changes and improvements to r53_stop function
eef59a17da0a7a14d1dac20ef808017d4b0785d7 Changes and improvements to r53_start function
5ec47cd6a92769cbeddf73f66240d4044d3cd389 Replace ec2metada with curl to fetch the IP address directly from EC2 metadata
37868e812b497cf4158d2f062c52373e6974de6d Add extra log line to r53_start function
96768ea4c8f1dcf6179e7494a0b0d3e152d331f5 Add --cli-connect-timeout 10 option to AWS CLI
b281c1940f3fc25ffae93d7ec4ee17101be43518 Changed log line wording on r53_stop function
482b37a33c555dd1903fad3bbc9bbf5b00764d35 Normalize variable declaration
ab4a9bebee90beb9a3724d2aa111c2d6b32babf5 Remove unecessary tabs
f62f7f9d94ec0f60bab20959859ec66352cec8ed Change check interval in _update record function
799669afd098457c72639471c00bfa01dbfa1923 Tuning on dig timeout on r53_monitor function
25cd5b1c9f6b4cbc3a471e83ebe88366c14212c8 Removed absolute path for awk command
The separated commits can not be applied because this file did not exist at SLE12-SP3 and was introduced by other name by the patch
0008-High-aws-vpc-route53-Add-agent-for-AWS-Route-53-fate.patch

--- a/heartbeat/aws-vpc-route53	2017-06-28 18:01:13.000000000 +0200
+++ b/heartbeat/aws-vpc-route53	2019-07-15 12:30:25.083529796 +0200
@@ -142,19 +142,25 @@
 </parameter>
 </parameters>
 <actions>
-<action name="start" timeout="180" />
-<action name="stop" timeout="180" />
-<action name="monitor" depth="0" timeout="180" interval="300" />
-<action name="validate-all" timeout="5" />
-<action name="meta-data" timeout="5" />
+<action name="start" timeout="180s" />
+<action name="stop" timeout="180s" />
+<action name="monitor" depth="0" timeout="180s" interval="300s" />
+<action name="validate-all" timeout="5s" />
+<action name="meta-data" timeout="5s" />
 </actions>
 </resource-agent>
 END
 }
 
-ec2ip_validate() {
+r53_validate() {
 	ocf_log debug "function: validate"
 
+	# Check for required binaries
+	ocf_log debug "Checking for required binaries"
+	for command in curl dig; do
+		check_binary "$command"
+	done
+
 	# Full name
 	[[ -z "$OCF_RESKEY_fullname" ]] && ocf_log error "Full name parameter not set $OCF_RESKEY_fullname!" && exit $OCF_ERR_CONFIGURED
 
@@ -175,32 +181,91 @@
 	ocf_log debug "ok"
 
 	if [ -n "$OCF_RESKEY_profile" ]; then
-		AWS_PROFILE_OPT="--profile $OCF_RESKEY_profile"
+		AWS_PROFILE_OPT="--profile $OCF_RESKEY_profile --cli-connect-timeout 10"
 	else
-		AWS_PROFILE_OPT="--profile default"
+		AWS_PROFILE_OPT="--profile default --cli-connect-timeout 10"
 	fi
 
 	return $OCF_SUCCESS
 }
 
-ec2ip_monitor() {
-	ec2ip_validate
+r53_monitor() {
+	#
+	# For every start action the agent  will call Route53 API to check for DNS record
+	# otherwise it will try to get results directly bu querying the DNS using "dig".
+	# Due to complexity in some DNS architectures "dig" can fail, and if this happens
+	# the monitor will fallback to the Route53 API call.
+	#
+	# There will be no failure, failover or restart of the agent if the monitor operation fails
+	# hence we only return $OCF_SUCESS in this function
+	#
+	# In case of the monitor operation detects a wrong or non-existent Route53 DNS entry
+	# it will try to fix the existing one, or create it again
+	#
+	#
+	ARECORD=""
+	IPREGEX="^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"
+	r53_validate
 	ocf_log debug "Checking Route53 record sets"
-	IPADDRESS="$(ec2metadata aws ip | grep local-ipv4 | /usr/bin/awk '{ print $2 }')"
-	ARECORD="$(aws $AWS_PROFILE_OPT route53 list-resource-record-sets --hosted-zone-id $OCF_RESKEY_hostedzoneid --query "ResourceRecordSets[?Name=='$OCF_RESKEY_fullname']" | grep RESOURCERECORDS | /usr/bin/awk '{ print $2 }' )"
-	ocf_log debug "Found IP address: $ARECORD ."
-	if [ "${ARECORD}" == "${IPADDRESS}" ]; then
-		ocf_log debug "ARECORD $ARECORD found"
+	#
+	IPADDRESS="$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)"
+	#
+	if [ "$__OCF_ACTION" = "start" ] || ocf_is_probe ; then
+		#
+		cmd="aws $AWS_PROFILE_OPT route53 list-resource-record-sets --hosted-zone-id $OCF_RESKEY_hostedzoneid --query ResourceRecordSets[?Name=='$OCF_RESKEY_fullname']"
+		ocf_log debug "Route53 Agent Starting or probing - executing monitoring API call: $cmd"
+		ARECORD="$($cmd | grep RESOURCERECORDS | awk '{ print $2 }')"
+	else
+		#
+		cmd="dig +retries=3 +time=5 +short $OCF_RESKEY_fullname 2>/dev/null"
+		ocf_log debug "executing monitoring command : $cmd"
+		ARECORD="$($cmd)"
+		rc=$?
+		ocf_log debug "dig return code: $rc"
+		#
+		if  [[ ! $ARECORD =~ $IPREGEX ]] || [ $rc -ne 0 ]; then
+			ocf_log info "Fallback to Route53 API query due to DNS resolution failure"
+			cmd="aws $AWS_PROFILE_OPT route53 list-resource-record-sets --hosted-zone-id $OCF_RESKEY_hostedzoneid --query ResourceRecordSets[?Name=='$OCF_RESKEY_fullname']"
+			ocf_log debug "executing monitoring API call: $cmd"
+			CLIRES="$($cmd 2>&1)"
+			rc=$?
+			ocf_log debug "awscli return code: $rc"
+			if [ $rc -ne 0 ]; then
+				ocf_log info "Route53 API returned an error: $CLIRES"
+				ocf_log info "Monitor skipping cluster action due to API call error"
+				return $OCF_SUCCESS
+			fi
+			ARECORD=$(echo $CLIRES | grep RESOURCERECORDS | awk '{ print $5 }')
+		fi
+		#
+	fi
+	ocf_log debug "Route53 DNS record pointing $OCF_RESKEY_fullname to IP address $ARECORD"
+	#
+	if [ "$ARECORD" == "$IPADDRESS" ]; then
+		ocf_log debug "Route53 DNS record $ARECORD found"
+		return $OCF_SUCCESS
+	elif [[ $ARECORD =~ $IPREGEX ]] && [ "$ARECORD" != "$IPADDRESS" ]; then
+		ocf_log info "Route53 DNS record points to a different host, setting DNS record on Route53 to this host"
+		_update_record "UPSERT" "$IPADDRESS"
 		return $OCF_SUCCESS
 	else
-		ocf_log debug "No ARECORD found"
-		return $OCF_NOT_RUNNING
+		ocf_log info "No Route53 DNS record found, setting DNS record on Route53 to this host"
+		_update_record "UPSERT" "$IPADDRESS"
+		return $OCF_SUCCESS
 	fi
 
 	return $OCF_SUCCESS
 }
 
 _update_record() {
+	#
+	# This function is the one that will actually execute Route53's API call
+	# and configure the DNS record using the correct API calls and parameters
+	#
+	# It creates a temporary JSON file under /tmp with the required API payload
+	#
+	# Failures in this function are critical and will cause the agent to fail
+	#
 	update_action="$1"
 	IPADDRESS="$2"
 	ocf_log info "Updating Route53 $OCF_RESKEY_hostedzoneid with $IPADDRESS for $OCF_RESKEY_fullname"
@@ -209,19 +274,19 @@
 		ocf_exit_reason "Failed to create temporary file for record update"
 		exit $OCF_ERR_GENERIC
 	fi
-	cat >>"${ROUTE53RECORD}" <<-EOF
+	cat >>"$ROUTE53RECORD" <<-EOF
 	{
 		  "Comment": "Update record to reflect new IP address for a system ",
 		  "Changes": [
 			  {
-				  "Action": "${update_action}",
+				  "Action": "$update_action",
 				  "ResourceRecordSet": {
-					  "Name": "${OCF_RESKEY_fullname}",
+					  "Name": "$OCF_RESKEY_fullname",
 					  "Type": "A",
-					  "TTL": ${OCF_RESKEY_ttl},
+					  "TTL": $OCF_RESKEY_ttl,
 					  "ResourceRecords": [
 						  {
-							  "Value": "${IPADDRESS}"
+							  "Value": "$IPADDRESS"
 						  }
 					  ]
 				  }
@@ -229,45 +294,39 @@
 		  ]
 	}
 	EOF
-	cmd="aws --profile ${OCF_RESKEY_profile} route53 change-resource-record-sets --hosted-zone-id ${OCF_RESKEY_hostedzoneid} \
-	  --change-batch file://${ROUTE53RECORD} "
+	cmd="aws --profile $OCF_RESKEY_profile route53 change-resource-record-sets --hosted-zone-id $OCF_RESKEY_hostedzoneid --change-batch file://$ROUTE53RECORD "
 	ocf_log debug "Executing command: $cmd"
-	CHANGEID=$($cmd | grep CHANGEINFO |	 /usr/bin/awk -F'\t' '{ print $3 }' )
-	ocf_log debug "Change id: ${CHANGEID}"
-	rmtempfile ${ROUTE53RECORD}
-	CHANGEID=$(echo $CHANGEID |cut -d'/' -f 3 |cut -d'"' -f 1 )
-	ocf_log debug "Change id: ${CHANGEID}"
+	CHANGEID=$($cmd | grep CHANGEINFO | awk -F'\t' '{ print $3 }' )
+	ocf_log debug "Change id: $CHANGEID"
+	rmtempfile $ROUTE53RECORD
+	CHANGEID=$(echo $CHANGEID | cut -d'/' -f 3 | cut -d'"' -f 1 )
+	ocf_log debug "Change id: $CHANGEID"
 	STATUS="PENDING"
-	MYSECONDS=2
+	MYSECONDS=8
 	while [ "$STATUS" = 'PENDING' ]; do
-		sleep	${MYSECONDS}
-		STATUS="$(aws --profile ${OCF_RESKEY_profile} route53 get-change --id $CHANGEID | grep CHANGEINFO |  /usr/bin/awk -F'\t' '{ print $4 }' |cut -d'"' -f 2 )"
-		ocf_log debug "Waited for ${MYSECONDS} seconds and checked execution of Route 53 update status: ${STATUS} "
+		sleep $MYSECONDS
+		STATUS="$(aws --profile $OCF_RESKEY_profile route53 get-change --id $CHANGEID | grep CHANGEINFO | awk -F'\t' '{ print $4 }' |cut -d'"' -f 2 )"
+		ocf_log debug "Waited for $MYSECONDS seconds and checked execution of Route 53 update status: $STATUS "
 	done
 }
 
-ec2ip_stop() {
-	ocf_log info "Bringing down Route53 agent. (Will remove ARECORD)"
-	IPADDRESS="$(ec2metadata aws ip | grep local-ipv4 | /usr/bin/awk '{ print $2 }')"
-	ARECORD="$(aws $AWS_PROFILE_OPT route53 list-resource-record-sets --hosted-zone-id $OCF_RESKEY_hostedzoneid --query "ResourceRecordSets[?Name=='$OCF_RESKEY_fullname']" | grep RESOURCERECORDS | /usr/bin/awk '{ print $2 }' )"
-	ocf_log debug "Found IP address: $ARECORD ."
-	if [ ${ARECORD} != ${IPADDRESS} ]; then
-		ocf_log debug "No ARECORD found"
-		return $OCF_SUCCESS
-	else
-		# determine IP address
-		IPADDRESS="$(ec2metadata aws ip | grep local-ipv4 | /usr/bin/awk '{ print $2 }')"
-		# Patch file
-		ocf_log debug "Deleting IP address to ${IPADDRESS}"
-		return $OCF_SUCCESS
-	fi
-
-	_update_record "DELETE" "$IPADDRESS"
+r53_stop() {
+	#
+	# Stop operation doesn't perform any API call or try to remove the DNS record
+	# this mostly because this is not necessarily mandatory or desired
+	# the start and monitor functions will take care of changing the DNS record
+	# if the agent starts in a different cluster node
+	#
+	ocf_log info "Bringing down Route53 agent. (Will NOT remove Route53 DNS record)"
 	return $OCF_SUCCESS
 }
 
-ec2ip_start() {
-	IPADDRESS="$(ec2metadata aws ip | grep local-ipv4 | /usr/bin/awk '{ print $2 }')"
+r53_start() {
+	#
+	# Start agent and config DNS in Route53
+	#
+	ocf_log info "Starting Route53 DNS update...."
+	IPADDRESS="$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)"
 	_update_record "UPSERT" "$IPADDRESS"
 	return $OCF_SUCCESS
 }
@@ -284,16 +343,16 @@
 		exit $OCF_SUCCESS
 		;;
 	monitor)
-		ec2ip_monitor
+		r53_monitor
 		;;
 	stop)
-		ec2ip_stop
+		r53_stop
 		;;
 	validate-all)
-		ec2ip_validate
+		r53_validate
 		;;
 	start)
-		ec2ip_start
+		r53_start
 		;;
 	*)
 		usage
