How to invalidate objects in with CloudFront using boto and python3?

Viewed 4989

I found code similar to what I need at the bottom of this page.

#!/usr/bin/env python3
from boto.cloudfront import CloudFrontConnection

aws_access_key         = 'BJDJLSMQRWDSC4UPLS6S' # Not real
aws_secret_access_key  = '8xRnWKxRR/93TeQv3pwzMNR222nwe5kjhYweCAij' # Not real
aws_cf_distribution_id = 'foobar35'

objects = [ '/index.html' ]
conn = CloudFrontConnection(aws_access_key, aws_secret_access_key)
print(conn.create_invalidation_request(aws_cf_distribution_id, objects))

When I run it, I get the following error:

$ ./invalidate.py
Traceback (most recent call last):
  File "./invalidate.py", line 14, in <module>
    print(conn.create_invalidation_request(aws_cf_distribution_id, objects))
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/boto/cloudfront/__init__.py", line 263, in create_invalidation_request
    raise CloudFrontServerError(response.status, response.reason, body)
boto.cloudfront.exception.CloudFrontServerError: CloudFrontServerError: 404 Not Found
<?xml version="1.0"?>
<ErrorResponse xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/">
  <Error>
    <Type>Sender</Type>
    <Code>NoSuchDistribution</Code>
    <Message>The specified distribution does not exist.</Message>
  </Error>
  <RequestId>343d3d5b-e269-11e5-bc96-eb9a228cf3e7</RequestId>
</ErrorResponse>

I think the problem is that I have not identified the S3 bucket where /index.html resides. I have about 20 buckets, each named after the domain part of the URL. I tried various permutations but to no avail.

  • s3://www.example.com.s3.amazonaws.com/index.html
  • s3://www.example.com/index.html
  • /www.example.com/index.html
  • www.example.com/index.html
  • /index.html

Can someone tell me how to get this to work?

3 Answers

The answer from Vladimir Mukhin was helpful: He was correct that my distribution ID was incorrect and that I needed to create a distribution. However, I didn't know how to get my distribution ID. I found it by looking through the awscli docs. The answer was not simply RTFM however, since the information I needed was not easy to find. Here's the answer that finally helped me

aws cloudfront list-distributions

With that info, I was able to find the parallels in the Python, Ruby, and Perl (Paws) APIs to get the correct distribution ID without shelling out to the command line. Hope this helps someone.

using boto3

def invalidate(distributionId:str, path:str='/*')->str:
  '''
    create a cloudfront invalidation
    parameters:
      distributionId:str: distribution id of the cf distribution
      path:str: path to invalidate, can use wildcard eg. "/*" means all path
    response:
      invalidationId:str: invalidation id
  '''
  cf = boto3.client('cloudfront')
  # Create CloudFront invalidation
  res = cf.create_invalidation(
      DistributionId=distributionId,
      InvalidationBatch={
          'Paths': {
              'Quantity': 1,
              'Items': [
                  path
              ]
          },
          'CallerReference': str(time.time()).replace(".", "")
      }
  )
  invalidation_id = res['Invalidation']['Id']
  return invalidation_id

use nicHelper

pip install nicHelper

from nicHelper.cloudfront import invalidate
# invalidate(<distributionId>, <path>)

invalidate("EIOJ239OIUOIU","/*")
Related