33# (a) it's more convenient to fetch specific info you need, such as an EC2 Instance's private IP and (b) so you can
44# replace these helpers with mocks to do local testing or unit testing.
55
6+ # shellcheck source=./modules/bash-commons/src/assert.sh
7+ source " $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) /assert.sh"
8+ # shellcheck source=./modules/bash-commons/src/log.sh
9+ source " $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) /log.sh"
10+
611# Look up the given path in the EC2 Instance metadata endpoint
712function aws_lookup_path_in_instance_metadata {
813 local -r path=" $1 "
@@ -60,6 +65,144 @@ function aws_get_instance_tags {
6065 --filters " Name=resource-type,Values=instance" " Name=resource-id,Values=$instance_id "
6166}
6267
68+ # Return the value of the $tag_key for the given EC2 Instance $instance_id
69+ function aws_get_instance_tag_val {
70+ local -r tag_key=" $1 "
71+ local -r instance_id=" $2 "
72+ local -r instance_region=" $3 "
73+
74+ local tags
75+ tags=$( aws_get_instance_tags " $instance_id " " $instance_region " )
76+
77+ local tag_val
78+ tag_val=$( echo " $tags " | jq -r " .Tags[] | select( .ResourceType == \" instance\" and .Key == \" $tag_key \" ) | .Value" )
79+
80+ echo " $tag_val "
81+ }
82+
83+ # Return all ENIs attached to the current EC2 Instance
84+ function aws_get_enis_for_instance {
85+ local -r instance_id=" $1 "
86+ local -r aws_region=" $2 "
87+
88+ aws ec2 describe-network-interfaces --region " $aws_region " --filters " Name=attachment.instance-id,Values=$instance_id "
89+ }
90+
91+ # Find all Elastic Network Interfaces (ENIs) that have a matching $tag_key=$tag_value
92+ function aws_get_enis_for_tag {
93+ local -r tag_key=" $1 "
94+ local -r tag_value=" $2 "
95+ local -r aws_region=" $3 "
96+
97+ aws ec2 describe-network-interfaces --region " $aws_region " --filters " Name=tag:$tag_key ,Values=$tag_value "
98+ }
99+
100+ # Given the $network_interfaces_output, return the ID of the ENI at the given $eni_index (zero-based)
101+ #
102+ # Example:
103+ # network_interfaces_output=$(aws_get_enis_for_this_ec2_instance)
104+ # aws_get_eni_id "$network_interfaces_output" 0
105+ function aws_get_eni_id {
106+ local -r network_interfaces_output=" $1 "
107+ local -r eni_device_index=" $2 "
108+
109+ assert_not_empty " network_interfaces_output" " $network_interfaces_output " " Value returned from AWS API describe-network-interfaces output"
110+ assert_not_empty " eni_device_index" " $eni_device_index "
111+
112+ local num_enis
113+ num_enis=$( echo " $network_interfaces_output " | jq -r " .NetworkInterfaces | length" )
114+
115+ if [[ " $num_enis " -lt 1 ]]; then
116+ log_error " Expected to find at least 1 ENI in AWS API describe-network-interfaces output."
117+ exit 1
118+ fi
119+
120+ if [[ " $num_enis " -lt " $eni_device_index " ]]; then
121+ log_error " Requested an ENI device-index out of range from describe-network-interfaces output."
122+ exit 1
123+ fi
124+
125+ local eni_id
126+ eni_id=$( echo " $network_interfaces_output " | jq -r " .NetworkInterfaces[] | select(.Attachment.DeviceIndex == $eni_device_index ).NetworkInterfaceId" )
127+
128+ assert_not_empty_or_null " $eni_id " " No ENI exists whose DeviceIndex property is $eni_device_index . Did you forget to create or attach an additional ENI?"
129+
130+ echo " $eni_id "
131+ }
132+
133+ # Given a $tag_key, return the corresponding tag_val for the ENI at the the given $eni_device_index (zero-based).
134+ #
135+ # Example:
136+ # network_interfaces_output=$(aws_get_enis_for_this_ec2_instance)
137+ # aws_get_eni_tag_val "$network_interfaces_output" 0 "DnsName"
138+ function aws_get_eni_tag_val {
139+ local -r network_interfaces_output=" $1 "
140+ local -r eni_device_index=" $2 "
141+ local -r tag_key=" $3 "
142+
143+ assert_not_empty " tag_key" " $tag_key "
144+
145+ local eni_id
146+ eni_id=" $( aws_get_eni_id " $network_interfaces_output " " $eni_device_index " ) "
147+ log_info " Looking up the value of the tag \" $tag_key \" for ENI $eni_id "
148+
149+ local tag_val
150+ tag_val=$( echo " $network_interfaces_output " | jq -j " .NetworkInterfaces[] | select(.NetworkInterfaceId == \" $eni_id \" ).TagSet[] | select(.Key == \" $tag_key \" ).Value" )
151+
152+ assert_not_empty_or_null_warn " $tag_val " " Found empty value when looking up tag \" $tag_key \" for ENI $eni_id "
153+
154+ echo " $tag_val "
155+ }
156+
157+ # Return the *public* IP Address of for the ENI at the the given $eni_device_index (zero-based).
158+ #
159+ # Example:
160+ # network_interfaces_output=$(aws_get_enis_for_this_ec2_instance)
161+ # aws_get_eni_public_ip "$network_interfaces_output" 0
162+ function aws_get_eni_public_ip {
163+ local -r network_interfaces_output=" $1 "
164+ local -r eni_device_index=" $2 "
165+
166+ local eni_id
167+ eni_id=" $( aws_get_eni_id " $network_interfaces_output " " $eni_device_index " ) "
168+ log_info " Looking up public IP address for ENI $eni_id "
169+
170+ public_ip=$( echo " $network_interfaces_output " | jq -j " .NetworkInterfaces[] | select(.NetworkInterfaceId == \" $eni_id \" ).PrivateIpAddresses[0].Association.PublicIp" )
171+
172+ assert_not_empty_or_null " $public_ip " " No public IP address found for ENI $eni_id ."
173+
174+ echo " $public_ip "
175+ }
176+
177+ # Return the *private* IP Address of for the ENI at the the given $eni_device_index (zero-based).
178+ #
179+ # Example:
180+ # network_interfaces_output=$(aws_get_enis_for_this_ec2_instance)
181+ # aws_get_eni_private_ip "$network_interfaces_output" 0
182+ function aws_get_eni_private_ip {
183+ local -r network_interfaces_output=" $1 "
184+ local -r eni_device_index=" $2 "
185+
186+ local eni_id
187+ eni_id=" $( aws_get_eni_id " $network_interfaces_output " " $eni_device_index " ) "
188+ log_info " Looking up private IP address for ENI $eni_id "
189+
190+ public_ip=$( echo " $network_interfaces_output " | jq -j " .NetworkInterfaces[] | select(.NetworkInterfaceId == \" $eni_id \" ).PrivateIpAddresses[0].PrivateIpAddress" )
191+
192+ echo " $public_ip "
193+ }
194+
195+ # Return the private IP Address of the ENI attached to the given EC2 Instance
196+ function aws_get_eni_private_ip_for_instance {
197+ local -r network_interfaces_output=" $1 "
198+ local -r instance_id=" $2 "
199+
200+ local attached_network_interface
201+ attached_network_interface=$( echo " $network_interfaces_output " | jq -r " .NetworkInterfaces[] | select(.Attachment.InstanceId == \" $instance_id \" )" )
202+
203+ echo " $attached_network_interface " | jq -r ' .PrivateIpAddresses[0].PrivateIpAddress'
204+ }
205+
63206# Get the instances with a given tag and in a specific region. Returns JSON from the AWS CLI's describe-instances command.
64207function aws_get_instances_with_tag {
65208 local -r tag_key=" $1 "
@@ -86,4 +229,4 @@ function aws_describe_instances_in_asg {
86229 local -r aws_region=" $2 "
87230
88231 aws ec2 describe-instances --region " $aws_region " --filters " Name=tag:aws:autoscaling:groupName,Values=$asg_name " " Name=instance-state-name,Values=pending,running"
89- }
232+ }
0 commit comments