Search code examples
djangoamazon-web-servicesboto3iis-10

django boto3: NoCredentialsError -- Ubale to locate credentials


I am running django website which is served by IIS on an amazon ec2 instance(windows 10) and I'm using boto3 module to send an email.

I installed awscli and ran aws configure and set up my aws access keys check out attached image

My email sending code looks like this:

import boto3
from botocore.exceptions import ClientError
from django.shortcuts import redirect, render
from django.http import HttpResponseRedirect

def sendEmail(request):

    if request.method == 'POST':
        SENDER = "Sender Name <xxx>"

        RECIPIENT = "xxx"

        AWS_REGION = "eu-west-1"

        # The subject line for the email.
        SUBJECT = "Amazon SES Test (SDK for Python)"

        # The email body for recipients with non-HTML email clients.
        BODY_TEXT = ("Amazon SES Test (Python)\r\n"
                    "This email was sent with Amazon SES using the "
                    "AWS SDK for Python (Boto)."
                    )

        # The HTML body of the email.
        BODY_HTML = """<html>
        <head></head>
        <body>
        <h1>Amazon SES Test (SDK for Python)</h1>
        <p>This email was sent with
            <a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
            <a href='https://aws.amazon.com/sdk-for-python/'>
            AWS SDK for Python (Boto)</a>.</p>
        </body>
        </html>
                    """

        # The character encoding for the email.
        CHARSET = "UTF-8"

        # Create a new SES resource and specify a region.
        client = boto3.client('ses', region_name=AWS_REGION)


        try:
            # Provide the contents of the email.
            response = client.send_email(
                Destination={
                    'ToAddresses': [
                        RECIPIENT,
                    ],
                },
                Message={
                    'Body': {
                        'Html': {
                            'Charset': CHARSET,
                            'Data': BODY_HTML,
                        },
                        'Text': {
                            'Charset': CHARSET,
                            'Data': BODY_TEXT,
                        },
                    },
                    'Subject': {
                        'Charset': CHARSET,
                        'Data': SUBJECT,
                    },
                },
                Source=SENDER,
            )
        # Display an error if something goes wrong.
        except ClientError as e:
            print(e.response['Error']['Message'])
            return render(request, 'error.html')
        else:
            print("Email sent! Message ID:"),
            print(response['MessageId'])
            return render(request, 'success.html')

Where xxx indicates verified emails on AWS.

My error looks like this:

Django Version: 3.0.3
Exception Type: NoCredentialsError
Exception Value:    
Unable to locate credentials
Exception Location: c:\users\administrator\python38\lib\site-packages\botocore\auth.py in add_auth, line 357
Python Executable:  c:\users\administrator\python38\python.exe
Python Version: 3.8.1
Python Path:    
['.',
 'c:\\users\\administrator\\python38\\python38.zip',
 'c:\\users\\administrator\\python38\\DLLs',
 'c:\\users\\administrator\\python38\\lib',
 'c:\\users\\administrator\\python38',
 'c:\\users\\administrator\\python38\\lib\\site-packages',

I used to send emails when this website was just running using "python manage.py runserver 0.0.0.0:80" in CMD but after I deployed it on IIS and also added SSL it doesn't work anymore.

I found kinda similar question for apache but don't know how to adjust to my circumstances.


Solution

  • I suspect that the problem you are having is that the effective user that IIS and your app are running under is not the same user (Administrator) that you configured the credentials for. Hence your app cannot find the credentials file because it's home directory is not the same.

    However, this is not the correct way to provide credentials to applications running on EC2. Instead, you should launch EC2 instances with an IAM role, rather than manually configuring credentials on the instance in the ~/.aws/credentials file.