Skip to content

Instantly share code, notes, and snippets.

@bergerx
Last active November 23, 2017 19:16
Show Gist options
  • Save bergerx/0f1b1fe718ba01d46c5ddc07306a13e1 to your computer and use it in GitHub Desktop.
Save bergerx/0f1b1fe718ba01d46c5ddc07306a13e1 to your computer and use it in GitHub Desktop.
AWS tags as DC/OS agent attributes

We use this service to populate Agent attributes to DC/OS agent nodes during first boot.

This service populates the tags only during first boot and doesn't trigger changes afterwards, since Mesos Agent config change forces the agent to be re-bootstrapped.

#!/bin/bash
# based on https://github.com/goguardian/mesos-aws-tags
set -eu
export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
export EC2_HOME=/opt/ec2-api-tools
export PATH=/usr/local/bin:$EC2_HOME/bin:$PATH
# Export these so the handlers can see them
export ATTRIBUTES_DIR="/etc/mesos-slave/attributes"
export ATTRIBUTES_FILE="/var/lib/dcos/mesos-slave-common"
export HANDLER_DIR=/usr/local/lib/tag_handlers
mkdir -p "${ATTRIBUTES_DIR}"
mkdir -p $(dirname "${ATTRIBUTES_FILE}")
rm -f "${ATTRIBUTES_FILE}"
# Generate individual tags in attributes file
# NOTE: The settings in ${ATTRIBUTES_FILE} supersede any variables that are set
# in /opt/mesosphere/etc/* (see the EnvironmentFile directives in
# /etc/systemd/system/dcos-mesos-slave[-public].service.
#
# In practical terms, this means that we are inadvertently removing the
# public_ip attribute on public agents.
# See http://mesos.apache.org/documentation/latest/attributes-resources
add_attribute()
{
local key=$(echo "${1}" | sed -e 's/[/><|:&:+ ]/_/g')
local clean_value=$(echo "${2}" | sed -e 's/[;:]/_/g')
local prefix=";"
if [ -z "${clean_value}" ]; then
echo "WARN: Not adding mesos attribute for tag ${key} with empty value."
return
fi
if [ ! -f "${ATTRIBUTES_FILE}" ]; then prefix="MESOS_ATTRIBUTES="; fi
echo -n "${prefix}${key}:${clean_value}" >> "${ATTRIBUTES_FILE}"
}
record_tag()
{
local clean_key=$(echo "${1}" | sed -e 's/[/><|:&:+ ]/_/g')
local value="${2}"
echo "Setting ${clean_key} to ${value} in ${ATTRIBUTES_DIR}"
echo -n "${value}" > "${ATTRIBUTES_DIR}/${clean_key}"
}
# Fetch tags
INSTANCE_ID=$(ec2-metadata -i | cut -d ' ' -f2)
MY_REGION=$(ec2-metadata --availability-zone | sed 's/.$//' | awk '{print $2}')
# Wait for a tag that we know will be set.
role=""
while [ -z "${role}" ]; do
echo "Waiting for role tag..."
role=$(ec2-describe-tags \
--region $MY_REGION \
--filter "resource-type=instance" \
--filter "resource-id=${INSTANCE_ID}" \
--filter "key=role" | cut -f 4)
if [ -z "${role}" ]; then sleep 5; fi
done
ec2-describe-tags \
--region $MY_REGION \
--filter "resource-type=instance" \
--filter "resource-id=${INSTANCE_ID}" \
| cut -f4-5 \
| while IFS='' read key_and_value; do
# Split the tag name and value using bash substring removal:
# - remove the first tab and everything after it to get the key
# - remove the first tab and everything before it to get the value
key="${key_and_value%% *}"
value="${key_and_value#* }"
record_tag "${key}" "${value}"
add_attribute "${key}" "${value}"
done
# Cap the attributes file with a newline so handlers can fiddle with it
if [ -s "${ATTRIBUTES_FILE}" ]; then
echo "" >> "${ATTRIBUTES_FILE}"
fi
# Run handlers for any tags that are set
for tag_file in "${ATTRIBUTES_DIR}"/*; do
key=$(basename "${tag_file}")
handler="${HANDLER_DIR}/${key,,}"
if [ -x "${handler}" ]; then
value=$(cat "${tag_file}")
echo "Calling ${handler} with \"${value}\""
"${handler}" "${value}"
fi
done
[Unit]
Description=set up instance tags for Mesos to find
After=cloud-final.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mesos-aws-tags
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment