Skip to content

Commit

Permalink
Bug/fix-if-statement-67 (#68)
Browse files Browse the repository at this point in the history
* fixing unbound variable

Using -z in an if statement causes an unbound variable error if set -eu is declared but the variable has not been declared.  Changing thing to -n which checks if the variable is declared and/or undefined.
undefined is an empty string like bob=""
undeclared is if it has never been declared at all

* Check for IMDS Endpoint

This checks of the IMDS Endpoint is available.  If not if fails.

* Add error message when IMDS Endpoint is unavailable

Add an error message if the IMDS Metadata Endpoint is not available.
  • Loading branch information
justin-octo authored Jun 28, 2024
1 parent 3fc19af commit eed9799
Showing 1 changed file with 52 additions and 23 deletions.
75 changes: 52 additions & 23 deletions modules/bash-commons/src/aws.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,65 @@ readonly three_hours_in_s=10800
# a token from IMDSv2
readonly six_hours_in_s=21600

# Detect if the instance is using IMDSv2 or if it is using IMDSv1 still.
# shellcheck source=./modules/bash-commons/src/assert.sh
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/assert.sh"
# shellcheck source=./modules/bash-commons/src/log.sh
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/log.sh"

# Set variable to an empty string if it is unbound to prevent "unbound variable".
export GRUNTWORK_BASH_COMMONS_IMDS_VERSION=${GRUNTWORK_BASH_COMMONS_IMDS_VERSION-}
# Set default variable to version "2" if nothing is set.
export default_instance_metadata_version=${default_instance_metadata_version-"2"}

# Detect if the instance has IMDS available and return what version is available.
# Users can always specify the version of the Instance Metadata Service they want bash-commons
# to consult by setting the environment variable GRUNTWORK_BASH_COMMONS_IMDS_VERSION
# Defaults to IMDSv2 since that is now enabled by default on instances (IMDS only has two options,
# "optional" = both v1 and v2, or "required" = v2 only). All new instances support v2 now.
if [[ -n "${GRUNTWORK_BASH_COMMONS_IMDS_VERSION}" ]]; then
to_token_or_not_to_token=$(sudo curl -s -o /dev/null -X PUT ${imdsv2_token_endpoint} -H "X-aws-ec2-metadata-token-ttl-seconds: 10"; echo $?)
if [ ${to_token_or_not_to_token} -eq 0 ]; then
# to consult by setting the environment variable GRUNTWORK_BASH_COMMONS_IMDS_VERSION.
# If set, GRUNTWORK_BASH_COMMONS_IMDS_VERSION will override default_instance_metadata_version.
# Defaults to IMDSv2 since that is now available by default on instances.
function aws_check_metadata_availability {
version_to_check=${GRUNTWORK_BASH_COMMONS_IMDS_VERSION:-$default_instance_metadata_version}
if [[ "${version_to_check}" == "" ]]; then
echo "No IMDS version specified, unable to check metadata availability."
return 9
fi

if [[ "${version_to_check}" == "2" ]]; then
curl_exit_code=$(sudo curl -s -o /dev/null -X PUT ${imdsv2_token_endpoint} -H "X-aws-ec2-metadata-token-ttl-seconds: 10"; echo $?)
if [ ${curl_exit_code} -eq 0 ]; then
default_instance_metadata_version="2"
elif [ ${to_token_or_not_to_token} -eq 7 ]; then
elif [ ${curl_exit_code} -eq 7 ]; then
echo "Check for IMDSv2 failed. IMDS endpoint connection refused."
default_instance_metadata_version="0"
else
finish_code=$(sudo curl -s -o /dev/null $metadata_endpoint; echo $?)
if [ ${finish_code} -eq 0 ]; then
default_instance_metadata_version="1"
elif [ ${finish_code} -eq 7 ]; then
echo "Check for IMDSv1 and v2 failed. IMDS endpoint connection refused."
default_instance_metadata_version="0"
else
echo "IMDS endpoint connection failed for an unknown reason with error code: ${finish_code}"
default_instance_metadata_version="0"
fi
echo "IMDS endpoint connection failed for an unknown reason with error code: ${finish_code}"
default_instance_metadata_version="0"
fi
fi
fi

# shellcheck source=./modules/bash-commons/src/assert.sh
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/assert.sh"
# shellcheck source=./modules/bash-commons/src/log.sh
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/log.sh"
if [[ "${version_to_check}" == "1" ]]; then
curl_exit_code=$(sudo curl -s -o /dev/null $metadata_endpoint; echo $?)
if [ ${curl_exit_code} -eq 0 ]; then
default_instance_metadata_version="1"
elif [ ${curl_exit_code} -eq 7 ]; then
echo "Check for IMDSv1 and v2 failed. IMDS endpoint connection refused."
default_instance_metadata_version="0"
else
echo "IMDS endpoint connection failed for an unknown reason with error code: ${finish_code}"
default_instance_metadata_version="0"
fi
fi

# returns "2" if IMDSv2 is available, "1" if v2 is not but v1 is, returns "0" if neither are available (i.e. endpoint is disabled or blocked)
echo $default_instance_metadata_version
}

# Check if IMDS Metadata Endpoint is available. This is required for most of the functions in this script.
imds_available=$(aws_check_metadata_availability)
if [[ "${imds_available}" == 9 ]]; then
echo "No IMDS Version declared. This should not be possible because this script sets a default of 2. Check to see if it was unset somewhere."
elif [[ "${imds_available}" == 0 ]]; then
echo "IMDS Metadata Endpoint is not available. Script cannot continue without the Endpoint."
fi

# AWS and Gruntwork recommend use of the Instance Metadata Service version 2 whenever possible. Although
# IMDSv1 is still supported and considered fully secure by AWS, IMDSv2 features special hardening against
Expand Down

0 comments on commit eed9799

Please sign in to comment.