diff --git a/lib/ec2macosinit/userdata.go b/lib/ec2macosinit/userdata.go index b32a40e..e8eb3e6 100644 --- a/lib/ec2macosinit/userdata.go +++ b/lib/ec2macosinit/userdata.go @@ -33,6 +33,15 @@ func (c *UserDataModule) Do(ctx *ModuleContext) (message string, err error) { return "", fmt.Errorf("ec2macosinit: received an unexpected response code from IMDS: %d - %s\n", respCode, err) } + // Attempt to base64 decode userdata. + // This maintains consistency alongside Amazon Linux 2's cloud-init, which states: + // "Some tools and users will base64 encode their data before handing it to + // an API like boto, which will base64 encode it again, so we try to decode." + decoded, err := decodeBase64(ud) + if err == nil { + ud = decoded + } + // Write user data to file userDataFile := path.Join(baseDir, ctx.IMDS.InstanceID, fileName) f, err := os.OpenFile(userDataFile, os.O_CREATE|os.O_WRONLY, 0755) diff --git a/lib/ec2macosinit/util.go b/lib/ec2macosinit/util.go index 25a2e8c..40a44ea 100644 --- a/lib/ec2macosinit/util.go +++ b/lib/ec2macosinit/util.go @@ -2,6 +2,7 @@ package ec2macosinit import ( "bytes" + "encoding/base64" "fmt" "io" "os" @@ -194,3 +195,13 @@ func getOSProductVersion() (version string, err error) { return version, nil } + +// decodeBase64 attempts to decode base64 data and returns the decoded string if successful +func decodeBase64(base64Data string) (decodedString string, err error) { + decodedBytes, err := base64.StdEncoding.DecodeString(base64Data) + if err != nil { + return "", fmt.Errorf("ec2macosinit: failed to decode base64 string: %s\n", err) + } + + return string(decodedBytes), nil +}