aws

lepistane 2024-04-23T19:23:04.159469Z

maybe super basic questions but i don't really know how to do this. I had a service that was uploading files to s3 automatically using aws cli (babashka). Service was moved to k8 cluster and all was well. There was a request to stop using aws cli and start using aws-api https://github.com/cognitect-labs/aws-api/ (and make service jvm) After short port and testing of functionality locally - all is good but once it was deployed to k8 cluster put-object was failing because access was denied. After looking further i realized that that credentials are different. Aws cli - uses pod role (as expected) aws-api - uses ec2 role (wrong) I found https://github.com/cognitect-labs/aws-api/blob/main/examples/assume_role_example.clj#L48 but role can't be assumed because sts client picks up node credentials which is wrong. https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html - has assume role https://github.com/cognitect-labs/aws-api/blob/0f0089f42c189ddf60b6ba2e0286bb71974aed63/src/cognitect/aws/credentials.clj#L321 - doesn't have assume role Is there a way for me to implement this? I can't be the first one that came across this?

2024-04-23T19:37:26.208689Z

What do you mean by sts client picks up node creds? I don't see an sts client in the line you linked?

2024-04-23T19:38:10.622769Z

How is/was the AWS cli finding the pod role?

lepistane 2024-04-23T19:42:02.210709Z

How is/was the AWS cli finding the pod role?
I am assuming by default because when exec -it into the pod and do
aws sts get-caller-identity
it pulls POD role. Here is the link to sts client:https://github.com/cognitect-labs/aws-api/blob/main/examples/assume_role_example.clj#L12

2024-04-23T19:45:41.683169Z

Ah, yes, sorry the example has an sts client at the top. Yeah the assume role stuff doesn't change the existing client/credentials it makes a new client with new credentials for the assumed role

2024-04-23T19:47:23.699019Z

https://github.com/cognitect-labs/aws-api/blob/main/src/cognitect/aws/credentials.clj#L332 is the code and the order in which different credential providers are checked

lepistane 2024-04-23T19:47:39.515269Z

Yeah i saw that and hoped i can extend it or something 😄

2024-04-23T19:48:13.080469Z

You can, the assumed role is an example of that, it uses it's own provider

lepistane 2024-04-23T19:49:35.906009Z

Yeah but it doesn't work in my case as it's picking up node credentials.

lepistane 2024-04-23T19:49:44.978739Z

Or i am missing something?

2024-04-23T19:50:21.613519Z

I think you need to back up, did you do any assume role stuff with aws-cli?

lepistane 2024-04-23T19:51:33.118549Z

not manually, i honestly didn't do anything. I was little bit magical

2024-04-23T19:51:37.981689Z

(is assume role the problem you are trying to solve, or is assume role a new problem with what could be a solution to the problem)

2024-04-23T19:51:46.653769Z

So forget assume role

✔️ 1
2024-04-23T19:52:16.142839Z

The issue is just aws-cli got the right credentials somehow, but aws-api is not

lepistane 2024-04-23T19:53:54.346499Z

Ok yes

2024-04-23T19:55:02.504959Z

If you can get aws-cli to tell you where it is getting creds from that would be great

2024-04-23T19:55:51.305749Z

Alternatively you can go down the list of cred providers (in the order in the code there) checking to see if the env variables or system properties are being set somewhere

lepistane 2024-04-23T19:56:34.489319Z

Ok, gonna start looking on how/where aws cli got the creds

2024-04-23T19:58:55.551819Z

You may just need to set AWS_CONTAINER_CREDENTIALS_RELATIVE_URI in the environment

lepistane 2024-04-23T20:05:50.466779Z

this kinda tells me

2024-04-23 20:04:18,215 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: env
2024-04-23 20:04:18,215 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: assume-role
2024-04-23 20:04:18,215 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: assume-role-with-web-identity
2024-04-23 20:04:18,216 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /usr/local/aws-cli/v2/2.15.40/dist/awscli/botocore/data/endpoints.json
2024-04-23 20:04:18,229 - MainThread - botocore.hooks - DEBUG - Event choose-service-name: calling handler <function handle_service_name_alias at 0xffffa82f91c0>

lepistane 2024-04-23T20:06:01.172489Z

that it's assume-role-with-web-identity right?

lepistane 2024-04-23T20:06:29.699849Z

ran

aws s3 ls --debug
and bunch of things happened

lepistane 2024-04-23T20:11:51.143429Z

same for aws sts get-caller-identity --debug

lepistane 2024-04-23T20:34:58.643839Z

tested upload with

import boto3

def upload_file_to_s3(file_name, bucket, object_name=None):
    """
    Upload a file to an Amazon S3 bucket

    :param file_name: File to upload
    :param bucket: Bucket to upload to
    :param object_name: S3 object name. If not specified, file_name is used
    :return: True if file was uploaded, else False
    """
    # If S3 object_name was not specified, use file_name
    if object_name is None:
        object_name = file_name

    # Create an S3 client
    s3_client = boto3.client('s3')

    try:
        # Upload the file
        response = s3_client.upload_file(file_name, bucket, object_name)
    except Exception as e:
        print(f'Error uploading file: {e}')
        return False
    return True

# Example usage
file_name = 'example.txt'  # This is the file to upload
bucket_name = 'your-bucket-name'  # Replace with your S3 bucket name
object_name = 'dest_filename.txt'  # S3 object name (optional)

uploaded = upload_file_to_s3(file_name, bucket_name, object_name)
if uploaded:
    print('File was uploaded successfully')
else:
    print('Failed to upload file')
File was uploaded without any permissions issues

lepistane 2024-04-23T20:35:06.064849Z

So it's something with aws-api

2024-04-23T20:44:02.455219Z

I don't know that the list output there actually tells you where the initial set of credentials came from

2024-04-23T20:45:35.057119Z

the last credential thing logged is for assume-role-with-web-identity, so that might be where the final set of credentials came from, but assuming "assume-role" in the name there means it is using the assume role api stuff, then it must have found some earlier set of credentials that had the permissions to assume the role

2024-04-23T20:49:22.362419Z

ah, assume-role-with-web-identity stuff might actually mean another set of environment variables, not actually calling the assume role api at all

2024-04-23T20:50:06.533149Z

AWS_WEB_IDENTITY_TOKEN_FILE
doesn't appear in aws-api at all

2024-04-23T20:56:53.189059Z

so you might be able to follow the assume rule example, but swap out https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html for the AssumeRole op and grab the parameters it needs from the env vars in the docs

lepistane 2024-04-23T21:00:28.964839Z

so you are thinking about https://github.com/cognitect-labs/aws-api/blob/main/examples/assume_role_example.clj#L18 instead of using AssumeRole to use AssumeRoleWithWebIdentity operation and then pass everything just like in the example?

lepistane 2024-04-23T21:00:32.821449Z

Did i understand you correctly?

2024-04-23T21:02:39.558719Z

no, the args to AssumeRoleWithWebIdentity are different, and it is likely aws-cli is grabbing them from the environment AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, and AWS_ROLE_SESSION_NAME so you'll need to adjust that too

lepistane 2024-04-23T21:41:33.520689Z

AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, are in the pod will see if it's possible to attempt this. Thank you so much i will let you know how it goes. Maybe PR to aws-cli so that no one else has to deal with this 😄

lepistane 2024-04-24T11:27:52.295009Z

solved with https://gist.github.com/gws/130ad8bfec5495c25c3dbc0ed2a69d42