Skip to content

Instantly share code, notes, and snippets.

@creisor
Created August 14, 2023 21:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creisor/ed2550354a37035f97102baa5ac48b60 to your computer and use it in GitHub Desktop.
Save creisor/ed2550354a37035f97102baa5ac48b60 to your computer and use it in GitHub Desktop.
Golang to access the AWS metadata endpoint
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
// You could add more fields here. The JSON looks like:
/*
{
"Code" : "Success",
"LastUpdated" : "2023-08-14T16:29:41Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASDF1234",
"SecretAccessKey" : "SUPERSECRET",
"Token" : "blahdiblah",
"Expiration" : "2023-08-14T22:56:15Z"
}
*/
type credentialsResponse struct {
Code string
Token string
}
func main() {
metadataUrl := "http://169.254.169.254"
metadataToken := getMetadataToken(metadataUrl)
//fmt.Printf("metadata token: %s\n", string(metadataToken))
credsToken := getCredsToken(metadataUrl, metadataToken)
//fmt.Printf("creds token: %s\n", credsToken)
}
func getMetadataToken(url string) string {
endpoint := fmt.Sprintf("%s/latest/api/token", url)
req , err := http.NewRequest("PUT", endpoint, nil)
req.Header.Set("X-Aws-Ec2-Metadata-Token-Ttl-Seconds", "21600")
if err != nil {
exitErrorf("Error creating request", err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
exitErrorf("Error making request", err)
}
defer resp.Body.Close()
token, err := io.ReadAll(resp.Body)
if err != nil {
exitErrorf("Error reading token body", err)
}
//fmt.Printf("token: %s\n", string(token))
return string(token)
}
func getCredsToken(url string, token string) string {
endpoint := fmt.Sprintf("%s/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance", url)
req, err := http.NewRequest("GET", endpoint, nil)
if err != nil {
exitErrorf("Error creating request", err)
}
req.Header.Set("X-Aws-Ec2-Metadata-Token", string(token))
resp, err := http.DefaultClient.Do(req)
if err != nil {
exitErrorf("Error making request", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
exitErrorf("Error reading credentials body", err)
}
//fmt.Printf("creds body: %s\n", string(body))
var creds credentialsResponse
if err := json.Unmarshal(body, &creds); err != nil { // Parse []byte to go struct pointer
exitErrorf("Can not unmarshal creds JSON", err)
}
//fmt.Printf("creds: %+v\n", creds)
return creds.Token
}
func exitErrorf(msg string, args ...interface{}) {
fmt.Fprintf(os.Stderr, msg+"\n", args...)
os.Exit(1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment