-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resign requests if they will expire within 1 min #822
Conversation
Thanks for contacting us, @AMeng. The SDK should automatically attempt to retry requests that fail because of expired credentials. It looks like the error code returned by the Route53 service API called is different than those expected. I'll take a look at how the other SDKs handle expired requests for Route53. Naively it looks like the error message will need to be parsed because the error code I think if we can solve the request signature resigning issue on failed request we can solve the issue. Though I agree the signer should be updated to allow custom request expiration to be set. With that said I don't see any issue with checking if the request's signature will expire "soon" and proactively resign it. |
Yep, looking over my failed requests, they are all from Route53. Let me know what you think the best path forward is, and if I can help in any way. |
Thanks for the update @AMeng. This morning I realized in my previous comment I mixed up expired credentials and expired request signatures. With that said, there is no work for us to do on the retry requests I linked in the previous post. In addition is the request being used a pre-signed URL request that the Terraform library vends to your application, or is Terraform making a request on behalf of your application? Or is Terraform providing a AWS SDK for Go I ask because the use-case between the two are fairly different. The Is the SDK just taking a very long time to create the signature of the request? |
I'm not terribly familiar with the Terraform internals. Are you suggesting that they are not correctly handling the request failures? This error is from the The failure seems to come about because AWS is rate limiting my account (I have over 1000 Route53 records), so Terraform waits for the SDK to finish the request (through retries). The actual One other thing I considered was clock skew, where my machine is off from Amazon's API machine just enough to have the failure raise before the request gets re-signed. Although I was able to reproduce this on both EC2 machines, and my local machine. |
Thanks for the additional information @AMeng, this is very helpful. This helps clarify what my be going on. I don't think there is any issue in the way Terraform is using the API, and I don't think there is a need for them to handle the error on their end. I'll dive deeper into how the retries are being done in this context. Its possible that a race condition is going on, but I'm not sure if the change here is the best approach, or if it should be more significant. |
Any updates on this? I wouldn't mind helping out here, given guidance on what the appropriate fix is. |
@AMeng, sorry for the delay, I'm looking into this issue. The more I review this condition I think it might be better for the SDK to not try to determine if the request needs to be resigned at all, and just resign it. Would need to ensure the digest of the request's Body is persisted between retries since this can be costly for large requests. But will not change between retries. |
Syncing with the other AWS SDKs, neither AWS SDK for Java nor AWS SDK for Javascript employ logic to not resign the request. They do implement various levels of caching though. AWS SDK for Java will cache the signing key, and AWS SDK for Javascript will cache the body digest. Since the Go SDK will already cache the body's digest through the With that said, we might want to consider adding the expiry check in the request's Something like the following added to the core handlers, and default handlers func RefreshSignature(r *request.Request) {
signingTime := req.Time
if !req.LastSignedAt.IsZero() {
signingTime = req.LastSignedAt
}
// 10 minutes to allow for some clock skew/delays in transmission. Would be improved
// with aws/aws-sdk-go#423
if time.Now().Before(signingTime.Add(10*time.Minute)) {
return
}
r.Sign()
} |
Improves the relyability of the request signature by resigning the request each retry. In addition logic was added to the Send request handler chain to ensure the delay between Sign and Send will not prevent expired signature. This also brings the SDK in line with the other AWS SDKs in their behavior of resigning the request each retry. Related to aws#822
…ed (#876) Improves the relyability of the request signature by resigning the request each retry. In addition logic was added to the Send request handler chain to ensure the delay between Sign and Send will not prevent expired signature. This also brings the SDK in line with the other AWS SDKs in their behavior of resigning the request each retry. Related to #822
…, Improve Overall SDK Readme (aws#822)
I use Terraform, which uses this library. From time to time while running a
terraform plan
(asks AWS for the status of all my resources, takes a long time) I get this error:I believe there is a race condition where the signature is checked for expiration, verified as not expired, then it expires, and the request is sent off. The expiration is being set in this same file here:
I'm also curious why 10 minutes was chosen as the expiration. Would it be possible to increase this value? Why not, say, one hour?