@@ -20,36 +20,65 @@ readonly three_hours_in_s=10800
2020# a token from IMDSv2
2121readonly six_hours_in_s=21600
2222
23- # Detect if the instance is using IMDSv2 or if it is using IMDSv1 still.
23+ # shellcheck source=./modules/bash-commons/src/assert.sh
24+ source " $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) /assert.sh"
25+ # shellcheck source=./modules/bash-commons/src/log.sh
26+ source " $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) /log.sh"
27+
28+ # Set variable to an empty string if it is unbound to prevent "unbound variable".
29+ export GRUNTWORK_BASH_COMMONS_IMDS_VERSION=${GRUNTWORK_BASH_COMMONS_IMDS_VERSION-}
30+ # Set default variable to version "2" if nothing is set.
31+ export default_instance_metadata_version=${default_instance_metadata_version-" 2" }
32+
33+ # Detect if the instance has IMDS available and return what version is available.
2434# Users can always specify the version of the Instance Metadata Service they want bash-commons
25- # to consult by setting the environment variable GRUNTWORK_BASH_COMMONS_IMDS_VERSION
26- # Defaults to IMDSv2 since that is now enabled by default on instances (IMDS only has two options,
27- # "optional" = both v1 and v2, or "required" = v2 only). All new instances support v2 now.
28- if [[ -n " ${GRUNTWORK_BASH_COMMONS_IMDS_VERSION} " ]]; then
29- 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 $? )
30- if [ ${to_token_or_not_to_token} -eq 0 ]; then
35+ # to consult by setting the environment variable GRUNTWORK_BASH_COMMONS_IMDS_VERSION.
36+ # If set, GRUNTWORK_BASH_COMMONS_IMDS_VERSION will override default_instance_metadata_version.
37+ # Defaults to IMDSv2 since that is now available by default on instances.
38+ function aws_check_metadata_availability {
39+ version_to_check=${GRUNTWORK_BASH_COMMONS_IMDS_VERSION:- $default_instance_metadata_version }
40+ if [[ " ${version_to_check} " == " " ]]; then
41+ echo " No IMDS version specified, unable to check metadata availability."
42+ return 9
43+ fi
44+
45+ if [[ " ${version_to_check} " == " 2" ]]; then
46+ curl_exit_code=$( sudo curl -s -o /dev/null -X PUT ${imdsv2_token_endpoint} -H " X-aws-ec2-metadata-token-ttl-seconds: 10" ; echo $? )
47+ if [ ${curl_exit_code} -eq 0 ]; then
3148 default_instance_metadata_version=" 2"
32- elif [ ${to_token_or_not_to_token } -eq 7 ]; then
49+ elif [ ${curl_exit_code } -eq 7 ]; then
3350 echo " Check for IMDSv2 failed. IMDS endpoint connection refused."
3451 default_instance_metadata_version=" 0"
3552 else
36- finish_code=$( sudo curl -s -o /dev/null $metadata_endpoint ; echo $? )
37- if [ ${finish_code} -eq 0 ]; then
38- default_instance_metadata_version=" 1"
39- elif [ ${finish_code} -eq 7 ]; then
40- echo " Check for IMDSv1 and v2 failed. IMDS endpoint connection refused."
41- default_instance_metadata_version=" 0"
42- else
43- echo " IMDS endpoint connection failed for an unknown reason with error code: ${finish_code} "
44- default_instance_metadata_version=" 0"
45- fi
53+ echo " IMDS endpoint connection failed for an unknown reason with error code: ${finish_code} "
54+ default_instance_metadata_version=" 0"
4655 fi
47- fi
56+ fi
4857
49- # shellcheck source=./modules/bash-commons/src/assert.sh
50- source " $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) /assert.sh"
51- # shellcheck source=./modules/bash-commons/src/log.sh
52- source " $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) /log.sh"
58+ if [[ " ${version_to_check} " == " 1" ]]; then
59+ curl_exit_code=$( sudo curl -s -o /dev/null $metadata_endpoint ; echo $? )
60+ if [ ${curl_exit_code} -eq 0 ]; then
61+ default_instance_metadata_version=" 1"
62+ elif [ ${curl_exit_code} -eq 7 ]; then
63+ echo " Check for IMDSv1 and v2 failed. IMDS endpoint connection refused."
64+ default_instance_metadata_version=" 0"
65+ else
66+ echo " IMDS endpoint connection failed for an unknown reason with error code: ${finish_code} "
67+ default_instance_metadata_version=" 0"
68+ fi
69+ fi
70+
71+ # 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)
72+ echo $default_instance_metadata_version
73+ }
74+
75+ # Check if IMDS Metadata Endpoint is available. This is required for most of the functions in this script.
76+ imds_available=$( aws_check_metadata_availability)
77+ if [[ " ${imds_available} " == 9 ]]; then
78+ 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."
79+ elif [[ " ${imds_available} " == 0 ]]; then
80+ echo " IMDS Metadata Endpoint is not available. Script cannot continue without the Endpoint."
81+ fi
5382
5483# AWS and Gruntwork recommend use of the Instance Metadata Service version 2 whenever possible. Although
5584# IMDSv1 is still supported and considered fully secure by AWS, IMDSv2 features special hardening against
0 commit comments