#!/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 start-up 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 # No ec2metadata command 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 no valid AWS CLI configuration found LOG="ERROR: AWS CLI commands not available. Check AWS CLI installation or configuration"; write_log exit 128 fi } start() { # EC2 metadata: public IP and Instance ID check_ec2metadata # Checking if any Public IP is assigned valid_ip if [ ${VALIDIP} -eq 0 ] then # No Public IP available. Can't execute AWS CLI command LOG="ERROR: There is no Public IP address assigned. Can't run AWS CLI commands"; write_log exit 3 fi # Check if AWS CLI commands are available check_awscli # Checking 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 a 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 # No unassigned Public IP on pool LOG="ERROR: No free Public IP from Elastic pool in ${REGION} region available"; 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 pool assigned to ${EC2INSTANCE} instance"; write_log else LOG="ERROR: (${EXITCODE}) Unable to associate ${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} not from pool disassociated in ${EC2INSTANCE} instance"; write_log else LOG="ERROR: (${EXITCODE}) Unable to disassociate default public IP ${EC2PUBLICIP} in ${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 assigned 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} assigned to ${EC2INSTANCE} instance is part of the ElasticIP pool" exit 0 else echo "Public IP ${EC2PUBLICIP} assigned to ${EC2INSTANCE} instance is a generic public IP NOT present in ElasticIP pool" exit 2 fi } case "$1" in start) start ;; stop) stop ;; status) status ;; *) usage ;; esac