Skip to content

Instantly share code, notes, and snippets.

@azilber
Forked from jsianes/ipassign
Created September 5, 2021 08:04
Show Gist options
  • Save azilber/f94c02cab19d74c8d94e56d38404dd4d to your computer and use it in GitHub Desktop.
Save azilber/f94c02cab19d74c8d94e56d38404dd4d to your computer and use it in GitHub Desktop.
Script to assign Public IP from Elastic IP pool for instances hosted in AWS. 'ec2-utils' and AWS CLI packages required. Instance role or access keys need to allow at least next EC2 actions: describe-addresses, associate-address and disassociate-address. Shell script is designed to be integrated with instance start-up
#!/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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment