-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue #16 is not solved by pull request #23; support AWS_WEB_IDENTITY_TOKEN_FILE as credential provider on EKS #31
Comments
@cpaika @j-hartshorn @osalloum I was wondering if you had a chance to validate the #16 fix from PR #23? Do you experience the same issues I'm seeing here or did your problems go away? If you were able to get things working, could you share the code you used to make it work? duckdb authors: Let me know if you need any additional info to help troubleshoot. |
Hey @joegoggins Thanks for opening the issue, I haven't really had time to investigate this properly so this is very helpful. Setting up some test infrastructure with AWS that can be used by the |
Thanks for the quick reply @samansmink. I'll provide a few more ideas that might allow you to repro/fix this issue quickly.
Before tinkering with CI, I'd recommend trying a scrappy approach to get the basic repro down and get your head around how the
|
I wanted to update that i'm getting same error and the s3 https endpoint is not set correctly as well like
from |
I am also facing this issue. As suggested I tried using the regional endpoint, but that also does not work. Apologies for table output being wide.
I know this is correct by using
While duckdb fails:
|
Also something I'm seeing! Instead of pulling directly from AWS like: cursor.execute(
f"""
INSTALL aws;
INSTALL httpfs;
LOAD aws;
LOAD httpfs;
CREATE SECRET secret3 (
TYPE S3,
PROVIDER CREDENTIAL_CHAIN,
-- tried all different options here
);
CREATE OR REPLACE TABLE country_data AS
SELECT *
FROM parquet_scan('{folder}/something=*/*.parquet', filename=true);
"""
)
logger.info("Data loaded into DuckDB.") We were seeing a lot of 403 errors (we run our pods on EKS) My hacked alternative is the following (but does not perform as well as the first from my tests) def load_data() -> None:
"""Load data from S3 into DuckDB."""
folder = f"s3://{S3_BUCKET}/{something}"
data_file = "data.parquet"
if os.path.exists(data_file):
os.remove(data_file)
logger.info("Removed existing data file.")
logger.info(f"Loading parquet data from {folder}.")
df = wr.s3.read_parquet(path=folder, boto3_session=SESSION, dataset=True)
logger.info("Data loaded.")
df.to_parquet(data_file, index=False)
del df # noqa: F821 Remove df to free up memory
logger.info("Data saved to parquet file.")
cursor.execute(
f"""
CREATE OR REPLACE TABLE country_data AS
SELECT *
FROM read_parquet('{data_file}', filename=true);
"""
)
logger.info("Data loaded into DuckDB.")
os.remove(data_file)
logger.info("Data file removed.")
logger.info("Dataset loaded successfully.") So would be very cool to fix this!!!!! |
I dont know if relevant, but I used This yielded Making it seem like it's ignoring What I find weird is that it all works fine locally, if I steal the AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN from the pod and attempt the same duckdb call with EDIT: Also, my current workaround is as such (since boto3 is transparently assuming the right role already): aws_session = boto3.Session()
creds = aws_session.get_credentials().get_frozen_credentials()
db = duckdb.connect()
db.execute(
f"""
CREATE SECRET aws_secret (
TYPE S3,
REGION '{aws_session.region_name}',
KEY_ID '{creds.access_key}',
SECRET '{creds.secret_key}',
SESSION_TOKEN '{creds.token}'
)
"""
) |
Also still not working for me, the credentials chain is seemingly ignoring the "sts" authentication method Maybe if we get a debug build with verbose logging enabled Furthermore I don't understand this part: we can create many secrets of type S3 , but which one would the extension use? i haven't found a parameter which i can pass to
|
This is a big problem for us. We have a pretty strict no static credentials policy and that seems to be the only thing that works in EKS. |
As of the DuckDB 1.0 release I'm still not seeing support for temporary credentials retrieved via STS AssumeRole. While default auth will produce a key/token, trying to auth using a config profile that sets a role_arn or setting The only way I've been able to get things working in a pinch is to run |
I might have a clue around why this is not working yet. I think that the sts module of the aws sdk should be statically linked by CMake/ vcpkg The current build does not specify STS as dependency , hence the web identity token file logic never gets checked Line 19 in 42c78d3
I am guessing that this would be a bit similar to AWS sdk in java where if it does not find sts in the CLASSPATH, it wouldn't attempt it -- Update 1 -- I just validated that current build does not link sts, if you check the logs here from github actions -- Update 2 -- I was able to add sts and build the aws sts library but now i need to build duckdb with the same build tag ( to validate the built extension :( osalloum#1
I will try pick this up later this week |
@osalloum I set up a duckdb local build yesterday as I was hoping to be able to debug things (my experience mirror yours in enabling Profile authentication with the Java SDK). I didn't get far with that plan, but I was just able to toss your branch artifact into At least in my testing this build doesn't appear to fix things right away (both with the below approach and with creating a SECRET. YMMV of course as I haven't touched C++ dev in 20 years.
Hoping to poke around more once I wrap my head around how to set up a decent out of tree extension dev workflow. |
@lukeman Good news I was not able to set up a local dev env on Mac, not quickly as I would like ( I would love to hear some tips on that ) However I forked the duckdb repo and used to build a version without extension version checks Then I uploaded my artifacts to a kubernetes pod on our account and tried it, it works
|
PR attempting to resolve this is now merged and available with force install aws from core_nightly please let me know if this still fails |
FYI This still somehow does not work with all docker images. but if you use an image with an Amazon Linux based docker it would work As examples: public.ecr.aws/lambda/python:3.10 --> works etc |
Thanks. It worked for me using duckdb v1.0.0 on Linux, and the pre-built/released linux_amd64_gcc4 httpfs and aws extensions. In the aws k8s pod environment I had, saw these environment variables: AWS_REGION, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, AWS_STS_REGIONAL_ENDPOINTS, AWS_DEFAULT_REGION; but there is no AWS_ACCESS_KEY_ID, AWS_SESSION_TOKEN, AWS_SECRET_ACCESS_KEY set, nor ~/.aws/credential and ~/.aws/config, which i think is by design/convention per policy. Here is the sample code snippet that worked for me in aws s3 and localstack, which fixed HTTP 403 (and HTTP 400, IO Error: Connection error for HTTP GET to, Unknown error for HTTP GET to) along the way
Hope this feedback is helpful to someone. Let me know if you have comment and suggestion. Thanks. |
We are running latest DuckDB 1.0.0 inside Windmill scripts (usually Python) and the only workaround that made it work for us here (after verifying that DuckDB will see all necessary environment variables) is the one found by @DanCardin . We are also running Windmill inside EKS with AWS IAM service accounts providing the necessary auth, so the following environment variables are set properly and are working as intended with other SDKs on the exact same pod inside the same container:
|
Hey, im observing the same issue using the Java client. |
This issue still persists in DuckDB v1.1.1. Sample query COPY (SELECT *, year(created_at) as year, month(created_at) as month, day(created_at) as day FROM sample) TO 's3://sample-bucket/sample' (FORMAT PARQUET, PARTITION_BY (year, month, day), FILENAME_PATTERN '{uuid}') Sample error message duckdb.duckdb.HTTPException: HTTP Error: HTTP GET error on '/?encoding-type=url&list-type=2&prefix=sample%2F' (HTTP 403) It only works when session token is provided, conn.sql(f"""
CREATE SECRET secret1 (
TYPE S3,
KEY_ID '{access_key}',
SECRET '{secret_key}',
SESSION_TOKEN '{session_token}',
REGION 'ap-southeast-1' );
"""
) I'm running FastAPI on python:3.12.6 in k8s with aws sts, but can't manage to make it work conn.sql(f"""
CREATE SECRET secret1 (
TYPE S3,
PROVIDER CREDENTIAL_CHAIN,
CHAIN 'sts'
REGION 'ap-southeast-1' );
"""
) Any help would be appreciated. |
Second that. |
Same here |
Same over here. |
I still have the same issue too in v1.1.3 (extension version f743d4b)... has anyone seen a change in behavior here? The short version is:
Environmental:
** I'm still using a workaround similar to what @DanCardin mentioned in #31 (comment). |
#16 was marked closed on Jan 2 as part of #23 being merged. Unfortunately, the solution described in the PR body did not work, i.e. #16 does not seem fixed to me. I didn't see any of the authors/commenters of that issue confirm the fix either, so I figured I'd file a bug report here.
Repro
Re-read #16. The problem/repro described here is the same, but with more technical detail that I hoping helps to solve the underlying problem.
Open a pod shell on EKS that defines the following vars:
Run
aws s3 ls s3://example-bucket/example.parquet
, observe successful output like this:This proves AWS CLI / pod perms are good.
Run
./duckdb -unredacted -json
to open duckdb console:Create a secret:
it takes a few seconds here and comes back successful.
Run
select secret_string from duckdb_secrets(redact=false);
Observe that the expected data is there -- key_id, secret, and session_token are set with values that look legit.
Run a query against the s3 bucket:
SELECT * FROM read_parquet('s3://example-bucket/example.parquet');
Observe an error like this:
Note; there is no 403 error here. It looks like somehow the endpoint is not getting set correctly--that https endpoint is clearly not valid. I tried specifying ENDPOINT to 's3.amazonaws.com' in the create secret command, but then I get an error like this:
I've tried lots of different permutations to get around this problem to no avail, here is a list of of other things I've tried/learned:
The problem happens using
[email protected]
in python as well. Similar repro, same error:Using
CHAIN 'config;env'
,CHAIN sts;instance
, or other variants don't fix the problem.The text was updated successfully, but these errors were encountered: