CloudFrontのキャッシュ削除はAWSコンソールから手動で行うことができますが、
デプロイ時に自動化するために、EC2からキャッシュ削除する方法をまとめました。
EC2+S3+CloudFrontは構築済みの前提で説明します。
1. 準備
デプロイ時の状況をシミュレーションするための準備をします。
1-1. S3へファイルアップロードする
まずはテスト用のファイルをアップロードします。
AWSコンソール > サービス > S3 > 該当バケット > アップロード
でS3へ適当な画像ファイルやHTMLファイルなどをアップロードします。
次へを押して、後の確認のためパブリックアクセス権を付与してください。
それ以外の設定はデフォルトでOKで、アップロードを押してください。
アップロードされたもの詳細を表示し、オブジェクトURLへアクセスし内容を確認してください、
CloudFrontのURLへアクセスします。
AWSコンソール > サービス > CloudFront > 該当のディストリビューション
で詳細を表示し、Domain Nameを確認します。
その後ろに、S3でアップロードしたオブジェクトのパスを付与すると該当のファイルへのURLとなります。
https://<domain name>/<object name>
同じ内容が表示されていればOKです。
ちなみに自分は↓の現象に当たったので、S3バケットを作り直しました。
S3+CloudFrontでS3のURLにリダイレクトされてしまう場合の対処法 | Developers.IO
でも作り直さなくても気長に反映されるまで待てば問題ないです。
1-2. S3のファイル上書きする
オリジンサーバ(S3)とキャッシュサーバ(CloudFront)の内容に差異をつけるため、S3の内容を変更します。
先ほどと同じ手順で、同じファイル名かつ違う内容のファイルをS3にアップロードすればOKです。
再アップロードした後、先ほどアクセスしたS3のURLとCloudFrontのURLへそれぞれアクセスし、
S3は変更後の内容、CloudFrontは変更前の内容になっていることを確認します。
CloudFrontのステータスコードは304(リソース未更新)が返ってきていると思います。
2. キャッシュ削除する
CloudFrontキャッシュの削除とは、公式だとファイルの無効化(CreateInvalidation)を指します。
これを行うためにCloudFront APIを利用します。
このAPIを利用する方法として、シェルスクリプトで行う場合と、PHPで行う場合を説明します。
2-1. シェルスクリプトで削除する
AWS CLIをインストール&設定したのちに
$ aws cloudfront create-invalidation
のコマンドでキャッシュ削除することができます。
詳細:[create-invalidation — AWS CLI 2.0.24 Command Reference]
(https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudfront/create-invalidation.html)
EC2の任意フォルダ内に以下のファイルを作成
#!/bin/bash
echo "CloudFront cache clear..."
aws cloudfront create-invalidation \
--distribution-id "EDFDVBD6EXAMPLE" \
--paths "/*"
権限付与して実行
$ chmod 755 clear_cache.sh
$ ./clear_cache.sh
出力結果
CloudFront cache clear...
{
"Invalidation": {
"Status": "InProgress",
"InvalidationBatch": {
"Paths": {
"Items": [
"/*"
],
"Quantity": 1
},
"CallerReference": "cli-1592983262-260490"
},
"Id": "XXXXXXXXXX",
"CreateTime": "2020-06-24T07:21:03.500Z"
},
"Location": "https://cloudfront.amazonaws.com/2019-03-26/distribution/EDFDVBD6EXAMPLE/invalidation/XXXXXXXXXX"
}
参考
CloudFrontキャッシュを削除するシェルスクリプトを書いてみた。 - Qiita
2-2. PHPで削除する
今回はPHPですが、AWS SDKは他の言語もいろいろあるのでなんでも良いと思います。
AWS SDK for PHPをインストールしたのち
Aws\CloudFront\CloudFrontClient のオブジェクトを利用して
$result = $client->createInvalidation();
または
$promise = $client->createInvalidationAsync();
のコマンドでキャッシュ削除することができます。
AWS SDK for PHP 3.x
EC2の任意フォルダ内に以下のファイルを作成
<?php
require 'vendor/autoload.php';
use Aws\CloudFront\CloudFrontClient;
use Aws\Exception\AwsException;
echo('CloudFront cache clear...'."\n");
$access_key = "xxxxxx";
$access_secret = "xxxxxx";
$distribution_id = "XXXXXX";
$paths = [
'/*',
];
$client = new CloudFrontClient([
'region' => 'us-east-1',
'version' => '2019-03-26',
'credentials' => [
'key' => $access_key,
'secret' => $access_secret,
],
]);
/** @var \Aws\Result $result */
$result = $client->createInvalidation([
'DistributionId' => $distribution_id,
'InvalidationBatch' => [
'Paths' => [
'Quantity' => count($paths),
'Items' => $paths,
],
'CallerReference' => time(),
],
]);
var_dump($result);
?>
実行
$ php clear_cache.php
出力結果
CloudFront cache clear...
/home/ec2-user/clear_cache.php:37:
class Aws\Result#90 (2) {
private $data =>
array(3) {
'Invalidation' =>
array(4) {
'Id' =>
string(14) "xxxxxxx"
'Status' =>
string(10) "InProgress"
'CreateTime' =>
class Aws\Api\DateTimeResult#109 (3) {
...
}
'InvalidationBatch' =>
array(2) {
...
}
}
'Location' =>
string(99) "https://cloudfront.amazonaws.com/2019-03-26/distribution/XXXXXX/invalidation/I2WADC1K0L962S"
'@metadata' =>
array(4) {
'statusCode' =>
int(201)
'effectiveUri' =>
string(84) "https://cloudfront.amazonaws.com/2019-03-26/distribution/XXXXXX/invalidation"
'headers' =>
array(5) {
...
}
'transferStats' =>
array(1) {
...
}
}
}
private $monitoringEvents =>
array(0) {
}
}
参考
AWS PHP SDK v3 で Amazon CloudFront のキャッシュをパージする | コンクリートファイブジャパン - concrete5 Japan Inc.
3. 確認
CloudFrontのステータスが「配備済み(APPROVED)」に変わってから
CloudFrontのURL https://<domain name>/<object name> へアクセス。
内容が変更後のものになったことを確認します。
ステータスコードも304ではなく200になっています。
コンソールでログ確認
一応 AWSコンソール > サービス > CloudTrail でログを確認します。
(他にCloudFrontのログ設定しているものがあればそちらを見れば良いと思います。)
エラーコードに何も表示されていなければ成功です。