Decomposition & Comparison: Why sometimes AWS CLI create-invalidation cannot clear Amazon CloudFront cache

Post Title Image (Photo by Wilhelm Gunkel on Unsplash)

Introduction

Since moving my blog from GitHub Pages to Amazon S3 + Amazon CloudFront, the deployment time and webpage loading time have been greatly reduced.

Even for long articles like Ernest PKM (Personal Knowledge Management) Workflow, the webpage loading time can still achieve DOMContentLoaded < 650 ms and Load < 2.5 s. The deployment time has been significantly reduced from an average of 10-13 minutes on GitHub Pages build to less than 1 minute when there are no image changes.

However, this led to another issue of managing and deciding the CDN cache expiration period.

As a proponent of “laziness is the mother of progress,” it should be lazy enough to directly use the wildcard character * to clear the cache in my Amazon CloudFront distribution on my blog (maybe :p).

So, have you compared the following scenarios? Which value for the paths can truly create an invalidation to clear the cache in the Amazon CloudFront distribution?

  • (A) aws cloudfront create-invalidation --distribution-id {dist_id} --paths /*
  • (B) aws cloudfront create-invalidation --distribution-id {dist_id} --paths '/*'
  • (C) aws cloudfront create-invalidation --distribution-id {dist_id} --paths *
  • (D) aws cloudfront create-invalidation --distribution-id {dist_id} --paths '*'

The results may vary depending on the operating system and the SHELL environment you are using. You can try to make a guess before looking at the results.

Here, I’m documenting the results I obtained on macOS 13 + zsh + AWS CLI 2.11. In my case, I had to choose (B).

❌ (A) /* with slash, without quote

The SHELL does additional work in this case. Please refer to the section “3.4.9. File name expansion” in the Shell expansion article. As a result, you will see 16 Path Items below. However, none of these exist in my Amazon CloudFront distribution. So, even though I successfully created a CloudFront invalidation each time, it didn’t correspond to the path I wanted to clear. Therefore, even if I execute this AWS CLI command, my blog article cache remains unchanged, and I continue to see the content of the old versions of the articles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
❯ aws cloudfront create-invalidation --distribution-id {dist_id} --paths /*
{
    "Location": "https://cloudfront.amazonaws.com/2020-05-31/distribution/{dist_id}/invalidation/IEFW9PJ2I78V8D7KL3X90S8D7N",
    "Invalidation": {
        "Id": "IEFW9PJ2I78V8D7KL3X90S8D7N",
        "Status": "InProgress",
        "CreateTime": "",
        "InvalidationBatch": {
            "Paths": {
                "Quantity": 16,
                "Items": [
                    "/Applications",
                    "/home",
                    "/Volumes",
                    "/private",
                    "/Users",
                    "/bin",
                    "/sbin",
                    "/var",
                    "/dev",
                    "/usr",
                    "/etc",
                    "/opt",
                    "/System",
                    "/Library",
                    "/cores",
                    "/tmp"
                ]
            },
            "CallerReference": "cli-1685975853-185479"
        }
    }
}

✅ (B) /* with slash, with quote

You can see that the Path Item has become just one, and it is the lazy method I wanted to use, /*.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
❯ aws cloudfront create-invalidation --distribution-id {dist_id} --paths '/*'
{
    "Location": "https://cloudfront.amazonaws.com/2020-05-31/distribution/{dist_id}/invalidation/IPBL9DUBVBJ39DIJ7EHE6CS9K",
    "Invalidation": {
        "Id": "IPBL9DUBVBJ39DIJ7EHE6CS9K",
        "Status": "InProgress",
        "CreateTime": "",
        "InvalidationBatch": {
            "Paths": {
                "Quantity": 1,
                "Items": [
                    "/*"
                ]
            },
            "CallerReference": "cli-1685977774-963591"
        }
    }
}

❌ (C) * without slash, without quote

When manually performing a CloudFront invalidation in the AWS Management Console, it conveniently adds the leading slash for you. However, in reality, the CloudFront API requires /* to function properly. So, providing just * to the API will not work.

1
2
3
❯ aws cloudfront create-invalidation --distribution-id {dist_id} --paths *

An error occurred (InvalidArgument) when calling the CreateInvalidation operation: Your request contains one or more invalid invalidation paths.

❌ (D) * without slash, with quote

1
2
3
❯ aws cloudfront create-invalidation --distribution-id {dist_id} --paths '*'

An error occurred (InvalidArgument) when calling the CreateInvalidation operation: Your request contains one or more invalid invalidation paths.

Reference

Loading comments…