Created
January 14, 2014 06:35
-
-
Save chhibber/8414078 to your computer and use it in GitHub Desktop.
AWS - NAT Bootstrap Example
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
#!/bin/bash - | |
#=============================================================================== | |
# vim: softtabstop=4 shiftwidth=4 expandtab fenc=utf-8 spell spelllang=en | |
#=============================================================================== | |
set -x | |
SALT_BOOTSTRAP_SCRIPT="salt-bootstrap.sh" | |
SALT_BOOTSTRAP_DOWNLOAD="http://bootstrap.saltstack.org" | |
exec 2>&1 > /tmp/awsbootstrap.log | |
# ===== FUNCTION ================================================================ | |
# NAME: log | |
# DESCRIPTION: | |
# =============================================================================== | |
log() { | |
echo `date` : "$@" | |
} | |
# ===== FUNCTION ================================================================ | |
# NAME: jsonvalue | |
# DESCRIPTION: Extracts the key value from json - magic. UGLY | |
# =============================================================================== | |
function jsonvalue { | |
temp=`echo $JSON | \ | |
sed 's/\\\\\//\//g' | \ | |
sed 's/[{}]//g' | \ | |
awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | \ | |
sed 's/\"\:\"/\|/g' | \ | |
sed 's/[\,]/ /g' | \ | |
sed 's/\"//g' | grep -w $PROP | \ | |
awk '{print $2}'` | |
echo ${temp##*|} | |
} | |
# ===== FUNCTION ================================================================ | |
# NAME: __download_salt_bootstrap_script | |
# DESCRIPTION: Retrieves a URL and writes it to a given path | |
# =============================================================================== | |
__download_salt_bootstrap_script() { | |
curl -L --insecure -o ${SALT_BOOTSTRAP_SCRIPT} ${SALT_BOOTSTRAP_DOWNLOAD} >/dev/null 2>&1 || | |
wget --no-check-certificate -O ${SALT_BOOTSTRAP_SCRIPT} ${SALT_BOOTSTRAP_DOWNLOAD} >/dev/null 2>&1 || | |
fetch -q -o ${SALT_BOOTSTRAP_SCRIPT} "$SALT_BOOTSTRAP_DOWNLOAD" >/dev/null 2>&1 | |
} | |
log "#################################################################################################" | |
log "# Starting System Bootstrap #" | |
log "#################################################################################################" | |
# | |
# Setup variables needed for script | |
# | |
export EC2_HOME=/opt/aws/apitools/ec2 | |
export JAVA_HOME=/usr/lib/jvm/jre | |
export INSTANCE_ID=`/opt/aws/bin/ec2-metadata -i | awk '{print $2}'` | |
export PLACEMENT=`/opt/aws/bin/ec2-metadata | grep -w ^placement | awk '{ print $2 }'` | |
export AVAILABILITY_ZONE=`/opt/aws/bin/ec2-metadata -z | awk '{print $2}'` | |
export AWS_DEFAULT_REGION=${AVAILABILITY_ZONE%?} | |
export AWS_DEFAULT_REGION=${AVAILABILITY_ZONE%?} | |
export SERVER_ROLE=`aws ec2 describe-tags --filters "Name=resource-id,Values=${INSTANCE_ID}" --output=text | \ | |
grep -w Role | awk '{print $3}'` | |
export SERVER_ENV=`aws ec2 describe-tags --filters "Name=resource-id,Values=${INSTANCE_ID}" --output=text | \ | |
grep -w Env | awk '{print $3}'` | |
export SALTVERSION=`aws ec2 describe-tags --filters "Name=resource-id,Values=${INSTANCE_ID}" --output=text | \ | |
grep -w Saltversion | awk '{print $3}'` | |
export ETH0_MAC=`/sbin/ifconfig | /bin/grep eth0 | \ | |
awk '{print tolower($5)}' | grep '^[0-9a-f]\{2\}\(:[0-9a-f]\{2\}\)\{5\}$'` | |
export VPC_CIDR_URI="http://169.254.169.254/latest/meta-data/network/interfaces/macs/${ETH0_MAC}/vpc-ipv4-cidr-block" | |
export VPC_CIDR_RANGE=`curl --retry 3 --retry-delay 0 --silent --fail ${VPC_CIDR_URI}` | |
export DFG=`ip route | grep default | awk '{print $3}' | head -n1` | |
# | |
# Disable source destination check on the instance | |
# | |
/usr/bin/aws ec2 modify-instance-attribute --instance-id $INSTANCE_ID --source-dest-check '{ "Value": false }' | |
# | |
# Enable forwarding | |
# | |
/bin/echo 1 > /proc/sys/net/ipv4/ip_forward | |
# | |
# Determine which ENI we need based on region | |
# | |
[[ $AVAILABILITY_ZONE == "us-west-2a" ]] && NATNIC='NATANIC' | |
[[ $AVAILABILITY_ZONE == "us-west-2b" ]] && NATNIC='NATBNIC' | |
[[ $AVAILABILITY_ZONE == "us-west-2c" ]] && NATNIC='NATCNIC' | |
[[ $AVAILABILITY_ZONE == "us-east-1b" ]] && NATNIC='NATANIC' | |
[[ $AVAILABILITY_ZONE == "us-east-1c" ]] && NATNIC='NATBNIC' | |
[[ $AVAILABILITY_ZONE == "us-east-1d" ]] && NATNIC='NATCNIC' | |
# | |
# Determine Network Interface ID | |
# | |
JSON=`/usr/bin/aws ec2 describe-network-interfaces \ | |
--filter Name=availability-zone,Values=$AVAILABILITY_ZONE \ | |
--filter Name=status,Values=available \ | |
--filter Name=tag-value,Values=$NATNIC` | |
PROP="NetworkInterfaceId" | |
ENI_ID=`jsonvalue` | |
echo $ENI_ID | |
# | |
# Disable Source Desintation Check on the Network Interface | |
# | |
/usr/bin/aws ec2 modify-network-interface-attribute --network-interface-id $ENI_ID --source-dest-check '{ "Value": false }' | |
# | |
# Attach the network interface to the instance | |
# | |
/usr/bin/aws ec2 attach-network-interface --network-interface-id $ENI_ID --instance-id $INSTANCE_ID --device-index 1 | |
sleep 5 | |
# | |
# Using ec2 interface tools, scan for a new interface | |
# | |
/sbin/ec2ifscan | |
sleep 5 | |
# | |
# Bring the new interface up | |
# | |
/sbin/ec2ifup eth1 | |
sleep 2 | |
# | |
# Start NATing out the ENI with the static IP address and delete | |
# the original entry | |
# | |
/sbin/iptables -t nat -A POSTROUTING -o eth1 -s ${VPC_CIDR_RANGE} -j MASQUERADE | |
sleep 2 | |
/sbin/iptables -t nat -D POSTROUTING -o eth0 -s ${VPC_CIDR_RANGE} -j MASQUERADE | |
# | |
# Delete the default route that tells traffic to go out ETH0 | |
# The AWS tools put an default entry via eth1 with a higher metric. | |
# e.g. default via 10.204.4.1 dev eth1 metric 10001 | |
# | |
/sbin/ip route del default via ${DFG} dev eth0 | |
/sbin/ip route flush cache | |
log "#################################################################################################" | |
log "# Starting salt bootstrap #" | |
log "#################################################################################################" | |
# | |
# Download Salt bootstrap file | |
# | |
sleep 5 | |
# Removed as we are not using DNS on the instances anymore. Just another thing to manage. | |
# Download Salt Bootstrap File | |
# echo "Downloading Salt Bootstrap file and setting permissions" | |
__download_salt_bootstrap_script | |
chmod 550 ${SALT_BOOTSTRAP_SCRIPT} | |
# | |
# Set the hostname and Name tag. We want to set the hostname before the install and starts | |
# the salt-minion. This way the key name stays consistent on the salt master. | |
# ie. Instead of getting a host named ip_10_20_125_12 we get us-east1-production-www-c123433 | |
# | |
AWS_NAME="${PLACEMENT}-${SERVER_ENV}-${SERVER_ROLE}-${INSTANCE_ID}" | |
hostname $AWS_NAME | |
#/usr/bin/aws ec2 create-tags --resources ${INSTANCE_ID} --tags Key=Name,Value=${AWS_NAME} | |
# | |
# Enable the EPEL repo that is already installed on AMI image | |
# | |
yum-config-manager --enable epel | |
yum -y install git | |
mkdir -p /etc/salt | |
# Install all things salt! | |
/salt-bootstrap.sh -P git v${SALTVERSION} | |
# | |
# | |
# Determine what salt server to point to. Need to make this smarter... | |
# | |
[[ "$SERVER_ENV" != "production" ]] && SALTMASTER="${AWS_DEFAULT_REGION}-development-salt.FOOBAR.com" | |
[[ "$SERVER_ENV" == "production" ]] && SALTMASTER="${AWS_DEFAULT_REGION}-production-salt.FOOBAR.com" | |
#SALTMASTER="${AWS_DEFAULT_REGION}-${SERVER_ENV}-salt.FOOBAR.com" | |
echo "master: ${SALTMASTER}" > /etc/salt/minion | |
echo '' >> /etc/salt/minion | |
echo 'grains:' >> /etc/salt/minion | |
echo ' roles:' >> /etc/salt/minion | |
echo " - ${SERVER_ROLE}" >> /etc/salt/minion | |
echo " environment: ${SERVER_ENV}" >> /etc/salt/minion | |
echo '' >> /etc/salt/minion | |
echo 'log_level: info' >> /etc/salt/minion | |
# | |
# Start the salt-minion | |
# | |
/usr/bin/salt-minion -d -c /etc/salt | |
# Wait for salt to start | |
sleep 5 | |
# | |
# Ensure the salt-minion is connected to salt-master | |
# | |
TIMEOUT=90 | |
COUNT=0 | |
while [ ! -f /etc/salt/pki/minion/minion_master.pub ]; do | |
echo "Waiting for salt to register with master." | |
if [ "$COUNT" -ge "$TIMEOUT" ]; then | |
echo "minion_master.pub not detected by timeout" | |
exit 1 | |
fi | |
sleep 5 | |
COUNT=$((COUNT+5)) | |
done | |
sleep 5 | |
echo "Install base requirements" | |
salt-call state.sls baseRequirements | |
# | |
# Send a notification to hip chat | |
# | |
curl -d \ | |
"room_id=Development+Notifications&from=AWS+Bootstrap&\ | |
message=\ | |
AMI+Info:+${INSTANCE_ID}+\ | |
Environment:+${SERVER_ENV}+\ | |
Role:+${SERVER_ROLE}+\ | |
+::+Calling+salt.highsate\ | |
&color=green"\ | |
https://api.hipchat.com/v1/rooms/message?auth_token=YOURTOKEN&format=json | |
echo "Calling salt.highstate" | |
salt-call state.highstate | |
log "#################################################################################################" | |
log "# Done System Bootstrap #" | |
log "#################################################################################################" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment