Skip to content

Does AWS SDK Go V2 take into account Fargate's different IMDS credential endpoint? #2558

Closed
@HJTP

Description

Acknowledgements

Describe the bug

We run Go in an ECS container in Fargate. I attached a policy to the ECS task execution role that should get it access to SES (we want to send an e-mail) but it fails to access the IMDS endpoint:

Get "http://169.254.169.254/latest/meta-data/iam/security-credentials/": dial tcp 169.254.169.254:80: connect: invalid argument

Therefore, it cannot access credentials and thus the call to SES fails.

Expected Behavior

I would expect the SDK to load the credentials from the role/policy. Perhaps this requires accessing a different IP address as listed here:
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html

Credentials can be retrieved from curl 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI

Current Behavior

It tries to connect to http://169.254.169.254/latest/meta-data/iam/security-credentials/ but it fails

The IP address is hardcoded here:

defaultIPv4Endpoint = "http://169.254.169.254"

Reproduction Steps

The example from the docs will do:

package main

import (
	"context"
	"log"
	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
	// Load the Shared AWS Configuration (~/.aws/config)
	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		log.Fatal(err)
	}

	// Create an Amazon S3 service client
	client := s3.NewFromConfig(cfg)

	// Get the first page of results for ListObjectsV2 for a bucket
	output, err := client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{
		Bucket: aws.String("my-bucket"),
	})
	if err != nil {
		log.Fatal(err)
	}

	log.Println("first page results:")
	for _, object := range output.Contents {
		log.Printf("key=%s size=%d", aws.ToString(object.Key), object.Size)
	}
}

But make sure to run it inside a Docker container on Fargate, for example with this task-definition.json

{
  "family": "my-application",
  "executionRoleArn": "my-ecs-task-execution-role-that-has-AmazonSESFullAccess",
  "networkMode": "awsvpc",
  "cpu": "4096",
  "memory": "8192",
  "requiresCompatibilities": ["FARGATE"],
  "containerDefinitions": [
    {
      "name": "backend",
      "image": "myaccount.dkr.ecr.eu-west-1.amazonaws.com/image:latest",
      "cpu": 512,
      "memory": 1024,
      "essential": true,
      "portMappings": [
        {
          "containerPort": 8080,
          "protocol": "tcp"
        },
        {
          "hostPort": 22,
          "containerPort": 22,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-create-group": "true",
          "awslogs-group": "/ecs/service-service",
          "awslogs-region": "eu-west-1",
          "awslogs-stream-prefix": "backend"
        }
      }
    }

### Possible Solution

Should the SDK detect that the container is running in Fargate and query the `169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` endpoint instead of the `169.254.169.254` one?

Or perhaps this should be configurable

### Additional Information/Context

_No response_

### AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2 v1.24.1
github.com/aws/aws-sdk-go-v2/config v1.26.6
github.com/aws/aws-sdk-go-v2/service/ses v1.19.6

### Compiler and Version used

1.19

### Operating System and version

docker.io/library/golang:1.19

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.needs-triageThis issue or PR still needs to be triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions