If you are running outside EC2 and don't have credentials, the AWS SDK will hang for 5+ seconds attempting to connect to the EC2 metadata API. That's annoying.
This is a helper library to detect, quickly, if you are running in EC2 or not. If you are not, then you can avoid including the EC2 metadata API in your credential list.
There are no dependencies.
import "github.com/kevinburke/isec2"
func main() {
yes, err := isec2.IsEC2(context.Background())
if err == nil {
fmt.Println("running on EC2:", yes)
}
}
The main reason to run this is to avoid making endless calls to the EC2 metadata API, 169.254.169.254, and taking 5+ seconds to time out when you are not running in EC2.
To avoid using the EC2 metadata API, build a credentials.Credentials
object as
follows, and then assign it to aws.Config.Credentials
.
import "github.com/kevinburke/isec2"
import "github.com/aws/aws-sdk-go/aws"
import "github.com/aws/aws-sdk-go/aws/credentials"
import "github.com/aws/aws-sdk-go/aws/defaults"
func main() {
conf := defaults.Config()
var creds *credentials.Credentials
handlers := defaults.Handlers()
isEC2, err := isec2.IsEC2(ctx)
if err == nil && !isEC2 {
// these are all of the defaults from the AWS SDK, except we skip the
// AWS Metadata service API ("defaults.RemoteCredProvider")
creds = credentials.NewCredentials(&credentials.ChainProvider{
VerboseErrors: aws.BoolValue(conf.CredentialsChainVerboseErrors),
Providers: []credentials.Provider{
&credentials.EnvProvider{},
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
},
})
conf.Credentials = creds
}
}
We will try to return an answer within a maximum of 50 milliseconds.
You may want to cache the answer as it is unlikely to change for the lifetime of a process.
This library synthesizes the advice from AWS and the advice from ServerFault to do the best possible EC2 detection.