Last active
September 7, 2020 04:32
-
-
Save amontalban/cb5744f8fe9e5ba966fece68dd2b16cb to your computer and use it in GitHub Desktop.
Attach an ENI (Elastic Network Interface) to an instance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# This script assigns Elastic Network Interface (ENI) passed as argument to current instance. | |
# The goal of this script is to attach an ENI to a single instance running in an ASG for example. | |
export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin | |
PROG_NAME=$(basename $0) | |
AWSCLI=$(which aws) | |
JQ=$(which jq) | |
CURL=$(which curl) | |
TR=$(which tr) | |
DHCLIENT=$(which dhclient) | |
IFCONFIG=$(which ifconfig) | |
GREP=$(which grep) | |
CUT=$(which cut) | |
AWK=$(which awk) | |
SED=$(which sed) | |
NIC="eth1" | |
ENI_ID=$1 | |
usage() { | |
cat<<EOF | |
NAME | |
${PROG_NAME} -- Assign an Elastic Network Interface to this instance | |
SYNOPSIS | |
${PROG_NAME} eni-id | |
EXIT STATUS | |
The ${PROG_NAME} utility exits 0 on success, and > 0 if an error occurs. | |
EOF | |
exit 0 | |
} | |
parse_cmdline() { | |
if [ $# -eq 0 ]; then | |
usage | |
else | |
while [ $# -gt 0 ]; do | |
case "$1" in | |
-*) | |
usage | |
;; | |
*) | |
break | |
;; | |
esac | |
shift | |
done | |
fi | |
} | |
get_eni_info () { | |
local ENI_ID=$1 | |
${AWSCLI} ec2 describe-network-interfaces --filters Name=network-interface-id,Values=${ENI_ID} | |
} | |
attach_eni () { | |
local ENI_ID=$1 | |
local INSTANCE_ID=$2 | |
${AWSCLI} ec2 attach-network-interface --network-interface-id ${ENI_ID} --instance-id ${INSTANCE_ID} --device-index 1 | |
} | |
dettach_eni () { | |
local ENI_ATTACHMENT_ID=$1 | |
${AWSCLI} ec2 detach-network-interface --attachment-id ${ENI_ATTACHMENT_ID} --force | |
} | |
main() { | |
ENI_INFO=$(get_eni_info ${ENI_ID}) | |
ENI_IP=$(echo ${ENI_INFO} | ${JQ} '.NetworkInterfaces[] .PrivateIpAddresses[] .PrivateIpAddress' | ${SED} 's/"//g') | |
ENI_STATUS=$(echo ${ENI_INFO} | ${JQ} '.NetworkInterfaces[] .Status' | ${TR} '[A-Z]' '[a-z]' | ${SED} 's/"//g') | |
INSTANCE_ID=$(${CURL} -s http://169.254.169.254/latest/meta-data/instance-id ) | |
echo "Configuring ENI ${ENI_ID}" | |
if [ "${ENI_STATUS}" == "available" ]; then | |
echo "ENI ${ENI_ID} is available, attaching it to ${INSTANCE_ID}" | |
while [ "${ENI_STATUS}" == "available" ]; do | |
# Attach ENI to current instance | |
attach_eni ${ENI_ID} ${INSTANCE_ID} | |
ENI_INFO=$(get_eni_info ${ENI_ID}) | |
ENI_STATUS=$(echo ${ENI_INFO} | ${JQ} '.NetworkInterfaces[] .Status' | ${TR} '[A-Z]' '[a-z]' | ${SED} 's/"//g') | |
sleep 1 | |
done | |
echo "ENI ${ENI_ID} attached to ${INSTANCE_ID}" | |
echo "Configuring ${NIC} with IP ${ENI_IP}" | |
# Configure network interface | |
${IFCONFIG} ${NIC} up | |
${DHCLIENT} ${NIC} | |
else | |
ENI_INSTANCE_ID=$(echo ${ENI_INFO} | ${JQ} '.NetworkInterfaces[] .Attachment .InstanceId' | ${SED} 's/"//g') | |
if [ "${INSTANCE_ID}" == "${ENI_INSTANCE_ID}" ]; then | |
# Check if the IP is configured properly | |
NIC_IP=$(${IFCONFIG} ${NIC} | ${GREP} 'inet addr:' | ${CUT} -d: -f2 | ${AWK} '{ print $1}') | |
if ! [ "${NIC_IP}" == "${ENI_IP}" ]; then | |
echo "Configuring NIC ${NIC}..." | |
# Configure network interface | |
${IFCONFIG} ${NIC} up | |
${DHCLIENT} ${NIC} | |
fi | |
else | |
echo "ENI ${ENI_ID} is attached to ${ENI_INSTANCE_ID}, dettaching..." | |
while [ "${ENI_STATUS}" == "in-use" ]; do | |
# Dettach ENI | |
ENI_ATTACHMENT_ID=$(echo ${ENI_INFO} | ${JQ} '.NetworkInterfaces[] .Attachment .AttachmentId' | ${SED} 's/"//g') | |
dettach_eni ${ENI_ATTACHMENT_ID} | |
ENI_INFO=$(get_eni_info ${ENI_ID}) | |
ENI_STATUS=$(echo ${ENI_INFO} | ${JQ} '.NetworkInterfaces[] .Status' | ${TR} '[A-Z]' '[a-z]' | ${SED} 's/"//g') | |
sleep 1 | |
done | |
echo "ENI ${ENI_ID} is available, attaching it to ${INSTANCE_ID}" | |
while [ "${ENI_STATUS}" == "available" ]; do | |
# Attach ENI to current instance | |
attach_eni ${ENI_ID} ${INSTANCE_ID} | |
ENI_INFO=$(get_eni_info ${ENI_ID}) | |
ENI_STATUS=$(echo ${ENI_INFO} | ${JQ} '.NetworkInterfaces[] .Status' | ${TR} '[A-Z]' '[a-z]' | ${SED} 's/"//g') | |
sleep 1 | |
done | |
echo "ENI ${ENI_ID} attached to ${INSTANCE_ID}" | |
echo "Configuring ${NIC} with IP ${ENI_IP}" | |
# Configure network interface | |
${IFCONFIG} ${NIC} up | |
${DHCLIENT} ${NIC} | |
fi | |
fi | |
} | |
parse_cmdline $@ | |
main | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Required IAM policy: