chander
chander

Reputation: 2167

Cannot access instance metadata from within a FARGATE Task

I have an AWS FARGATE Task that is running a relatively simple python application (with a Docker image built from python:3.6-stretch .) It runs fine using Amazon EC2 Tasks (Where an EC2 host provides the docker container); but I'm trying to move these to FARGATE.

When I deploy my images in Fargate and they attempt to get the local IPv4 data using the URL:

'http://169.254.169.254/latest/meta-data/local-ipv4'

I get the error:

HTTPConnectionPool(host='169.254.169.254', port=80): Max retries exceeded with url: /latest/meta-data/local-ipv4 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f086aa8d438>: Failed to establish a new connection: [Errno 22] Invalid argument',))

As a side note, my FARGATE container here is sitting on a private subnet ( there is a nat gateway configured and the instance(s) can get out to the internet) . the IP space is 10.160.16.0/20 .

The image is based on the python:3.6-stretch docker image.

Is there something I need to do to get a FARGATE task to be able to access the link-local address?

TIA!

Upvotes: 5

Views: 11743

Answers (4)

sanjay HillStudios
sanjay HillStudios

Reputation: 1

Try to get data from environment variable. Don't use IP address directly.

In my situation my environment variable has some random string appended to IP address. So better to call get request on environment variable: ECS_CONTAINER_METADATA_URI_V4

Upvotes: 0

hendryanw
hendryanw

Reputation: 1937

Attempting to answer the original question. In order to fetch the IP address information for the task running on AWS Fargate with Amazon ECS, you can use Amazon ECS task metadata endpoint. The endpoint URI is injected automatically to each container within the task as environment variable ECS_CONTAINER_METADATA_URI_V4.

For example:

curl ${ECS_CONTAINER_METADATA_URI_V4}

will return

{
    "DockerId": "cd189a933e5849daa93386466019ab50-2495160603",
    "Name": "curl",
    "DockerName": "curl",
    "Image": "111122223333.dkr.ecr.us-west-2.amazonaws.com/curltest:latest",
    "ImageID": "sha256:25f3695bedfb454a50f12d127839a68ad3caf91e451c1da073db34c542c4d2cb",
    "Labels": {
        "com.amazonaws.ecs.cluster": "arn:aws:ecs:us-west-2:111122223333:cluster/default",
        "com.amazonaws.ecs.container-name": "curl",
        "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west-2:111122223333:task/default/cd189a933e5849daa93386466019ab50",
        "com.amazonaws.ecs.task-definition-family": "curltest",
        "com.amazonaws.ecs.task-definition-version": "2"
    },
    "DesiredStatus": "RUNNING",
    "KnownStatus": "RUNNING",
    "Limits": {
        "CPU": 10,
        "Memory": 128
    },
    "CreatedAt": "2020-10-08T20:09:11.44527186Z",
    "StartedAt": "2020-10-08T20:09:11.44527186Z",
    "Type": "NORMAL",
    "Networks": [
        {
            "NetworkMode": "awsvpc",
            "IPv4Addresses": [
                "192.0.2.3"
            ],
            "AttachmentIndex": 0,
            "MACAddress": "0a:de:f6:10:51:e5",
            "IPv4SubnetCIDRBlock": "192.0.2.0/24",
            "DomainNameServers": [
                "192.0.2.2"
            ],
            "DomainNameSearchList": [
                "us-west-2.compute.internal"
            ],
            "PrivateDNSName": "ip-10-0-0-222.us-west-2.compute.internal",
            "SubnetGatewayIpv4Address": "192.0.2.0/24"
        }
    ],
    "ContainerARN": "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1",
    "LogOptions": {
        "awslogs-create-group": "true",
        "awslogs-group": "/ecs/containerlogs",
        "awslogs-region": "us-west-2",
        "awslogs-stream": "ecs/curl/cd189a933e5849daa93386466019ab50"
    },
    "LogDriver": "awslogs"
}

Upvotes: 2

Sal
Sal

Reputation: 365

Here is python version of the process to get role credentials from within the Fargate container. Although the code below is for a S3 bucket (tested Dec 2020), the principle applies for other AWS services as well. Just initiate your boto3 client for that service and attach correct role to the Fargate task with the right policy. The relative credential URI looks similar to '/v2/credentials/xxxx-xxxx-xxxx-xxxx' (mind the forward slash at the beginning) if you're interested.

creds_uri = os.environ.get('AWS_CONTAINER_CREDENTIALS_RELATIVE_URI')
r = requests.get('http://169.254.170.2{}'.format(creds_uri))
credentials = r.json()
s3_client = boto3.client('s3',
                         aws_access_key_id=credentials['AccessKeyId'],
                         aws_secret_access_key=credentials['SecretAccessKey'],
                         aws_session_token=credentials['Token'])
    

Upvotes: 1

Shawn Clake
Shawn Clake

Reputation: 181

I believe this is because you are using the wrong endpoint for AWS Fargate. According to the docs listed below, your IP is wrong.

Use 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI to get IAM metadata.

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html

I hope this helps :)

Upvotes: 5

Related Questions