#!/bin/bash # chkconfig: 2345 99 10 # description: Auto assigns free EIP # processname: ipassign # Provides: ipassign # Required-Start: # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: # Short-Description: Set Public IP from ElasticIP pool during instance startup # # # Developed by: Javier Sianes - jsianes@gmail.com # OUTPUT="text" REGION="eu-west-1" IPLOGFILE="/var/log/ipassign.log" export PATH=/usr/share/pear:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/bin timestamp() { TIMESTAMP=`date -u +"%Y-%m-%dT%H:%M:%S.000Z"` } usage() { echo "$0 {start|stop|status}" exit 255 } write_log() { timestamp echo "${TIMESTAMP} - ${LOG}" >> ${IPLOGFILE} } valid_ip() { RX='([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])' if [[ ${EC2PUBLICIP} =~ ^${RX}\.${RX}\.${RX}\.${RX}$ ]] then VALIDIP=1 else VALIDIP=0 fi } check_ec2metadata() { ec2-metadata >/dev/null 2>&1 if [ $? -eq 0 ] then # Amazon Linux ec2-metadata command found EC2INSTANCE=`ec2-metadata -i | awk '{ print $NF; }'` EC2PUBLICIP=`ec2-metadata -v | awk '{ print $NF; }'` else # Checking ec2metadata command ec2metadata >/dev/null 2>&1 if [ $? -eq 0 ] then # ec2metadata command found EC2INSTANCE=`ec2metadata --instance-id` EC2PUBLICIP=`ec2metadata --public-ipv4` else # ec2metadata/ec2-metadata command not found LOG="ERROR: No ec2metadata or ec2-metadata command found"; write_log exit 127 fi fi } check_awscli() { aws ec2 describe-addresses >/dev/null 2>&1 if [ $? -ne 0 ] then # Incorrect instance role or invalid AWS CLI configuration LOG="ERROR: AWS CLI command not available. Check instance role or AWS CLI installation/configuration"; write_log exit 128 fi } start() { check_ec2metadata # Check Public IP valid_ip if [ ${VALIDIP} -eq 0 ] then # No Public IP available. So, AWS CLI unavailable LOG="ERROR: There is no Public IP address attached to ${EC2INSTANCE} instance. Unable to use AWS CLI."; write_log exit 3 fi # Check if AWS CLI is available check_awscli # Check if instance has a public IP from Elastic pool assigned PUBLICIPASSIGNED=`aws ec2 describe-addresses --output ${OUTPUT} --region ${REGION} | grep ${EC2INSTANCE} | wc -l` if [ ${PUBLICIPASSIGNED} -gt 0 ] then # Instance has (at least) one Pulic IP associated from Elastic pool IP=`aws ec2 describe-addresses --output ${OUTPUT} --region ${REGION} | grep ${EC2INSTANCE} | head -1 | awk '{ print $NF; }'` LOG="Instance ${EC2INSTANCE} has (at least) one Public IP address from Elastic pool in ${REGION} region (${IP})"; write_log exit 4 else # Get IP address from Elastic pool IP=`aws ec2 describe-addresses --output ${OUTPUT} --region ${REGION} | grep -v 'i-' | head -1 | awk '{ print $NF; }'` if [ "${IP}" = "" ] then # Public IP on Elastic pool unavailable LOG="ERROR: Free Public IP inside Elastic pool in ${REGION} region unavailable"; write_log exit 5 else # Attach Public IP from Elastic pool BOOL=0 aws ec2 associate-address --output ${OUTPUT} --region ${REGION} --instance-id ${EC2INSTANCE} --public-ip ${IP} >/dev/null 2>&1 EXITCODE=$? if [ ${EXITCODE} -eq 0 ] then LOG="${IP} Public IP from Elastic pool assigned to ${EC2INSTANCE} instance"; write_log else LOG="ERROR: (${EXITCODE}) Unable to attach ${IP} Public IP from Elastic pool to ${EC2INSTANCE} instance"; write_log BOOL=1 fi if [ ${BOOL} -eq 0 ] then # Detaching default Public IP aws ec2 disassociate-address --output ${OUTPUT} --region ${REGION} --instance-id ${EC2INSTANCE} --public-ip ${EC2PUBLICIP} >/dev/null 2>&1 EXITCODE=$? if [ ${EXITCODE} -eq 0 ] || [ ${EXITCODE} -eq 255 ] then LOG="Default public IP ${EC2PUBLICIP} outside Elastic pool detached from ${EC2INSTANCE} instance"; write_log else LOG="ERROR: (${EXITCODE}) Unable to detach default public IP ${EC2PUBLICIP} from ${EC2INSTANCE} instance"; write_log BOOL=2 fi fi exit ${BOOL} fi fi } stop() { exit 6 } status () { check_ec2metadata valid_ip if [ ${VALIDIP} -eq 0 ] then echo "No Public IP address attached to ${EC2INSTANCE} instance." exit 1 fi check_awscli IPPRESENTINPOOL=`aws ec2 describe-addresses --output ${OUTPUT} --region ${REGION} | grep "${EC2INSTANCE}" | grep ${EC2PUBLICIP} | wc -l` if [ ${IPPRESENTINPOOL} -eq 1 ] then echo "Public IP ${EC2PUBLICIP} attached to ${EC2INSTANCE} instance in ${REGION} region belongs to ElasticIP pool" exit 0 else echo "Public IP ${EC2PUBLICIP} attached to ${EC2INSTANCE} instance in ${REGION} region is a generic public IP NOT present in ElasticIP pool" exit 2 fi } case "$1" in start) start ;; stop) stop ;; status) status ;; *) usage ;; esac