Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Elastic BeansTalk Django cronjob post request returning 403 error

I'm working on a software function in which I have to delete files periodically using Django + cron + AWS. The problem is I can't make it work. What's the best way to make it work? Am I missing some AWS configuration? I've configured one web server and one worker environment, deployed the same application version on them. The task is a view mapped into a url (accessing the url the function is executed). There's a confirmation message on the worker environment:

Successfully loaded 1 scheduled tasks from cron.yaml.

But also an 403 error on the worker access_log:

"POST /networks_app/delete_expired_files HTTP/1.1" 403 2629 "-" "aws-sqsd/2.0"

cron.yaml:

version: 1
cron:
 - name: "delete_expired_files"
   url: "/networks_app/delete_expired_files"
   schedule: "10 * * * *"

url mapping at urls.py:

urlpatterns = [
    url(r'^delete_expired_files', views.delete_expired_files, name='delete_expired_files'),
]

function to delete files at views.py:

def delete_expired_files(request):
    users = DemoUser.objects.all()
    for user in users:
        documents = Document.objects.filter(owner=user.id)
        if documents:
            for doc in documents:
                now = timezone.now()
                if now >= doc.date_published + timedelta(days=doc.owner.group.valid_time):
                    doc.delete()

My IAM roles are:

AmazonSQSFullAccess

AmazonS3FullAccess

AWSElasticBeanstalkFullAccess

AmazonDynamoDBFullAccess

If I access the url via browser, the task is executed (the expired files are deleted). However, the worker environment was supposed to access the url and execute the task automatically and not only when I access the url via browser. How can I make it work?

like image 384
Jaqueline Passos Avatar asked Feb 04 '16 20:02

Jaqueline Passos


Video Answer


1 Answers

I had a similar issue. In my case, I needed to modify 2 things to get it to work:

  1. Ensure the view is set up to accept a POST action from AWS. Previously I had mine set up as GET only, and it doesn't seem that AWS supports GET cron requests.

  2. Once it supports POST, make it CSRF-exempt, so that Django isn't afraid that there's a CSRF threat taking place when AWS makes POST requests lacking a CSRF token. You can use the @csrf_exempt decorator described at this SO answer; in my case, it was slightly more complicated still by my using a class-based view, and I found this other SO answer on how to include the @csrf_exempt decorator on a class-based view.

like image 178
jmq Avatar answered Oct 13 '22 07:10

jmq