@@ -146,18 +146,20 @@ def ec2_metadata_credentials_json
146
146
require_relative "request"
147
147
require_relative "request/connection_pools"
148
148
require "json"
149
-
150
- iam_info = ec2_metadata_request ( EC2_IAM_INFO )
149
+ token = ec2_metadata_token
150
+ iam_info = ec2_metadata_request ( EC2_IAM_INFO , token )
151
151
# Expected format: arn:aws:iam::<id>:instance-profile/<role_name>
152
152
role_name = iam_info [ "InstanceProfileArn" ] . split ( "/" ) . last
153
- ec2_metadata_request ( EC2_IAM_SECURITY_CREDENTIALS + role_name )
153
+ ec2_metadata_request ( EC2_IAM_SECURITY_CREDENTIALS + role_name , token )
154
154
end
155
155
156
- def ec2_metadata_request ( url )
156
+ def ec2_metadata_request ( url , token )
157
157
uri = Gem ::URI ( url )
158
158
@request_pool ||= create_request_pool ( uri )
159
159
request = Gem ::Request . new ( uri , Gem ::Net ::HTTP ::Get , nil , @request_pool )
160
- response = request . fetch
160
+ response = request . fetch do |req |
161
+ req . add_field "X-aws-ec2-metadata-token" , token
162
+ end
161
163
162
164
case response
163
165
when Gem ::Net ::HTTPOK then
@@ -167,13 +169,30 @@ def ec2_metadata_request(url)
167
169
end
168
170
end
169
171
172
+ def ec2_metadata_token
173
+ uri = Gem ::URI ( EC2_IAM_TOKEN )
174
+ @request_pool ||= create_request_pool ( uri )
175
+ request = Gem ::Request . new ( uri , Gem ::Net ::HTTP ::Put , nil , @request_pool )
176
+ response = request . fetch do |req |
177
+ req . add_field "X-aws-ec2-metadata-token-ttl-seconds" , 60
178
+ end
179
+
180
+ case response
181
+ when Gem ::Net ::HTTPOK then
182
+ response . body
183
+ else
184
+ raise InstanceProfileError . new ( "Unable to fetch AWS metadata from #{ uri } : #{ response . message } #{ response . code } " )
185
+ end
186
+ end
187
+
170
188
def create_request_pool ( uri )
171
189
proxy_uri = Gem ::Request . proxy_uri ( Gem ::Request . get_proxy_from_env ( uri . scheme ) )
172
190
certs = Gem ::Request . get_cert_files
173
191
Gem ::Request ::ConnectionPools . new ( proxy_uri , certs ) . pool_for ( uri )
174
192
end
175
193
176
194
BASE64_URI_TRANSLATE = { "+" => "%2B" , "/" => "%2F" , "=" => "%3D" , "\n " => "" } . freeze
195
+ EC2_IAM_TOKEN = "http://169.254.169.254/latest/api/token"
177
196
EC2_IAM_INFO = "http://169.254.169.254/latest/meta-data/iam/info"
178
197
EC2_IAM_SECURITY_CREDENTIALS = "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
179
198
end
0 commit comments