MichaelRSF
MichaelRSF

Reputation: 896

Credentials can't be located for S3 Flask app in Heroku

My flask app works locally with AWS S3 bucket, but when I try to get it to work in Heroku, I keep getting this error

2020-06-07T00:58:29.174989+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/botocore/signers.py", line 160, in sign
2020-06-07T00:58:29.174989+00:00 app[web.1]:     auth.add_auth(request)
2020-06-07T00:58:29.174989+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/botocore/auth.py", line 357, in add_auth
2020-06-07T00:58:29.174989+00:00 app[web.1]:     raise NoCredentialsError
2020-06-07T00:58:29.174994+00:00 app[web.1]: botocore.exceptions.NoCredentialsError: Unable to locate credentials

I've been going over this issue for over a day now. Here is a snippet of my code from my app.py file.

from flask import render_template, request, redirect, url_for
import boto3, os, zipfile, io


AWS_STORAGE_BUCKET_NAME ="some bucket"   

AWS_ACCESS_KEY_ID="some key"
AWS_SECRET_ACCESS_KEY="some secret key"


s3 = boto3.client(
    "s3",
    aws_access_key_id = AWS_ACCESS_KEY_ID,
    aws_secret_access_key = AWS_SECRET_ACCESS_KEY)
s3_resource = boto3.resource("s3")
my_bucket = s3_resource.Bucket(AWS_STORAGE_BUCKET_NAME)

Also, in my bucket, I configured the CORS configuration by pasting this from the docs.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

My requirements.txt file

Flask==1.1.1
Flask_SQLAlchemy==2.4.1
Werkzeug==1.0.0
Flask_WTF==0.14.3
SQLAlchemy==1.3.13
arrow==0.15.6
alembic==1.4.2
boto3==1.13.16
boto==2.49.0
botocore==1.16.16
Flask_Migrate==2.5.3
Pillow==7.1.2
psycopg2==2.8.4
gunicorn==19.9.0
requests==2.22.0
certifi==2019.6.16
chardet==3.0.4
Click==7.0
distributed==2.1.0
gunicorn==19.9.0
itsdangerous==1.1.0
Jinja2==2.10.1
MarkupSafe==1.1.1
pytz==2019.1

All I'm currently doing in my simple app is reading the file names from my bucket, and displaying it on the home page. Works fine on my local app, but not on heroku. Any help would be very much appreciated.

Upvotes: 1

Views: 666

Answers (1)

Atte
Atte

Reputation: 308

I am not certain if providing authentication parameters to the client method will extend to calling resource. Is it possible that boto3.resource isn't authenticated on heroku but can get authentication on your local machine through environment variables or the .aws directory. Have you tried setting the secrets as environment variables (see:https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html) in Heroku, or using an authenticated session to create the resource:

session = boto3.Session( aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY)

s3 = session.resource('s3')

Upvotes: 3

Related Questions